AutoCAD VBAの深淵:`Utility.GetPoint`の真価と、メモリを支配する実装術
AutoCADのオートメーションにおいて、`Utility.GetPoint`は単なる座標取得メソッドではない。これはAutoCADのグラフィカルエンジンと対話するための、最も低レイヤーに近いインターフェースの一つだ。
多くの初学者はこのメソッドを「クリックした点を取得するだけのもの」と誤解している。しかし、シニアエンジニアにとって、`GetPoint`は「ラバーバンドの制御権」を掌握するための鍵である。今回は、基準点からの相対ベクトル計算と、実務で不可欠なメモリ管理の作法を紐解く。
—
1. `GetPoint`の第二引数「ベースポイント」がもたらす体験の差
`GetPoint`メソッドのシグネチャ `GetPoint([Point], [Prompt])` において、第一引数に `Variant` 型で基準点を与えることで、AutoCADは自動的に「基準点から現在位置へのラバーバンド線」を描画する。
これを活用せず、自前で `MouseMove` イベントや `Transient Graphics` を使って描画を実装するのは愚策だ。AutoCADの組み込み機能を利用することで、ハードウェアアクセラレーションを最大限に活かした滑らかな操作感を実現できる。
実装コード:相対配置ツール
‘ 基準点からの相対距離指定によるブロック挿入の雛形
Public Sub PlaceObjectRelatively()
Dim acadApp As AcadApplication
Dim doc As AcadDocument
Dim basePoint As Variant
Dim targetPoint As Variant
Set acadApp = ThisDrawing.Application
Set doc = ThisDrawing
On Error Resume Next
‘ ユーザーから基準点を取得
basePoint = doc.Utility.GetPoint(, vbCrLf & “基準点を指定:”)
If Err.Number <> 0 Then Exit Sub ‘ キャンセル時は終了
‘ ベースポイントを引数に渡し、ラバーバンドを起動
‘ これによりユーザーは基準点からの距離を視覚的に確認できる
targetPoint = doc.Utility.GetPoint(basePoint, vbCrLf & “相対配置先を指定:”)
If Err.Number <> 0 Then Exit Sub
‘ オブジェクト生成ロジックへ
Call CreateEntityAt(targetPoint)
‘ 明示的なメモリ解放(VBAにおいては重要)
Set doc = Nothing
Set acadApp = Nothing
End Sub
—
2. メモリ最適化:`Nothing`への回帰とCOM参照の真実
VBAはガベージコレクションを備えていない。`AcadDocument` や `AcadApplication` をモジュールレベルで保持し続けることは、AutoCADのプロセスを肥大化させ、最終的には `Access Violation` を引き起こす主因となる。
- オブジェクト変数の局所化: 可能な限りプロシージャ内で定義し、終了時に `Set x = Nothing` を明示する。
- イベントハンドラの注意: `WithEvents` を用いたイベントリスナーは、参照が循環しやすいため、解放ロジック(`Terminate`時など)を疎かにしてはならない。
大規模なバッチ処理を行う場合、`ThisDrawing` を多用せず、参照をキャッシュした後は適切に破棄することで、メモリリークを最小限に抑えることができる。
—
3. レガシー環境とWindows APIによる「壁」の突破
AutoCAD VBAは本質的にWindows APIと親和性が高い。`GetPoint` だけでは取得できない「キーボード入力のフック」や「ダイアログの前面固定」を行いたい場合、`User32.dll` の出番だ。
例えば、`GetPoint` 中に特定のキー入力を監視してモードを切り替えるような高度な対話ツールを作る場合、`GetAsyncKeyState` を利用する。
‘ キー入力監視の例(抜粋)
Private Declare PtrSafe Function GetAsyncKeyState Lib “user32” (ByVal vKey As Long) As Integer
Const VK_SHIFT = &H10
‘ 処理中にSHIFTキーの状態をポーリングする
If GetAsyncKeyState(VK_SHIFT) <> 0 Then
‘ 高速スナップモードへ切り替える等の拡張ロジック
End If
ただし、APIを呼び出す際は必ず `PtrSafe` 属性を付与し、64bit AutoCAD環境でのスタックオーバーフローを防ぐ必要がある。これが、レガシーコードを現代の設計に適合させるための「作法」である。
—
4. 最後に:伝説的アーキテクトからの助言
技術の深淵を覗くとき、最も危険なのは「動けばいい」という妥協だ。
AutoCAD VBAは、現代の .NET APIと比較すれば確かに古い。しかし、ユーザーの直感的な操作(ラバーバンド)と、エンジニアリングの厳密さ(オブジェクトモデルの管理)を融合させる能力は、どの言語を使おうと色褪せない本質的なスキルである。
`GetPoint` を使いこなすことは、AutoCADという巨大なエンジンの「神経系」に直接触れる行為に等しい。この神経系をいかに制御するか。それが、あなたのツールが「単なるスクリプト」で終わるか、「業務を劇的に変えるシステム」になるかの分水嶺となる。
コードを書け。ただし、その裏側にあるメモリの鼓動を感じながら。
