AutoCAD VBAの深淵:Polyline操作から紐解くメモリ管理とアーキテクチャの真髄
AutoCADのオートメーションにおいて、`AcadLWPolyline`は単なる図形ではない。それはデータベース上のインデックスであり、メモリ上の構造体であり、そしてレンダリングエンジンへの命令書だ。
多くの初学者は「ポリラインを作って終わり」にするが、我々のようなシステムアーキテクトは、その裏で何が起きているかを見極める必要がある。今日は、ポリラインの生成と編集を通じ、レガシー環境を生き抜くための「真のAutoCAD開発」について語ろう。
—
1. 座標配列の物理的解釈とメモリへの負荷
ポリラインの作成において、初心者は頻繁に「動的配列の再定義(`ReDim`)」を繰り返す。これは極めて低効率だ。VBAにおいて、`Variant`型で渡す座標配列は、一度の呼び出しでCOM境界をまたぐ。
以下のコードは、効率的かつ堅牢にLWPolylineを生成するための「型」となる。
Public Sub CreateOptimizedPolyline()
Dim acadDoc As AcadDocument: Set acadDoc = ThisDrawing
Dim polyObj As AcadLWPolyline
Dim points(0 To 5) As Double ‘ 2点×2次元 = 4要素だが、インデックスは0-5まで確保
‘ 座標データの初期化(明示的な値代入)
points(0) = 0#: points(1) = 0#
points(2) = 100#: points(3) = 0#
points(4) = 100#: points(5) = 100#
‘ モデル空間へのオブジェクト生成
Set polyObj = acadDoc.ModelSpace.AddLightWeightPolyline(points)
‘ 属性設定の最適化
With polyObj
.ConstantWidth = 2.0 ‘ 線の太さ
.Closed = True ‘ 閉合フラグ
.Update ‘ 変更を反映
End With
‘ メモリ解放の儀式
Set polyObj = Nothing
Set acadDoc = Nothing
End Sub
伝説的エンジニアの勘所
`AddLightWeightPolyline`を使用せよ。古い`Polyline`オブジェクト(2D/3D)はもはやレガシーの遺物であり、メモリ消費量がLWPolylineの数倍に達する。現代のAutoCADアーキテクチャではLWPolylineがデフォルトであり、唯一の正解だ。
—
2. 頂点編集:AddVertexの罠と再描画のタイミング
頂点の追加・削除を行う際、`AddVertex`を多用してはいけない。AutoCADのCOMサーバーは、頂点追加のたびに再計算(Re-calculate)を走らせようとする。
大量の頂点を一度に処理する場合、「一度データベースから分離し、配列を更新してから戻す」のがパフォーマンスの定石だ。
‘ 頂点を追加する際の、メモリを考慮したアプローチ
Public Sub AppendVertexToPolyline(polyObj As AcadLWPolyline, x As Double, y As Double)
Dim n As Integer
n = (UBound(polyObj.Coordinates) + 1) / 2
‘ 頂点を追加(この時、AutoCADは内部で配列を再確保している)
polyObj.AddVertex n, Array(x, y)
‘ 大規模な処理であれば、最後に一度だけUpdateを呼ぶ
polyObj.Update
End Sub
—
3. レガシー環境とWindows APIによる「割り込み」
長年稼働しているAutoCADシステムには、時としてVBAの標準機能では解決できない「UIのフリーズ」や「座標系の不一致」が発生する。ここで出番となるのがWindows APIだ。
例えば、大量のポリラインを生成する際、AutoCADの画面描画を一時的に停止させ、プロセッサ時間を計算に集中させる。
‘ APIの宣言(モジュールヘッダーへ記述)
If VBA7 Then
Private Declare PtrSafe Sub Sleep Lib “kernel32” (ByVal dwMilliseconds As Long)
Else
Private Declare Sub Sleep Lib “kernel32” (ByVal dwMilliseconds As Long)
End If
‘ 描画の負荷を制御するアーキテクチャ
Public Sub BatchProcess()
ThisDrawing.Utility.Prompt “処理開始…”
‘ 描画更新をオフ(パフォーマンス向上の秘訣)
Application.Visible = False
‘ …処理ロジック…
Application.Visible = True
ThisDrawing.Regen acActiveViewport
End Sub
—
4. 最後に:メモリ管理の鉄則
AutoCAD VBAは、現代の言語と比較してメモリ管理が極めて脆弱だ。特にCOMオブジェクトをループ内で生成し、解放し忘れると、AutoCADのプロセスは数時間でメモリリークにより肥大化し、クラッシュする。
1. オブジェクト変数は必ず `Set = Nothing` で解放せよ。
2. `ThisDrawing` などのグローバル参照に頼らず、明示的に変数へ割り当て、スコープを最小化せよ。
3. エラーハンドラ(`On Error GoTo`)を必ず記述し、異常終了時もオブジェクトをクリーンアップする体制を構築せよ。
コードを美しく保つこと。それがシステムの信頼性に直結する。AutoCADの内部モデルを掌握し、プログラムに「意思」を吹き込むこと。それこそが、我々業務自動化エンジニアの誇りである。
次は、もっと深い「ObjectARXとの境界線」について話そうか。準備ができたらまた来い。
