基礎から始める Revit Dynamo 超入門　～Excel連携とプロパティーの自動入力編～

## はじめに

　本記事はAutodesk Revit用のVPLであるDynamoについて、私が個人的に取り組んでいる内容及び社内で取り組んでいる内容の一部または抽象化したものについて、備忘録として、また建築業界のICT技術活用の発展に寄与することを願って執筆するものです。
　特に入門的な内容を扱うシリーズとして作成しますが、たまに難しいことをし始めるかもしれないので、その際はご指摘、ご質問いただければと思います。


## 概要
　今回は部屋の仕上げ情報を例に、Dynamoを介したRevitとExcelのデータ連携について記載していきます。
　どのような形式で仕上げ材の情報を管理しているかは各企業さんによって異なると思いますので、そのあたりは適宜仕様に合わせて変更していただければと思います。

## 使用するデータ
* Revitデータ：部屋を3つ作成したもの。  
\* 部屋名は「会議室」「設計部」「設備部」
* Excelデータ：部屋名及び、壁・床・天井仕上げの情報をまとめたデータ

　以下に図を示します。
　どちらも簡単なものなので、作成してみてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350776/fe2cb857-8a13-252d-964e-2d8ab0a01c9e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350776/a9ee5b2a-a773-1ee1-1b05-39fce2d90e62.png)


## Dynamoプログラムの作成
　それではここから、Excelデータからプロパティーにデータを入力するプログラムの作成を行っていきます。

### Excelファイルの読み込み
　まずはExcelファイルの読み込みから実装します。
　ライブラリの検索窓に「file」と入力し、「File Path」および「File From Path」を配置します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350776/1b33b796-cd34-4733-ca0f-9fff98a8d414.png)

　次に、ライブラリの検索窓に「excel」と入力し、「ImportExcel」ノードを配置します。
　このノードは第1引数にファイルを、第2引数にシート名を入力します。「Code Block」でシート名を作成し、第2引数につなぎましょう。
\*（プログラム開発経験のある方には改めて説明する必要はありませんが、）文字列を扱うときは「"｜ダブルクオーテーション」で文字を囲むようにしましょう。

　接続が完了したら、プログラムを実行してみましょう。
　Excelのデータがリスト形式で読み込まれます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350776/6ce361be-240e-ad78-f7ea-24e644bf20ff.png)



### 部屋オブジェクトを取得
　次に、もう一つの必要要素である部屋オブジェクトの取得を行います。
　ライブラリの検索窓に「category」と入力し、「Categories」及び「All Elements of Category」を配置します。
　「Categories」ノード内にあるセレクターで部屋を選択すると、**プロジェクト内に存在する**すべての部屋オブジェクトを取得できます。

　ここで注目すべき点として、「All Elements of Category」で取得した結果の右側（緑の網掛け部分）に6桁の整数が表示されています。
　これは要素IDと呼ばれるもので、Revitがもつオブジェクト一つ一つに割り当てられたユニークな値です（データベースらしい仕様ですね）。

　今後場合によっては、この要素IDを利用する機会があるかもしれないので、こういったIDが割り振られていることは覚えておきましょう。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350776/20117fd0-0cc4-4478-d37d-362c0cecc318.png)



　ここまでで、必要となる情報の取得ができました。
　ここからは、これらの情報を最終的に制御するためのかたちに整えていきます。まずはじめに取得したExcelの情報を、**部屋の名前を用いて**部屋オブジェクトの並び順と一致させます。

### 部屋名の取得

　取得したExcelデータと部屋オブジェクトから、部屋の名前を取得します。

#### Excelデータから部屋の名前を取得
　Excelデータの中身（下図）を見ると、一行ごとにリスト形式でまとめられていることが分かります。一行目（リストの0番目）が表の見出し（ヘッダー）で、それ以降がデータの中身となっているので、一度これらを分割しましょう。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350776/0eddcb36-5edf-2250-14b8-c8631f30f718.png)

ライブラリの検索窓に「deconstruct」と入力し、「Deconstruct」を配置します。
これで、戻り値の「first」に見出しが、「rest」にデータの中身が割り振られました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350776/277e5198-e0f9-e939-0677-4a5c0eeb9244.png)


　この「rest」に入っている情報から各部屋の名前を取得しましょう。
　ライブラリの検索窓に「getitem」と入力し、「GetItemAtIndex」を配置し、第1引数「list」の「>」をクリックし、「レベルを使用」にチェックを入れましょう。
　すると、リストのどの階層から値を取得するかを選択できるようになるので、「L2」を選択しましょう。
　次に、第2引数「index」に「Code Block」で「0」を入力して下さい。こうすることで、**「L2」の階層の「0」番目の値を取得する**ことができます（図のように各部屋の名前を取得することができます）。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350776/82612f6a-4704-a13f-bb1e-c7c58b8bf379.png)


