エンジニア諸君、今日も図面の中に魂を込めているだろうか。
単に「動くコード」を書くレベルは卒業したはずだ。我々が目指すべきは、ユーザーの思考を妨げず、意図を正確に図面に反映させる「道具」としてのプログラムである。
今回は、AutoCAD VBAにおけるユーザーインターフェースの要とも言える、`AcadDocument.Utility.GetDistance` を取り上げる。特に「ベースポイント」を指定し、視覚的なフィードバック(ラバーバンド)を伴う距離入力の実装だ。
なぜこれが必要なのか? 単に数値を入力させるだけなら `InputBox` で事足りる。しかし、CADの現場では「あの点から、この辺りまでの距離」という直感的な操作が不可欠だ。この「直感」をシステムに繋ぐための作法を、チーフアーキテクトの視点から徹底解説する。
—
1. 「点」ではなく「体験」を設計せよ:ラバーバンドの重要性
`GetDistance` メソッドには、省略可能な第1引数 `BasePoint` が存在する。これこそが「素人」と「プロ」を分ける境界線だ。
- 引数なしの場合: ユーザーは2点をクリックする。1点目をクリックするまで、画面には何も表示されない。
- ベースポイントを指定した場合: 1点目は既にプログラム側で定義されており、ユーザーがマウスを動かすと、その点からカーソルまで「ラバーバンド(伸縮線)」が表示される。
この視覚的なフィードバックがあるだけで、操作ミスは激減する。ユーザーは「どこを基準に、どの方向に、どれくらいの距離を取ろうとしているのか」をリアルタイムで確信できるからだ。
2. 堅牢な設計:ユーザーの「キャンセル」をどう捌くか
実務レベルのコードで最も重要なのは、正常系ではなく異常系(例外処理)だ。
AutoCADの対話型メソッド(Get系)は、ユーザーが `ESC` キーを押したり、右クリックでキャンセルしたりすると、即座に実行時エラーを吐いてプログラムを停止させる。
「エラーが出たのでマクロが止まりました」は、プロの仕事ではない。
これをエレガントにトラップし、適切にリソースを解放して終了させる設計が求められる。
3. プロダクション・コード:`GetDistance` のカプセル化
以下のコードは、単なるサンプルではない。私が実際のプロジェクトで基盤として採用する、堅牢なラッパー関数をベースにした実装例だ。
Option Explicit
”’
”’
Public Sub InteractiveDistanceExample()
Dim basePt As Variant
Dim dist As Double
On Error Resume Next
‘ 1. まず基準となる点を選択させる(または計算で算出する)
‘ ここではユーザーに1点目を選ばせる
basePt = ThisDrawing.Utility.GetPoint(, vbCrLf & “基準点を選択してください: “)
If Err.Number <> 0 Then
Debug.Print “基準点の選択がキャンセルされました。”
Exit Sub
End If
On Error GoTo 0
‘ 2. 本題:ベースポイントを指定して距離を取得
‘ GetDistance(BasePoint, Prompt)
‘ この第1引数が「ラバーバンド」を出現させる鍵だ
dist = SafeGetDistance(basePt, “オフセットする距離を指定、または画面上でクリック: “)
‘ 3. 結果の判定(戻り値が負の場合はキャンセルとみなす設計)
If dist < 0 Then
MsgBox "操作がキャンセルされました。", vbInformation, "中止"
Exit Sub
End If
' 4. 業務ロジックへの適用(例:取得した距離を表示)
MsgBox "確定した距離: " & Format(dist, "0.000") & " mm", vbInformation, "結果"
' ここでデータベース連携や、Excelへの書き出し、図形作成を行う
' Call UpdateDatabase(dist)
End Sub
'''
”’
”’ 基準点
”’ プロンプト文字列
”’
Private Function SafeGetDistance(ByVal basePoint As Variant, ByVal prompt As String) As Double
On Error Resume Next
Dim result As Double
‘ AutoCADのUtilityメソッドは、エラーハンドリングが必須
‘ Err.Number 0以外は、ESCキーによるキャンセル、または不正入力
result = ThisDrawing.Utility.GetDistance(basePoint, prompt)
If Err.Number <> 0 Then
SafeGetDistance = -1 ‘ キャンセルを示すフラグ
Err.Clear
Else
SafeGetDistance = result
End If
End Function
コードの急所:アーキテクトの解説
1. Variant型とDouble配列の互換性: AutoCAD VBAの `GetPoint` や `GetDistance` は内部的に `Double(0 To 2)` の配列を期待しているが、戻り値や引数としては `Variant` で受けるのが最も安全だ。型変換のオーバーヘッドよりも、実行時エラーの回避を優先している。
2. カプセル化: `SafeGetDistance` という関数に切り出した点に注目してほしい。メインロジックの中に `On Error Resume Next` を散布させるのは三流だ。例外が起きやすい「対話型処理」を分離することで、メインコードの可読性と保守性を担保している。
3. ユーザーへの配慮: プロンプト文字列の先頭に `vbCrLf` を入れている。これにより、AutoCADのコマンドライン上でメッセージが改行され、視認性が向上する。
—
4. 実務での応用:ファイル・データベース連携への発展
この `GetDistance` で得た数値は、単なる浮動小数点数ではない。「現場の意思」そのものだ。
- Excel連携: 取得した距離を部材の長さとして、積算用Excelシートに自動書き出しする。
- データベース同期: 特定の属性(Handle)を持つオブジェクト間の距離を計測し、設備管理DBの値を動的に更新する。
その際、注意すべきは「単位系(Units)」だ。
AutoCAD内部では単なる数値(Unitless)として扱われるが、外部システムと連携する際は、`ThisDrawing.GetVariable(“LUNITS”)` や `LUPREC` を参照し、図面の単位設定と整合性を取らなければならない。これを怠ると、ミリメートルとメートルの混在という、エンジニアリングにおける致命的なミスを招く。
結論:神は細部に宿る
`GetDistance` に `BasePoint` を渡す。
たったこれだけのことで、ツールの品位は劇的に向上する。
ユーザーが迷わず操作でき、かつ予期せぬ中断(ESCキー)にも動じない。そんな「プロの道具」を、君たちのコードで実現してほしい。この記事が、君が真のシステムアーキテクトへと昇華する一助となれば幸いだ。
次は、この入力値を用いて「動的に図形をトランスフォームさせる」高度なイベントハンドリングの世界で会おう。
