AutoCAD VBAの深淵:WindowState制御とメモリ管理による「図面サムネイル自動生成」の極意
AutoCADのオートメーションにおいて、画面描画を伴う処理は最大のボトルネックであり、同時に最も制御が難しい領域だ。多くのエンジニアが「なんとなく」動くコードを書き、メモリリークや描画の競合に頭を悩ませる。
今回は、AutoCADの`WindowState`を極限まで制御し、Windows APIを直叩きして高速・確実に図面サムネイルを生成する、アーキテクトレベルの技術を解説する。これは単なるスクリプトではなく、数千枚の図面を管理するシステム基盤としての作法だ。
—
1. 描画パイプラインを支配する:WindowStateの罠
AutoCADはUIスレッドと図面データベース(DBX)が密接に結合されている。`Application.WindowState`を単に`acMaximized`にするだけでは不十分だ。Windowsメッセージループが描画を完了する前に画像キャプチャを走らせれば、真っ黒な画像や、前回の残像が残るゴミデータが生成される。
アーキテクトの知見:同期の鉄則
`DoEvents`を乱用するな。あれはイベントキューを空にするだけで、描画完了を保証しない。真の制御には `Sleep` APIと、ウィンドウ状態の遷移を確実に監視するループが必要だ。
—
2. 実装:Windows APIを用いた高精度キャプチャ
VBA単体では描画領域(Viewport)の正確な取得は困難だ。`User32.dll`を介してウィンドウハンドル(hWnd)を特定し、`BitBlt`でビットマップを切り出すのが最速の手段である。
‘ Windows APIの宣言
Private Declare PtrSafe Function GetWindowDC Lib “user32” (ByVal hWnd As LongPtr) As LongPtr
Private Declare PtrSafe Function BitBlt Lib “gdi32” (ByVal hDestDC As LongPtr, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As LongPtr, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
‘ … 他にもReleaseDC等の解放用APIが必要
Sub GenerateThumbnail(doc As AcadDocument, savePath As String)
Dim app As AcadApplication
Set app = doc.Application
‘ 1. ウィンドウの最適化
app.WindowState = acMaximized
doc.SendCommand “_ZOOM _E ” ‘ 図面全体を表示
‘ 2. 描画の安定化を待機(最低限のインターバル)
Sleep 500
‘ 3. キャプチャの実行ロジック
‘ ※hWndの取得は Application.WindowHandle からではなく、
‘ アクティブなMDIクライアント領域を特定するのがコツだ。
‘ … (ここにBitBlt処理とStdPictureへの変換ロジックを記述)
‘ 4. オブジェクトの明示的解放
‘ VBAのガベージコレクションを信じるな。
‘ APIのハンドルは自ら解放せよ。
ReleaseDC hWnd, hDC
End Sub
—
3. パフォーマンスの重み:メモリ管理の真実
AutoCAD VBAにおいて、`AcadDocument`をループ処理で開閉すると、確実にメモリリークを起こす。これはCOMオブジェクトの参照カウントが適切にデクリメントされないためだ。
- 明示的なNothing代入: ループ内で生成したオブジェクトは、次のイテレーションに移る前に必ず`Set obj = Nothing`せよ。
- バックグラウンド処理の検討: もしUIが見える必要がないなら、そもそもVBA(UIスレッド)ではなく、`ObjectARX`または`.NET API (AcMgd.dll)`の`ObjectDBX`を使用して非表示で処理せよ。UIを介さないキャプチャは、速度が10倍以上向上する。
—
4. 管理台帳システムとの連携
生成したサムネイルは、単にフォルダに放り込むのではない。メタデータ(図面番号、作成者、更新日時)と紐付けたJSONまたはDBへ登録する。
シニアエンジニアの推奨アーキテクチャ
1. VBA側: 図面を開く → `ZoomExtents` → キャプチャ → 一時ファイル保存。
2. 中間層(Python/PowerShell): VBAからキックされ、画像のリサイズとメタデータのDB登録を非同期で行う。
3. 利点: AutoCADのプロセスがクラッシュしても、管理台帳システム側への影響を最小限に抑えられる。
—
5. 最後に:レガシーと向き合う勇気
AutoCAD VBAは「古い技術」と揶揄されるが、現役の設計現場でこれほど強力なツールはない。重要なのは、「いつVBAを捨て、いつAPIを信じるか」の境界線を見極めることだ。
今回紹介したWindowState制御とAPI連携は、いわば「AutoCADをプログラムで無理やり操る」ための荒療治だ。この手法を使えば、何千枚もの図面を夜通しで処理し、朝には完璧な管理台帳ができあがっているという状況を作り出せる。
諸君、コードを書く前にまず、AutoCADという巨大なCOMサーバーの呼吸を読み取れ。機械を支配するのは、仕様を知る者ではなく、挙動を理解した者のみだ。
—
追記:もし描画が不安定な場合は、`Application.Update`メソッドを過信せず、`AcadDocument.Regen acActiveViewport`を明示的に実行し、再描画の完了を`IsQuiescent`プロパティで監視せよ。それがプロの仕事だ。
