AutoCAD VBAの深淵:GetPointの「ラバーバンド」でUIを極限まで洗練させる
AutoCADのオートメーションにおいて、ユーザー体験(UX)を決定づけるのは「いかにCADらしく振る舞うか」という一点に尽きる。素人が書いたコードは、ユーザーに座標入力を強いる際に「無言のカーソル」を突きつけるが、プロフェッショナルは「ラバーバンド」という視覚的フィードバックで対話を行う。
今回は、`AcadUtility.GetPoint`の第2引数(Prompt)と第3引数(Point)を使いこなし、ユーザーの直感に訴える動的なインターフェースを実装する極意を伝授する。
—
なぜ「ラバーバンド」が不可欠なのか
AutoCAD標準のコマンド(`LINE`や`MOVE`など)を触っていて違和感を感じたことはないはずだ。それは、操作の過程で常に「結果のプレビュー」が動的に描画されているからだ。
`Utility.GetPoint`は、単に座標を取得するだけのメソッドではない。第3引数に「始点」を渡すことで、AutoCAD内部のグラフィックスエンジンは自動的に始点と現在地を結ぶベクトルを計算し、ラバーバンドを描画する。この「暗黙の仕様」を使いこなすか否かで、ツールの格が決定的に変わる。
実装:動的なベクトルフィードバックの構築
以下のコードは、単に点を得るだけでなく、始点からの動的な追従を実現する設計である。
Option Explicit
‘ 伝説のエンジニアとして警告しておくが、VBAのオブジェクトは寿命管理が全てだ。
‘ AcadApplicationやDocumentをグローバルで保持し続ける悪癖は、メモリリークの元凶となる。
Public Sub DrawRubberBandExample()
Dim doc As AcadDocument
Dim util As AcadUtility
Dim startPoint As Variant
Dim endPoint As Variant
Set doc = ThisDrawing
Set util = doc.Utility
On Error Resume Next ‘ ユーザーのESC中断をスマートに捌く
‘ 1. 始点の取得
startPoint = util.GetPoint(, vbCrLf & “始点を指定してください: “)
If Err.Number <> 0 Then Exit Sub
‘ 2. ラバーバンドを伴う終点の取得
‘ ここが極意。第3引数(startPoint)を指定することで、
‘ AutoCADは自動的にラバーバンドを描画する。
endPoint = util.GetPoint(startPoint, vbCrLf & “終点を指定してください: “)
If Err.Number = 0 Then
‘ 3. 図形の生成(ここではラインを配置)
Dim lineObj As AcadLine
Set lineObj = doc.ModelSpace.AddLine(startPoint, endPoint)
lineObj.Update
End If
‘ 明示的解放:VBAのガーベジコレクションを待つな
Set lineObj = Nothing
Set util = Nothing
Set doc = Nothing
End Sub
—
シニアエンジニアが意識すべき「裏側の挙動」
このコードをただコピペするだけでなく、以下の3つの観点からシステムを俯瞰してほしい。
1. メモリ管理とオブジェクトの生死
VBAにおいて、`AcadDocument`や`AcadModelSpace`への参照を保持し続けると、COMの解放が遅延し、AutoCADの動作が不安定になる。特に大規模図面では顕著だ。関数の出口では必ず `Set = Nothing` を実行し、参照カウントを確実にデクリメントする。これが「落ちないツール」の絶対条件だ。
2. Windows APIによる割り込みと非同期処理
複雑なツールになると、`GetPoint`中にキーボード入力やダイアログの割り込みが発生する場合がある。もし`GetPoint`が期待通りに動作しない(ラバーバンドが出ない)場合は、呼び出し元の関数がフォーカスを奪っていないか確認せよ。Windows APIの `SetForegroundWindow` を使い、AutoCAD本体へ強制的にフォーカスを戻す処理を組み込むのが、堅牢なシステム構築の定石である。
3. レガシー環境と.NETへの橋渡し
AutoCAD VBAはレガシーであるが、その設計思想は現在の ObjectARX や .NET API (C#) と根底で繋がっている。`Utility.GetPoint` が行っていることは、内部的には `acedGetPoint` と同じだ。この挙動を理解しておくことは、将来的にC#へ移行する際、`Editor.GetPoint` を使いこなすための強力な資産となる。
結論:ツールは「CADの一部」であれ
ユーザーはあなたの書いたツールを「プログラム」として見ているのではない。AutoCADという巨大な環境の一部として期待しているのだ。だからこそ、標準コマンドと操作感が乖離してはならない。
`GetPoint` にラバーバンドを実装せよ。それが、システム管理者として、またエンジニアとして、ユーザーへの最大の敬意を示す方法である。
次回の記事では、このラバーバンドに「吸着(OSNAP)の動的制御」を加える、さらに一段上のハックについて触れるとしよう。コードを書き続けろ。それだけが、唯一の証明だ。
