【AutoCAD VBA】全自動クリーンアップの真髄:安全に、そして「破壊的」にオブジェクトを排除せよ
AutoCADのプロフェッショナルな現場において、「不要なオブジェクトを消す」という行為は、単なる削除ではない。それはメモリの解放であり、図面データベース(DWG)の最適化であり、次世代のシステム連携に向けたデータ純度の向上である。
多くの初心者は `For Each` 文で安易にコレクションを回し、直後に「インデックスが範囲外です」という例外で爆死する。本記事では、システム管理者やシニアエンジニアが知るべき、実運用に耐えうる「外科手術的なオブジェクト削除」の極意を伝授する。
—
1. 破壊的走査の鉄則:逆順ループとポインタ管理
AutoCADのオブジェクトコレクションをループ中に削除すると、イテレータの整合性が崩壊し、予期せぬクラッシュやスキップが発生する。これを回避する唯一の正解は、「後ろから前へ」走査する逆順ループだ。
‘ 安全に削除を行うための逆順走査パターン
Public Sub SafeDeleteObjects()
Dim i As Long
Dim ent As AcadEntity
Dim ms As AcadModelSpace
Set ms = ThisDrawing.ModelSpace
‘ 逆順で走査することで、削除によるインデックスのズレを無効化する
For i = ms.Count – 1 To 0 Step -1
Set ent = ms.Item(i)
‘ 条件判定関数を分離し、可読性と保守性を確保する
If ShouldDelete(ent) Then
ent.Delete
End If
‘ 巨大図面では明示的なメモリ解放が重要
Set ent = Nothing
Next i
End Sub
—
2. 複合条件によるフィルタリング:プロパティアクセスの最適化
「画層、色、線種」の複合条件は、`If`文のネストで記述してはならない。それはコードの腐敗を招く。条件判定は独立したブール関数に切り出し、判定速度を上げるために「頻度の高い条件」を先頭に持ってくるのがプロの流儀だ。
Private Function ShouldDelete(ent As AcadEntity) As Boolean
‘ 削除対象外(保護対象)を先に弾く(ガード節)
If ent.Layer = “0” Then ShouldDelete = False: Exit Function
‘ 条件判定:画層名、色、線種を照合
If ent.Layer = “TEMP_LAYER” And _
ent.Color = acRed And _
ent.Linetype = “DASHED” Then
ShouldDelete = True
End If
End Function
—
3. レガシー環境とメモリの呪縛:解放の作法
AutoCAD VBAはCOM(Component Object Model)のラッパーである。`Set ent = Nothing` を怠れば、巨大な図面を開閉するプロセスの中で「メモリーリーク」が確実に進行する。
特に、`AcadSelectionSet` を使用して削除対象を事前に抽出する場合、メモリ上の生存期間を最小化することが肝要だ。
‘ 選択セットを用いた高速な削除アプローチ
Public Sub FastDeleteBySelectionSet()
Dim ss As AcadSelectionSet
Set ss = ThisDrawing.SelectionSets.Add(“TempSet”)
‘ フィルタ設定(DXFコードによる高速な抽出)
Dim filterType(0) As Integer
Dim filterData(0) As Variant
filterType(0) = 8: filterData(0) = “DELETE_ME” ‘ 画層名でフィルタ
ss.Select acSelectionSetAll, , , filterType, filterData
‘ 削除後、必ずSelectionSetを削除しメモリをクリーンにする
ss.Erase
ss.Delete
End Sub
—
4. プロフェッショナルへの提言:システム連携を見据えて
このスクリプトを単なる「消しゴム」で終わらせてはならない。将来的に、RevitやForge(Autodesk Platform Services)との連携、あるいはBIMデータとの整合性チェックを行う際、この「削除ロジック」はそのまま「検証ロジック」へと昇華させる必要がある。
運用上の注意点
- Undoスタックの肥大化: 削除処理を `StartUndoMark` で囲むことで、ユーザーが誤操作した際に一括で復元できるようにする。これは業務自動化における「優しさ」であり、同時に「事故対応コストの削減」である。
- Windows APIの活用: 非常に大規模な図面の場合、`DoEvents` を適宜呼び出し、AutoCADのUIが「応答なし」にならないよう、メインスレッドへの制御権を譲渡する配慮を忘れてはならない。
最後に
コードを書くことは、道具を作ることと同義だ。今回示した手法は、貴殿が管理する図面データを、ノイズから解放し、常に「機械が読み取りやすい綺麗な状態」に保つための基盤となる。
次は、これをクラスモジュール化し、イベントドリブンで自動監視する仕組みを構築することをお勧めする。AutoCADの深淵はまだ先にある。健闘を祈る。
