AutoCADの「沈黙の腐敗」を断つ:BeginSaveフックによる自動クリーンアップの極意
AutoCADの図面ファイル(DWG)は、長年の運用と複数人による編集を経て、目に見えない「デジタル負債」を蓄積していく。未使用のブロック定義、レイヤー、線種、そしてゾンビ化したオブジェクト。これらを放置することは、ファイルサイズの肥大化のみならず、致命的な図面破損のトリガーとなる。
多くの開発者は、これを「手動でのクリーンアップ」や「バッチ処理」で解決しようとする。だが、真のエンジニアはシステムに介入する。ユーザーが「保存」という行動をとった瞬間、背後で静かに、かつ確実に図面を浄化する。これが、本質的な自動化の解だ。
1. BeginSaveイベントを狙い撃つ理由
図面をクリーンに保つためのフックポイントとして、`BeginSave`イベントは最適解である。`EndSave`ではない。保存が完了した後に処理を走らせることは、書き込み済みのファイルを再度開くという無駄なI/Oを発生させるからだ。
ここで肝となるのは、「保存というプロセスを完遂させるために、先行して図面を健全化する」という思想である。
2. 実装の要諦:再帰的パージと監査の強制
VBAでこれを実装する際、最大の罠は「オブジェクトの参照保持」にある。パージを実行する際にアクティブな図面オブジェクトへ無闇にアクセスし続けると、メモリリークや予期せぬスタックオーバーフローを招く。
実装コード:Auto-Sanitize Architecture
以下のコードを `ThisDrawing` モジュールに配置せよ。
Option Explicit
‘ イベント駆動の設計:BeginSaveをフック
Private Sub AcadDocument_BeginSave(ByVal FileName As String)
On Error Resume Next
‘ 1. コマンドエコーを抑制し、ユーザーの操作感を損なわないようにする
Dim oldEcho As Integer
oldEcho = ThisDrawing.GetVariable(“CMDECHO”)
ThisDrawing.SetVariable “CMDECHO”, 0
‘ 2. 監査(AUDIT)の実行(エラー修復を強制)
‘ ※注意:AUDITは非モーダルな挙動をとるため、必要に応じて同期を取る
ThisDrawing.SendCommand “_AUDIT” & vbCr & “Y” & vbCr
‘ 3. パージ(不要データの完全削除)
‘ ネストされたブロックや未知のアプリケーション登録データを一掃する
Call PurgeAll
‘ 4. 環境復帰
ThisDrawing.SetVariable “CMDECHO”, oldEcho
‘ メモリ最適化:明示的な解放
‘ VBAはCOMラッパーであるため、大規模処理後は参照をクリアする
DoEvents
End Sub
Private Sub PurgeAll()
Dim i As Integer
‘ 複数回パージを実行するのは、ネストされたオブジェクトを連鎖的に削除するため
‘ 3回が経験則上の最適値
For i = 1 To 3
ThisDrawing.SendCommand “-PURGE” & vbCr & “All” & vbCr & “” & vbCr & “N” & vbCr
Next i
End Sub
3. シニアエンジニアが知るべき「見えざる制約」
このコードを実装する上で、単なる技術者とアーキテクトを分かつ境界線がいくつか存在する。
A. コマンド実行の同期性
`SendCommand` は非同期的にキューへ送られる。大規模図面でこの処理を挟むと、保存処理と競合し、AutoCADがフリーズしたような挙動を示すことがある。これを回避するためには、Windows APIの `Sleep` を利用した待機ロジックを組み込むか、`.NET API (ObjectARX)` への移行を検討すべき閾値を見極める必要がある。
B. Windows APIによるプロセスの監視
もし、バックグラウンドでのパージ処理が重すぎる場合、`kernel32.dll` の `GetTickCount` を使用し、処理時間を計測せよ。保存時間が通常の1.5倍を超える場合は、処理をスキップまたはログ出力のみに変更する「インテリジェント・バイパス」を実装することが、現場の生産性を守る鍵となる。
C. 未定義オブジェクトの再帰的削除
上記の `-PURGE` コマンドだけでは、特定のサードパーティ製アプリケーションが付与した「拡張レコード(XRecord)」や「辞書オブジェクト(Dictionary)」は消去できない場合がある。これらが必要な場合は、`ObjectDBX` を活用し、UIを介さずにメモリ空間上で直接オブジェクトを走査・削除する、一段階上のアーキテクチャが必要だ。
4. 総括
VBAはレガシーと言われるが、AutoCADの内部メモリ構造を直接操作できる唯一無二のツールであることに変わりはない。今回紹介した `BeginSave` フックは、単なる自動化ではない。「組織の図面品質を、個人のスキルに依存させず、システムによって強制的に維持する」ための、防御的プログラミングの第一歩である。
このコードをそのまま導入するのも良いが、貴殿の環境における図面の肥大化要因を分析し、パージ対象をカスタマイズしてほしい。技術とは、使われるものではなく、現場に合わせて磨き上げられるものである。
さあ、レガシーを「資産」へと昇華させよう。
