【テクニカル・上級編】【初心者向け】AutoCAD VBAで図面上の線分(Line)の始点・終点座標を取得し、距離を計算する – AutoCAD VBA解析バイブル

スポンサーリンク

AutoCAD VBAの深淵:オブジェクトのライフサイクルと幾何学演算の最適解

AutoCAD VBAは「古い」と切り捨てるのは容易い。だが、数十年積み上げられた膨大なレガシー図面資産と、それを自動化するパイプラインにおいて、VBAほど即応性に優れたインターフェースは他に存在しない。

今日は、単純な「線分の距離計算」を題材に、貴殿が書くコードを“動くおもちゃ”から“堅牢な基幹システム”へと昇華させるための極限の知見を授ける。

1. オブジェクトモデルの誤解と真実

`AcadLine`オブジェクトにアクセスする際、多くの初学者は`ThisDrawing.ModelSpace.Item(i)`を無造作に繰り返す。これは大規模図面では自殺行為だ。

AutoCADのオブジェクトモデルはCOM(Component Object Model)ベースであり、参照のたびにマーシャリングが発生する。数万のオブジェクトを扱う際、このオーバーヘッドは数秒から数分の遅延を生む。「参照はローカル変数に退避させ、ループ内でのプロパティアクセスを最小化する」。これが鉄則だ。

2. 幾何学演算の極意と実装コード

線分(`AcadLine`)の始点・終点から距離を求める際、`Sqr((x2-x1)^2 + (y2-y1)^2)`と書くのは、中学生の数学だ。AutoCADエンジニアなら、AutoCADが内部で持つベクタ演算の能力を呼び出すべきだ。

以下に、メモリ効率と実行速度を考慮した実装例を示す。

Option Explicit

”’

”’ 選択された線分の距離を計算し、メモリを適切に解放する
”’

Public Sub CalculateLineLength()
Dim acadObj As AcadObject
Dim lineObj As AcadLine
Dim startPoint As Variant
Dim endPoint As Variant
Dim dist As Double

‘ ユーザーに線分を選択させる(フィルタリングによる最適化)
On Error Resume Next
ThisDrawing.Utility.GetEntity acadObj, basePnt, “線分を選択してください: ”
If Err.Number <> 0 Then Exit Sub
On Error GoTo 0

‘ 型の安全性を確保する(TypeOf演算子は必須)
If TypeOf acadObj Is AcadLine Then
Set lineObj = acadObj

‘ 座標の取得(Variant型で返されるため、配列として扱う)
startPoint = lineObj.startPoint
endPoint = lineObj.endPoint

‘ 距離計算(ユークリッド距離)
‘ ※複雑な計算は Utility.DistanceToReal を活用する手もあるが、
‘ 内部的な演算速度を求めるなら直接計算が最も速い
dist = Sqr((endPoint(0) – startPoint(0)) ^ 2 + _
(endPoint(1) – startPoint(1)) ^ 2 + _
(endPoint(2) – startPoint(2)) ^ 2)

MsgBox “線分の長さ: ” & Format(dist, “0.000”), vbInformation
Else
MsgBox “選択されたオブジェクトは線分ではありません。”, vbExclamation
End If

‘ 【重要】明示的なオブジェクトの解放
‘ VBAのガベージコレクションを待つな。参照を即座に破棄する
Set lineObj = Nothing
Set acadObj = Nothing
End Sub

3. シニアエンジニアが意識すべき「メモリと安定性」の境界線

オブジェクトの明示的解放

VBAは参照カウンタ方式のメモリ管理を行う。ループ内で大量のオブジェクトを生成・破棄する場合、`Set obj = Nothing`を怠ると、AutoCADのプロセスが肥大化し、最悪の場合クラッシュを引き起こす。特に`AcadDocument`や`AcadApplication`のインスタンスを扱う際は、循環参照を徹底的に排除せよ。

Windows APIとの連動

もし、計算結果をクリップボードに自動転送したり、外部データベースとリアルタイム通信する必要があるなら、`Declare PtrSafe`を使用してWindows API(`user32.dll`等)を直接叩く必要がある。VBAの標準機能だけで戦う時代は終わった。OSのメモリ領域を直接操作するスキルは、自動化エンジニアの嗜みだ。

システム間連携の要諦

Excelとの連携は最も多いケースだが、`CreateObject`で毎回インスタンスを立ち上げてはならない。`GetObject`で既存のインスタンスを拾うか、バインディング(事前/事後)の特性を理解して、セッションのライフサイクルを制御せよ。

4. 最後に:伝説のエンジニアへの道

コードを書くことは、ただ目的を達成するだけではない。そのコードが、次の担当者にどう読み取られ、5年後のAutoCADのバージョンアップでどう耐えうるかを設計することだ。

VBAは、正しく扱えば最強の武器になる。
「とりあえず動く」から「枯れた技術として極め尽くす」へ。貴殿のコードが、現場の生産性を極限まで高めることを期待している。

何か深掘りしたい技術的課題があれば、いつでも提示してほしい。我々の戦場は、常に限界のその先にある。

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