【テクニカル・上級編】【実務中級】AcadDocument.Utility.InitializeUserInputによる入力制限:キーワードと数値入力をスマートに制御する – AutoCAD VBA解析バイブル

スポンサーリンク

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自動化の深淵で、さらなる高みを目指そう。

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