【テクニカル・上級編】【初心者向け】AcadApplication.Visibleの切り替えで「画面のちらつき」を抑え、マクロの体感速度を向上させる基本テクニック – AutoCAD VBA解析バイブル

スポンサーリンク

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の呼吸」を感じ取れ。それができれば、君もまた、この領域のアーキテクトだ。

タイトルとURLをコピーしました