AutoCAD VBAの深淵:Hatchオブジェクトを掌握し、メモリの鎖を解き放て
AutoCAD VBAにおいて、`AcadHatch`オブジェクトをただ「配置する」だけのコードを書くのは素人の仕事だ。シニアエンジニアである貴殿が直面するのは、数万の境界を持つ図面、動的に変化するパターン定義、そしてAutoCADという巨大なメモリ空間との戦いである。
本稿では、単なるAPIのリファレンスではなく、オブジェクトのライフサイクルを制御し、パフォーマンスの極限を追求するための「ハッチング自動化の正攻法」を伝授する。
—
1. 境界の不確実性と「AddHatch」の真実
`AddHatch`メソッドは、AutoCADのジオメトリエンジンと密接に結びついている。単純なループでハッチングを生成すると、図面の複雑さに応じて処理時間が指数関数的に増大する。
重要なのは、境界オブジェクト(OuterLoop)の評価を最小限に抑えることだ。
‘ 高速なハッチング生成の定石
Public Sub CreateOptimizedHatch(ByVal targetLayer As String, ByVal boundaryObjs As Variant)
Dim hatchObj As AcadHatch
Dim patternName As String: patternName = “ANSI31”
Dim patternType As Long: patternType = acHatchPatternTypePreDefined
Dim bAssociativity As Boolean: bAssociativity = True ‘ 境界と連動させるならTrue
‘ モデル空間へのアクセスをキャッシュする
Dim ms As AcadModelSpace
Set ms = ThisDrawing.ModelSpace
‘ ハッチオブジェクトの生成
Set hatchObj = ms.AddHatch(patternType, patternName, bAssociativity)
‘ 境界の追加(配列として一度に渡すのがパフォーマンスの鉄則)
hatchObj.AppendOuterLoop boundaryObjs
‘ プロパティ設定は評価後に行う
hatchObj.Layer = targetLayer
hatchObj.Evaluate ‘ 明示的な再評価が重要
‘ メモリ解放の儀式
Set hatchObj = Nothing
Set ms = Nothing
End Sub
なぜ `Evaluate` を呼ぶのか?
AutoCADは非同期的な計算を好む。`AppendOuterLoop`直後にプロパティを変更しても、描画エンジンが追いつかず、図面が「壊れたハッチ」として認識されることがある。`Evaluate`は、演算子を強制的に再実行し、メモリ上の整合性を担保する唯一の手段だ。
—
2. メモリ最適化:VBAの「死の淵」を避ける
AutoCAD VBAはGC(ガベージコレクション)が非常に甘い。`AcadDocument`や`AcadDatabase`をループ内で不用意に生成すると、数千回の操作でメモリリークが蓄積し、AutoCAD自体がクラッシュする。
伝説のアーキテクトによる「明示的解放」戦略
以下のパターンを徹底せよ。
- Set = Nothing の強制: ループ内で生成したオブジェクトは、次のイテレーションに入る前に必ずNothingを代入せよ。
- Late Bindingの回避: パフォーマンスが求められる環境では、必ず参照設定(Reference)を行い、Early Bindingを使用すること。COMのディスパッチコストを侮ってはならない。
—
3. レガシー環境での保守性と外部連携
もし、このハッチング処理を外部のExcelシートやデータベースから制御するシステムを構築しているなら、「AutoCADの起動状態」の管理が最大のボトルネックになる。
Windows API `FindWindow` や `GetActiveObject` を使い、既に起動しているインスタンスへのアタッチを確実に行うべきだ。
‘ 既存のAutoCADインスタンスを安全に取得する技術
Public Function GetActiveAcad() As AcadApplication
On Error Resume Next
Set GetActiveAcad = GetObject(, “AutoCAD.Application.24”) ‘ バージョンは環境に合わせて調整
If Err.Number <> 0 Then
‘ インスタンスがない場合は新規生成、もしくはエラーハンドリング
Set GetActiveAcad = New AcadApplication
End If
On Error GoTo 0
End Function
—
4. 極限の知見:パフォーマンスチューニングの極意
最後に、大規模図面を扱う際のアドバイスを一つ。
「`Application.ScreenUpdating` 相当の制御」
AutoCAD VBAにはExcelのような明示的な画面更新フラグは存在しないが、`Application.Visible = False` でバックグラウンド処理を行い、最後に可視化する方法、あるいは `System.Drawing` 関連のAPIを駆使して描画を一時停止させる手法がある。
また、複雑なハッチングを生成する際は、一時的にシステム変数 `HPASSOC` を 0 に設定し、アソシエーション(境界連動)を切ることで、計算コストを劇的に下げられる。処理完了後に 1 に戻せばよい。
結論
ハッチングの自動化とは、単なる図形の描画ではない。AutoCADという巨大なデータベースの整合性を守りながら、いかに効率よくジオメトリを挿入するかという「空間計算の最適化問題」である。
貴殿の書くコードが、数年後のメンテナンス時にも「美しい」と評されることを期待している。VBAは決して死んでいない。正しく使えば、最強の自動化エンジンである。
