現場の「所作」をコードに落とし込む:PickFirstSelectionSetの真実
AutoCAD VBAにおいて、ユーザーが事前に選択した図形を処理対象とする――いわゆる「ピックファースト(PickFirst)」の実装は、単なる機能追加ではない。それは、UI/UXの流儀を理解し、エンドユーザーのストレスを最小化する「プロフェッショナルの作法」だ。
世の中の入門書は、`ThisDrawing.PickfirstSelectionSet` を呼んで終わりにするが、現実は甘くない。メモリリーク、COMラッパーの不整合、そして図面状態による予期せぬエラー。これらを制御下に置くことが、チーフアーキテクトとしての最低条件である。
1. 致命的な落とし穴:オブジェクトのライフサイクルとメモリ解放
VBA(COM)における最大の敵は、明示されないオブジェクトの残滓だ。特に `SelectionSet` は、明示的に `Delete` しなければ、AutoCADのセッション内にゾンビのように残り続ける。
‘ 【現場の作法】確実に生成し、確実に葬る
Public Sub ProcessPickFirstSelection()
Dim ss As AcadSelectionSet
Dim obj As AcadEntity
Dim ssName As String
‘ SelectionSet名は一意である必要がある。既存の残骸をクリーンアップする
ssName = “MyTempSS”
On Error Resume Next
ThisDrawing.SelectionSets.Item(ssName).Delete
On Error GoTo 0
‘ オブジェクトを生成
Set ss = ThisDrawing.SelectionSets.Add(ssName)
‘ 現在の選択セットを取得
ss.PickFirstSelectionSet
‘ 処理ロジック
If ss.Count > 0 Then
For Each obj In ss
‘ ここでビジネスロジックを展開
Debug.Print “Entity Type: ” & obj.ObjectName
Next obj
Else
MsgBox “対象が選択されていません。”
End If
‘ 【重要】使用後は必ず解放し、名前付きセットを破棄する
ss.Clear
ss.Delete
Set ss = Nothing
End Sub
2. なぜ「On Error Resume Next」が不可欠なのか
AutoCADのAPIは、特定の操作(例えば、全く同じ名前の `SelectionSet` を作成しようとする等)において、例外をスローする。これを「エラー」と捉えて停止するのではなく、「状態の初期化プロセス」として管理するのが、安定したシステムを構築するコツだ。
特に、他社製プラグインや古いLISPルーチンが図面内に不可視の `SelectionSet` を放置しているケースは多々ある。名前付けには、GUIDを模したユニークな文字列を使用するか、実行のたびに `Delete` する実装を徹底すること。
3. パフォーマンスの限界を突破する:Windows APIの活用
大量の図形を扱う場合、`For Each` ループは遅延の温床となる。VBAのオーバーヘッドを避けるなら、`Variant` 配列への一括格納を検討すべきだ。
しかし、真に極限のパフォーマンスを求めるなら、`ObjectARX` や `.NET` APIへの移行が正攻法である。もしVBAで限界を迎えたなら、以下のようにして処理を切り分けるのが「レガシーの保守」における賢い選択だ。
- VBAの役割: UI制御、パラメータの受け渡し、ユーザーインターフェース。
- バックエンドの役割: 重いジオメトリ計算、大量のエンティティ操作(.NET/C#)。
4. シニアエンジニアへの提言:なぜ「今」これをやるのか
システム管理者の視点から言えば、自動化の目的は「キー入力の回数を減らすこと」ではない。「ユーザーがCADを操作する際の思考を中断させないこと」にある。
1. 選択の強制: コマンドラインから起動するのか、リボンボタンから起動するのか。ユーザーの意図を汲み取り、`PickFirst` を使うべきか、`GetEntity` でプロンプトを出すべきかを設計段階で峻別する。
2. エラーハンドリングの哲学: APIが戻り値を返さない場合、それは「選択なし」なのか「エラー」なのか。曖昧さを排除した設計が、後の保守コストを劇的に下げる。
3. レガシーの継承: 古いVBAコードを書き換える際は、必ずそのコードが「どのバージョンのAutoCADから引き継がれたか」を確認せよ。COMの実装はバージョンによって微妙に挙動が変わる。
結びとして
AutoCAD VBAは、現代のモダンな開発言語から見れば「化石」に近いかもしれない。しかし、図面という極めて複雑なデータ構造と直接対話できるこのアーキテクチャには、未だに多くの現場を支えるポテンシャルがある。
「動けばいい」というコードを卒業し、メモリの消費量と、コマンド終了後の図面状態までを制御下に置く。それこそが、伝説を築くエンジニアの証だ。
次は、`SelectionSet` をフィルタリング(`FilterType`, `FilterData`)して、特定のレイヤーや画層のオブジェクトだけをピンポイントで抽出する「高速化の極意」について深掘りするとしよう。準備はいいか?
