【AutoCAD VBA極意】Regenを制する者は描画負荷を制す:100倍速を実現する最適化戦略
AutoCADのAPIを叩く際、初心者が陥る最大の罠は「オブジェクトを作成するたびに画面を更新しようとする」ことだ。
数千、数万のエンティティを一気に生成するツールを開発しているとき、コードの途中で何気なく挿入した `ThisDrawing.Regen acActiveViewport` が、実はあなたのコードの命運を握る「時限爆弾」であることを知っているだろうか。
今回は、AutoCAD VBAにおける「描画負荷の最適化」をテーマに、なぜ `Regen` を制御すべきなのか、そしてプロの現場で通用する「堅牢なループ処理」の設計術を伝授する。
—
1. なぜ「そのRegen」がパフォーマンスを殺すのか
AutoCADの内部エンジンにおいて、`Regen`(再描画)は単なる表示の更新ではない。描画データベースを再構築し、全ての表示項目を再計算する極めて「重い」処理だ。
ループ内で `Regen` を呼ぶという行為は、「1枚ずつ印刷するたびに、一度工場を全停止してラインを再整備している」のと同じだ。この無駄を排除するだけで、処理時間は数分から数秒へと劇的に短縮される。
最適化の鉄則:
1. ループ内ではRegenを一切呼ぶな。
2. システム変数を一時停止せよ。
3. 処理完了後に一度だけRegenを叩け。
—
2. プロダクションコード:最適化されたエンティティ生成テンプレート
実務でそのまま使える、パフォーマンスと安全性を両立させたコード例だ。ここでは、AutoCADの内部システム変数を制御し、描画負荷を最小化する設計を採用している。
Public Sub BatchObjectCreation()
Dim acadApp As AcadApplication
Dim doc As AcadDocument
‘ エラーハンドリングの徹底(中級以上の必須事項)
On Error GoTo ErrorHandler
Set doc = ThisDrawing
‘ — パフォーマンス最適化:システム変数の制御 —
‘ ECOMODE: 0に設定することで、再描画の頻度を抑える
Dim oldEcoMode As Integer
oldEcoMode = doc.GetVariable(“ECOMODE”)
doc.SetVariable “ECOMODE”, 0
‘ FILEDIAやCMDECHOも必要に応じてOFFにするとより安全
‘ — 処理開始 —
Dim i As Long
Dim lineObj As AcadLine
Dim startPt(0 To 2) As Double, endPt(0 To 2) As Double
‘ 大量オブジェクト作成のシミュレーション
For i = 1 To 10000
‘ 座標計算(本来は動的に)
startPt(0) = i 0.1: startPt(1) = 0: startPt(2) = 0
endPt(0) = i 0.1: endPt(1) = 10: endPt(2) = 0
‘ ModelSpaceにオブジェクトを追加
Set lineObj = doc.ModelSpace.AddLine(startPt, endPt)
Next i
‘ — 処理終了:ここで初めて再描画 —
doc.Regen acActiveViewport
‘ — 終了処理:システム変数の復元 —
doc.SetVariable “ECOMODE”, oldEcoMode
MsgBox “処理完了:10,000オブジェクトの作成に成功しました。”, vbInformation
Exit Sub
ErrorHandler:
‘ 強制終了時でもシステム変数を戻すためのリカバリ
doc.SetVariable “ECOMODE”, oldEcoMode
MsgBox “エラーが発生しました: ” & Err.Description, vbCritical
End Sub
—
3. 堅牢な設計のための3つの指針
① エラーハンドリングは「復元」を考慮する
上記のコードのように、`ErrorHandler` 内でも必ず `SetVariable` を呼ぶこと。もしエラーで処理が中断した際にシステム変数がOFFのまま放置されると、ユーザーは「AutoCADの挙動がおかしい」と混乱する。これはエンジニアとして絶対に避けるべきだ。
② データベース連携時のトランザクション意識
もし外部データベース(ExcelやCSV)からデータを読み込む場合、ループ内で毎回ファイルを開閉するようなコードは論外である。
- 悪い例: `Do While` 内で `Open #1` → `Read` → `Close #1`
- 良い例: 最初に全データをメモリ配列(Array)やコレクションに読み込み、そのメモリデータを使ってループを回す。ディスクI/Oは極限まで減らすのが鉄則だ。
③ 表示負荷の更なる軽減(レイヤー制御)
もし数万個のオブジェクトを生成する場合、`Regen` を呼ぶ前の段階で、対象のレイヤーを一時的に非表示(Freeze)にすることも検討せよ。オブジェクト生成後にレイヤーをThaw(フリーズ解除)すれば、AutoCADは一度の計算で表示を最適化できる。
—
チーフアーキテクトからのメッセージ
AutoCAD VBAは、レガシーな技術だと思われがちだ。しかし、APIの深層を理解し、AutoCADがどのようにメモリを確保し、どのように描画パイプラインを処理しているかを把握すれば、それは最強の自動化兵器へと変貌する。
「動けばいい」コードを書くのはプロではない。「将来の自分やチームが保守でき、かつマシンに負荷を与えないコード」を書くことこそが、真のエンジニアの流儀だ。
次のコードを書くとき、あなたは `Regen` をどこに置くか?
その判断一つで、あなたのツールの価値は大きく変わるはずだ。