#### 部屋オブジェクトから部屋の名前を取得
　次に、部屋オブジェクトが持つ「名前」プロパティーから情報を取得します。
　ライブラリの検索窓に「getpara」と入力し、「GetParameterValueByName」を配置してください。
　第1引数「Element」に部屋オブジェクトを、第2引数「ParameterName」に「Code Block」で作成した「名前」の文字列を接続してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350776/62d17652-1611-9b48-d383-7f9cdac1dca3.png)


　これで、Excel、Revit双方の部屋の名前を取得することができました。
　次からは、この名前を利用して双方の並び順を一致させていきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350776/014561c6-907a-3498-021b-a0d6173b43a4.png)



### データの順番を一致させる
　ライブラリの検索窓に「indexof」と入力し、「IndexOf」を選択します。
　結果を見ると「2,0,1」となっていますが、これは簡単にいうと、「**部屋オブジェクトの並び順は、Excelのデータの2番目、0番目、1番目の順番です**」ということです。
　つまり、ここで取得した順番を利用してExcelデータを並び替えることで、双方のデータの順番を一致させます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350776/996f3ae3-a587-98d5-ee90-264947e7c1cd.png)

　ソートキーを元にデータを並び替える場合は、先ほど利用した「GetItemAtIndex」を利用します。
　下図のように接続して、Excelデータをソートできているか確認しましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350776/65b10e80-3c7d-1d80-43f5-3f8227b3fa94.png)


### 仕上げ情報の抽出

　ソートしたデータには未だ部屋の名前も入っていますが、この情報はプロパティーの値の変更対象ではないため除外しておきましょう。
　ライブラリの検索窓に「restof」と入力し、「RestOfItems」を配置します。
　このノードは先頭の要素を削除するものですが、ここでもどの階層の先頭を削除するかを指定することができますので、「L2」を選択しましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350776/66a5215b-4aba-1a2d-ec57-ef1aad27a0ff.png)



### 制御するプロパティー名を取得（表の見出しから）
　ここまでで、セットする**プロパティーの値**の準備ができました。
　ここからは、セットする**プロパティーの名前**を準備します。とはいいつつも、Excelの見出しの名前をプロパティーの名前と一致するように定義してあるため、表の見出しの値を利用していきます。

　先ほど作成したノードで、表の見出しとデータを切り分けているので、この見出しから不要な値「名前」を削除しましょう。
　手順は先ほどと同様「RestOfItems」を利用します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350776/06141efe-8869-dd98-e634-7c8edf01968c.png)

　結果の値を見ると、不要な階層があるため階層を一段下げましょう。
　ライブラリの検索窓に「flatten」と入力し、「Flatten」を配置しましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350776/f8327626-b818-6067-8f6b-da437ac08fee.png)


### プロパティーの書き換え
　それでは最後に、プロパティーに値をセットするノードを配置しましょう。
　ライブラリの検索窓に「setpara」と入力し、「SetParameterValueByName」を配置します。
　下図では、第1引数「Element」に部屋オブジェクトをつなぐ途中で「Watch」を挟んでいます。このようにすることで、線同士が複雑に絡んだ状態を避け、どのようにデータが流れるかを可視化することができます。
　たまに「これぞ[スパゲッティーコード](https://ja.wikipedia.org/wiki/%E3%82%B9%E3%83%91%E3%82%B2%E3%83%86%E3%82%A3%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0)」と言わんばかりのぐちゃぐちゃなプログラムを見かけますが、VPL（Dynamoなど）は人の脳みそを除く窓といっても過言ではないため、可能な限りすっきりと分かりやすいものを作るように心がけましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350776/aa0d371b-e0e4-b28d-af44-3df94684d627.png)

　話はそれましたが、最後に「SetParameterValueByName」の設定を行いましょう。
　第1引数「element」の「＞」をクリックし、**「レベルを使用」と「リスト構造を保持」の両方にチェックを入れ**、レベルは「L1」としましょう。
　また、第3引数「value」は**「レベルを使用」のみ**チェックを入れ、レベルは「L2」を選択してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350776/19c2125f-453e-03bf-0c7f-0caa7284dfd0.png)


### プログラムの実行と確認
　
　ここまで作成できたら、プログラムを実行し部屋のプロパティーを確認してみましょう。
　下図のように値がセットできていれば成功です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350776/698dfdd6-512f-8271-8578-9ee5557f3149.png)


## 終わりに
　本記事の内容はここまでです。
　
　ExcelとRevitの連携は、部屋の仕上げ情報だけでなくまだまだ様々なことに利用できます。
　是非色々なデータを連携（あるいはBIMデータに集約）し、Revitの持つ機能を利用して作業効率の向上につなげていただければと思います。

　今回も最後までご閲覧いただきありがとうございました。