タイトル: Revit API:トランザクションと要素編集
SEOタイトル: Revit API トランザクション|Transaction Start/Commit/RollBack・using・Parameter.Set・要素作成・TransactionGroup
| この記事の要点 |
|
要素を取得したら、次はそれを編集・作成します。Revit ではモデル変更を「トランザクション」で囲むことが義務付けられています。パラメータの基礎は パラメータ も参照してください。
トランザクションの必須性
モデルへの変更(要素の作成・削除、パラメータ値の変更など)は、必ず Transaction の中で行わなければなりません。トランザクション外で変更しようとすると例外が発生します。これは元に戻す(Undo)の単位を明確にし、変更の一貫性を保つための仕組みです。
外部コマンドのクラスには [Transaction(TransactionMode.Manual)] を付け、コード内で明示的にトランザクションを開始・コミットするのが標準的な書き方です。
Start / Commit / RollBack と using
トランザクションは Start で開始し、成功すれば Commit、失敗すれば RollBack で取り消します。例外発生時に確実に後始末するため、using 文で囲むのが定石です。
using Autodesk.Revit.DB;
using (Transaction tx = new Transaction(doc, "パラメータ更新"))
{
tx.Start();
try
{
// ここでモデルを変更する
Wall wall = doc.GetElement(wallId) as Wall;
Parameter p = wall.get_Parameter(BuiltInParameter.ALL_MODEL_MARK);
p.Set("W-001");
tx.Commit();
}
catch
{
tx.RollBack();
throw;
}
}
using を使うと、スコープを抜ける際に Dispose が呼ばれ、コミットされていないトランザクションは自動的にロールバックされます。トランザクション名(第2引数)は Undo メニューに表示されるので、分かりやすい名前を付けます。
パラメータの取得と設定
パラメータの読み書きは編集の基本です。取得は get_Parameter(BuiltInParameter または名前で指定)、設定は Set を使います。値の型に応じて読み出しメソッドが分かれます。
- 文字列:
AsString()/Set("文字列") - 数値(長さなど):
AsDouble()/Set(double)。内部単位フィートで扱う。 - 整数・真偽:
AsInteger()/Set(int) - 要素参照:
AsElementId()/Set(ElementId)
長さ系を mm で扱いたい場合は、UnitUtils.ConvertToInternalUnits でフィートに変換してから Set します。読み取り専用パラメータに Set すると失敗するため、IsReadOnly を確認すると安全です。
要素の作成
壁・床・梁などの要素は、各クラスの静的ファクトリメソッドで作成します。たとえば直線の壁は Wall.Create を使います。
using (Transaction tx = new Transaction(doc, "壁を作成"))
{
tx.Start();
Line line = Line.CreateBound(
new XYZ(0, 0, 0), new XYZ(10, 0, 0)); // 単位はフィート
Wall wall = Wall.Create(
doc, line, levelId, false); // structural=false
tx.Commit();
}
座標を表す XYZ の値も内部単位(フィート)です。作成系メソッドは引数にレベル ID やタイプ ID を要求することが多いので、事前に FilteredElementCollector で取得しておきます。
TransactionGroup
複数のトランザクションを論理的にひとまとまりにし、1回の Undo で全体を戻したい場合は TransactionGroup を使います。グループを Start し、その中で複数のトランザクションを実行したあと、Assimilate(同化)で1つにまとめるか、RollBack で全体を取り消します。
using (TransactionGroup tg = new TransactionGroup(doc, "一括処理"))
{
tg.Start();
// 中で複数の Transaction を実行...
tg.Assimilate(); // すべてを1つの Undo 単位にまとめる
}
段階的に処理を進めつつ、最終的にユーザーには「1操作」として見せたい複雑なツールで重宝します。