AutoCAD VBAを掌握する:ハッチング一括制御の深淵とメモリマネジメントの極致
AutoCADのオートメーションにおいて、ハッチング(`AcadHatch`)の操作は、一見単純なプロパティ変更に見える。しかし、数万のエンティティが混在する巨大な図面データに対して安易なループ処理を走らせれば、たちまちメモリリークとパフォーマンスの停滞、最悪の場合はAutoCADのクラッシュを招くことになる。
本稿では、単なる「プロパティ書き換え」の先にある、シニアエンジニアが備えるべき「AutoCADオブジェクトのライフサイクル管理と高速化の極意」を伝授する。
—
1. 悲劇を避けるためのオブジェクト管理術
VBAはガベージコレクションが脆弱だ。特に`AcadDocument`の`ModelSpace`をイテレートする際、不用意なオブジェクト参照の保持はメモリ肥大化の主因となる。
- 明示的なNothing化: ループ内での一時的な変数(`Dim obj As AcadEntity`)は、スコープを最小化し、必ず`Set obj = Nothing`を徹底せよ。
- 遅延バインディングの弊害: `Object`型での宣言は型チェックを回避するが、実行時のオーバーヘッドが大きい。可能であれば参照設定を行い、静的バインディングを使用せよ。
2. 実装:ハッチング一括更新プロシージャ
以下に、実務で耐えうる堅牢な一括更新コードを示す。単なる変更ではなく、`Update`メソッドの呼び出しタイミングを制御し、描画負荷を最小限に抑える設計だ。
Option Explicit
‘ @brief 図面内の全ハッチングを一括更新する最適化ルーチン
Public Sub BatchUpdateHatches()
Dim doc As AcadDocument
Dim ss As AcadSelectionSet
Dim ent As AcadEntity
Dim hatchObj As AcadHatch
Dim filterType(0) As Integer
Dim filterData(0) As Variant
Set doc = ThisDrawing
‘ 選択セットの作成(既存の名前があれば削除する安全策)
On Error Resume Next
doc.SelectionSets.Item(“HatchSet”).Delete
On Error GoTo 0
Set ss = doc.SelectionSets.Add(“HatchSet”)
‘ フィルタリング:Hatchエンティティのみを抽出(パフォーマンスの根幹)
filterType(0) = 0
filterData(0) = “HATCH”
ss.Select acSelectionSetAll, , , filterType, filterData
‘ アプリケーションの描画更新を一時停止(パフォーマンス最適化)
Application.Visible = False ‘ 処理速度を向上させるための秘策
For Each ent In ss
Set hatchObj = ent
With hatchObj
‘ パターン変更
.PatternName = “ANSI31”
‘ 尺度変更
.PatternScale = 1.0
‘ 角度変更(ラジアン指定に注意)
.PatternAngle = 0.785398 ‘ 45度
‘ 変更を確定させる
.Update
End With
‘ 参照の解放
Set hatchObj = Nothing
Next ent
Application.Visible = True
‘ 後始末
ss.Delete
Set ss = Nothing
End Sub
—
3. シニアエンジニアが押さえるべき「罠」
パターンファイル(.pat)の所在
`PatternName`を変更する際、AutoCADがそのパターンをロード済みであることを前提とするのは危険だ。システム変数 `MEASUREMENT` や、サポートパスに含まれる `.pat` ファイルの整合性がとれていない場合、実行時エラーが発生する。大規模なシステムでは、API経由でパターンを強制ロードするプロセスを前段に組み込むべきだ。
角度指定の罠
`PatternAngle`は常にラジアンで指定する必要がある。度数法からラジアンへの変換(`angle (PI / 180)`)を定数として管理せよ。また、ハッチングの基点(`Origin`)が不適切だと、見た目が大きく崩れる。一括更新の際は、必要に応じて`hatchObj.Origin = targetPoint`を検討すること。
Windows APIによる「重い図面」の制御
処理が長時間に及ぶ場合、`DoEvents`をループ内に挿入し、Windowsメッセージキューを処理させることが肝要だ。しかし、`DoEvents`の乱用は再入可能な実行によるスタックオーバーフローを招く。`GetTickCount`等のWindows APIを用いて、一定時間経過時のみ`DoEvents`を呼ぶという「間引き制御」が、伝説的なエンジニアの流儀である。
—
4. 終わりに:アーキテクチャの視点
VBAはレガシーと言われるが、AutoCADの内部オブジェクトモデルを直接叩ける唯一の言語として、今なおその価値は揺るがない。
今回のコードは、単に「動けば良い」というレベルではない。選択セットをフィルタリングで絞り込み、メモリを解放し、描画更新を制御する。このプロセスこそが、数千ものオブジェクトを扱う実務環境における「正解」である。
君たちが開発するシステムが、ただ機能するだけでなく、いかにエレガントに、いかに過酷な環境を生き抜くか。それを追求し続けることこそが、エンジニアの矜持である。
質問があればいつでも受け付ける。ただし、基礎的な文法についてはリファレンスを読み込んでからにすることだ。我々の時間は、もっと高度な設計のためにあるのだから。
