AutoCAD VBAの深淵:Blocksコレクションを「制御」するアーキテクトの視点
AutoCADのAPIを扱うということは、単にオブジェクトを操作するのではない。メモリ空間に展開された巨大なデータベースの整合性を守りながら、いかに効率的に「必要な情報だけを抽出するか」という戦いである。
多くの初心者は`Blocks`コレクションをただループさせるだけで満足する。だが、長年数百万行のレガシーコードと対峙してきた諸君ならわかるはずだ。「なぜその処理が重いのか」「なぜメモリリークが発生するのか」。
今回は、単なるブロック名リストアップという初歩的なテーマを題材に、システム管理者やシニアエンジニアが知るべき「極限の制御術」を伝授する。
—
1. なぜ「Blocks」の走査がボトルネックになるのか
AutoCADの`Blocks`コレクションは、図面内の全ブロック定義を保持する巨大なテーブルだ。ここには、ユーザーが作成したブロックだけでなく、外部参照、レイアウト、さらにはシステム内部で生成された「Model_Space」や「Paper_Space」といった無名のブロックも含まれる。
単純な `For Each` ループは読みやすいが、大規模な図面や数千の定義が存在する環境では、オブジェクトのオーバーヘッドが蓄積し、パフォーマンスを確実に蝕む。
制御の要諦:
- IsXRef(外部参照)の判定: 不要な外部参照を走査対象から除外する。
- IsLayout(レイアウト)の判定: モデル空間やペーパー空間の定義をスキップする。
- メモリの明示的解放: VBAのガベージコレクション(GC)は不安定だ。オブジェクト参照を適切に `Nothing` に戻す規律が、長時間稼働するプロセスの生命線となる。
—
2. 実装コード:堅牢性を担保したブロックリストアップ
このコードは、単にリストを出すだけでなく、後続のシステム連携(Excelへのエクスポートやデータベースへの登録)を想定した「堅牢な構造」で記述している。
Option Explicit
”’
”’ 大規模図面でのパフォーマンスを考慮した実装
”’
Public Sub ExtractUniqueBlockNames()
Dim acadDoc As AcadDocument
Dim blkColl As AcadBlocks
Dim blk As AcadBlock
Dim blockNames As Collection
Dim bName As String
‘ 参照のセット
Set acadDoc = ThisDrawing
Set blkColl = acadDoc.Blocks
Set blockNames = New Collection
‘ エラーハンドリングを忘れずに。AutoCADのプロセスは予期せぬ中断が最も危険
On Error Resume Next
Dim i As Long
For i = 0 To blkColl.Count – 1
Set blk = blkColl.Item(i)
‘ 極限の知見:システムブロック、外部参照、レイアウトを除外する
‘ これを行わないと、不要なデータまで処理することになる
If Not blk.IsXRef And Not blk.IsLayout Then
bName = blk.Name
‘ 先頭にが付くシステム生成ブロック(無名ブロック)を弾く
If Left(bName, 1) <> “” Then
‘ 重複チェック:コレクションのキーを利用した高速フィルタ
blockNames.Add bName, bName
End If
End If
‘ オブジェクトの明示的解放:ループ内でのメモリ堆積を防ぐ
Set blk = Nothing
Next i
On Error GoTo 0
‘ 結果の出力(ここではイミディエイトウィンドウへ)
Dim v As Variant
For Each v In blockNames
Debug.Print “Found Block: ” & v
Next v
‘ 終了処理
Set blockNames = Nothing
Set blkColl = Nothing
Set acadDoc = Nothing
End Sub
—
3. シニアエンジニアが守るべき3つの鉄則
① オブジェクトの明示的解放(Nothingの徹底)
VBAは参照カウンタ方式のGCを採用しているが、AutoCADのAPIはCOMオブジェクトである。ループ内で生成される `AcadBlock` オブジェクトを `Nothing` に明示的に戻さなければ、巨大図面を連続処理した際にプロセス全体のメモリ使用量が肥大化し、最悪の場合、AutoCADのクラッシュを招く。
② `On Error Resume Next` の正しい使い方
APIの走査では、図面の状態やパーミッションにより稀にアクセス違反が発生することがある。上記コードのように、必要な判定処理の直前でエラーを局所的に制御し、`On Error GoTo 0` で即座に通常モードに戻すのが、プロフェッショナルの作法だ。
③ Excel連携を見据えたデータ構造
今回のコードでは `Collection` オブジェクトをキー(`Key`)として利用した。これにより、`If Exists` のような遅い検索処理を記述せずとも、`Add` メソッドが自動的に重複を弾いてくれる。この「言語仕様の隙間」を突く実装こそが、計算量を抑えるコツである。
—
結びに:次なるステップへ
このコードをベースに、次は `FileSystemObject` を使ったログ出力や、`ADO/DAO` を介した部品表データベースとの照合へと拡張していくのが、業務自動化エンジニアの歩む道だ。
CADは単なる製図ツールではない。諸君が書くコードによって、AutoCADは「データ統合のハブ」へと変貌する。技術を磨き、泥臭い保守から解放されるための「真の自動化」を追求してほしい。
何かあれば、またこの場所で対峙しよう。健闘を祈る。
