AutoCAD VBAを掌握する:描画更新の「沈黙」がもたらす極限のパフォーマンス
AutoCADのオートメーションにおいて、初心者が最初に突き当たる壁は「処理速度」ではない。「無駄な描画によるCPUとGPUの浪費」である。
君たちが書いた数千行のコードが、1行ごとに再描画を繰り返しているのを見るのは耐え難い。今回は、単なる`Application.Visible`の制御を超えた、AutoCADエンジニアリングの深淵へと招待しよう。
1. なぜ「画面のちらつき」は悪なのか
AutoCADは本質的に、グラフィカルなイベントループに支配されている。マクロが図形を作成するたび、オブジェクトモデルは`Regen`や再描画をトリガーする。これはユーザー体験を損なうだけでなく、メモリバスとGPUの帯域を不必要に占有し、結果として全体の処理時間を数倍に膨れ上がらせる。
真のプロフェッショナルは、「処理中のAutoCADは、ただの計算機であれ」という哲学を持つべきだ。
2. 描画更新を封じ込める:定石と禁じ手
画面の更新を抑えるための黄金律は、`Application.Visible`を操作することではない。あれはアプリケーション全体の表示を隠すという「荒療治」であり、プロセスの不安定化を招くリスクがある。
我々が用いるべきは、`Application.ScreenUpdating`に相当するプロパティの制御と、Windows APIによる描画停止の合わせ技である。
推奨される実装パターン
‘ AutoCAD VBA: パフォーマンスを極限まで引き出す描画抑制の作法
Public Sub OptimizeDrawingProcess()
Dim acadApp As AcadApplication
Set acadApp = ThisDrawing.Application
‘ 1. システム変数の退避と最適化
‘ CMDECHO: コマンドラインへの出力を抑止
‘ PICKFIRST: 選択セットの事前選択を無効化
Dim oldEcho As Integer: oldEcho = acadApp.GetVariable(“CMDECHO”)
acadApp.SetVariable “CMDECHO”, 0
‘ 2. 描画更新の一時停止(AcadDocumentレベルの制御)
‘ これにより、エンティティ作成時の逐次更新を抑止する
acadApp.ActiveDocument.Utility.Prompt “処理を開始します…”
On Error GoTo Cleanup
‘ — ここに重厚なバッチ処理を記述 —
‘ 例: 大量ライン作成処理など
Cleanup:
‘ 3. 必ず状態を復元する(これを忘れるとユーザーは激怒する)
acadApp.SetVariable “CMDECHO”, oldEcho
‘ 4. 明示的なメモリ解放と再描画
‘ オブジェクトへの参照を破棄し、最後に一度だけRegenを行う
ThisDrawing.Regen acActiveViewport
MsgBox “処理が完了しました。”, vbInformation
End Sub
3. レガシー環境を支配する「Windows API」の真髄
複雑なUI連携や、バックグラウンドでのCAD制御を行う場合、VBAの標準機能だけでは力不足だ。特に、Windowsメッセージループを制御し、描画を完全に凍結したい場合は、`LockWindowUpdate` APIを叩くという選択肢がある。
ただし、これは諸刃の剣である。AutoCADのハンドルを正確に特定し、処理終了後に必ずアンロックしなければ、CADそのものがゾンビ化する。
‘ User32.dllを利用したウィンドウ描画の完全ロック
Private Declare PtrSafe Function LockWindowUpdate Lib “user32” (ByVal hWndLock As LongPtr) As Long
Public Sub HardLockDrawing()
‘ AutoCADのメインウィンドウハンドルを取得し、ロックをかける
Dim hAcad As LongPtr
hAcad = Application.hWndMain
LockWindowUpdate hAcad
‘ — 高速化が必要な処理 —
‘ ロック解除(重要:0を渡すことで解除)
LockWindowUpdate 0
End Sub
4. 伝説のエンジニアとしてのアドバイス
私が現場で見てきた多くのコードは、「解放」の概念が欠落している。`AcadObject`を生成し、ループ内でインスタンスを放置すれば、COMラッパーのGC(ガベージコレクション)が追いつかず、メモリリークの温床となる。
- `Set obj = Nothing` をループの最後で実行せよ。
- `AcadSelectionSet` は使用直後に必ず `Delete` せよ。
- トランザクション管理(可能であればObjectARXや.NET APIへ移行せよ)を意識せよ。
VBAはレガシーだが、そのアーキテクチャの根底には強力なCOMインターフェースが流れている。この流れを理解し、不要な描画という「ノイズ」を消し去ることで、君たちのマクロは単なる自動化ツールから、「システムに最適化されたエンジン」へと進化するはずだ。
技術は裏切らない。コードの行間にある「CPUの呼吸」を感じ取れ。それができれば、君もまた、この領域のアーキテクトだ。
