AutoCAD VBAの深淵:`InitializeUserInput`で制御する入力の「品格」
AutoCAD VBAを「ただ動くマクロ」の域から脱却させるには、ユーザー入力をいかに堅牢かつスマートに捌くかにかかっている。多くの初学者は`InputBox`や単純な`GetPoint`で満足するが、シニアエンジニアである我々は、AutoCADという高精細なエンジンに対し、いかに妥協のない入力を強制するかに心血を注ぐべきだ。
今回は、`Utility.InitializeUserInput`を駆使し、レガシーなVBA環境下で入力バリデーションを極限まで最適化する知見を共有する。
—
1. なぜ`InitializeUserInput`を「強制」すべきなのか
AutoCAD APIの`GetInteger`や`GetDistance`は、そのままだと負の値やゼロ入力を許容してしまう。これが図面データの整合性を破壊する最大の要因だ。
`InitializeUserInput`は、次の入力メソッド(`GetXXX`系)の挙動を、直前の一瞬だけ書き換える「状態制御」の仕組みである。ここで重要なのは、ビットコード(BitCode)による制御だ。これを理解せずしてAutoCAD開発は語れない。
ビットコードの代表的構成
- 1 : 空入力(Enterのみ)を禁止する
- 2 : 負の値を禁止する
- 4 : ゼロ値を禁止する
- 8 : 図面範囲外の入力を禁止する
- 128 : 任意の文字列入力を許可する(キーワード活用)
—
2. 実装の極致:エラーハンドリングとキーワード制御の融合
単にビットを立てるだけでなく、キーワードを併用し、プロフェッショナルなコマンドラインUIを構築する例を示す。
‘ @brief 入力バリデーションを極めた距離取得関数
‘ @param promptMsg ユーザーへのプロンプト
‘ @return 取得した距離。失敗時は-1を返す
Public Function GetValidDistance(ByVal promptMsg As String) As Double
Dim util As AcadUtility
Set util = ThisDrawing.Utility
‘ エラーハンドリングの境界を定義
On Error Resume Next
‘ ビットコード: 1(空不可) + 2(負不可) + 4(ゼロ不可) = 7
‘ ユーザーが「Auto」「Manual」等のキーワードを入力した場合にも対応
util.InitializeUserInput 7, “Auto Manual”
Dim retVal As Variant
retVal = util.GetDistance(, promptMsg & ” [Auto/Manual]
If Err.Number <> 0 Then
‘ キーワード入力時やキャンセル時の処理
If Err.Number = -2145386489 Then ‘ ユーザーキャンセル
GetValidDistance = -1
Else
‘ キーワードが入力された場合の判定
‘ AutoCADはキーワード入力をString型で返す
If VarType(retVal) = vbString Then
Debug.Print “選択されたキーワード: ” & retVal
GetValidDistance = 0 ‘ 特殊値として0を返す設計
End If
End If
Else
GetValidDistance = CDbl(retVal)
End If
‘ オブジェクトの明示的解放はVBAでは参照カウンタ管理だが、
‘ 大規模システムでは明示的にNothingをセットしメモリリークの芽を摘む
Set util = Nothing
End Function
—
3. シニアアーキテクトのための「メモリとパフォーマンス」の知見
VBAのガーベジコレクションは信用してはならない。特にAutoCADのCOMオブジェクトは、明示的に解放しなければメモリ内に残滓を残す。
Windows APIによる「入力中断」の防御
AutoCADのコマンド実行中、ユーザーが予期せぬ操作(Escキー連打など)を行うとスタックが汚染されることがある。これを防ぐには、Windows APIの`GetAsyncKeyState`等で状態を監視するのも一つの手だ。しかし、最も効率的なのは「エラーハンドリングの局所化」である。
- オブジェクトのスコープ: `AcadDocument`や`AcadApplication`をグローバルで保持しすぎない。必要な時に取得し、処理が終われば即座に解放する。これが、長時間の作図作業でも落ちないシステムを作る鉄則だ。
- Variant型の罠: `GetDistance`等の戻り値は必ず`Variant`である。これを安易に`Double`へキャストせず、`VarType`関数で型を確認してから処理する。この一手間が、ランタイムエラーの9割を防ぐ。
—
4. 最後に:レガシーを「保守可能な資産」へ
VBAはオワコンだと言われることもある。だが、AutoCADの深い階層にあるAPIを叩ける言語として、これほどまでに即効性の高いものはない。
あなたが書くその1行の`InitializeUserInput`は、次世代のエンジニアが図面データを破壊しないための「ガードレール」となる。「コードは書くものではなく、運用に耐えるよう設計するもの」という哲学を忘れないでほしい。
今日のコードを明日の標準に。AutoCAD自動化の深淵で、さらなる高みを目指そう。
