【テクニカル・上級編】【実務中級】AcadDocument.Utility.InitializeUserInputのビットコード(1, 2, 4)を駆使し、ゼロ入力や空入力を防ぐバリデーション術 – AutoCAD VBA解析バイブル

スポンサーリンク

AutoCAD VBAを掌握する極限の知見:`InitializeUserInput`のビットコードを制す者だけが到達できる堅牢なバリデーション術

シニアエンジニアやプラント・建築の社内システムを統括するアーキテクトであれば、AutoCAD VBAにおける「ユーザー入力の不確実性」に幾度となく泣かされてきたはずだ。
`ThisDrawing.Utility.GetReal` や `GetInteger` は便利だが、素のまま呼び出せば、現場のオペレーターが誤って「0」を入力し、ゼロ除算エラー(Error 11)でプロセスが沈黙する。あるいは、「負の寸法」という物理法則を無視したデータが、下流のDXF出力や構造計算モジュールを汚染する。

VBAのエラーハンドリングで場当たり的に `On Error Resume Next` を多用する時代は終わった。
真に洗練されたCAD自動化アーキテクチャとは、APIのネイティブな制約(ビットコード)を極限まで利用し、CADのコマンドラインのレイヤーで不正入力を物理的に拒絶することにある。

今回は、`AcadDocument.Utility.InitializeUserInput` のビットコード(1, 2, 4)を完全支配し、極限まで堅牢な入力を担保する実務的アプローチを詳解する。

1. なぜ `GetReal` 単体では実務に耐えないのか?

多くの初学者は、以下のようなコードを書く。

‘ 【アンチパターン】これでは実務の現場でバグが頻発する
Dim dValue As Double
dValue = ThisDrawing.Utility.GetReal(“数値を入力してください: “)
‘ ユーザーが「0」や「-10.5」を入力した場合の防壁がここにない

このコードの最大の問題点は、AutoCADのユーザー対話ループの外側でバリデーションを行っている点だ。
ユーザーが意図せず `0` を入れたり、Enterキーのみ(空入力)で抜けたりした場合、VBAの実行コンテキストに制御が戻ってから初めてエラー検知し、ループを回して再入力を促すという無駄なオーバーヘッドが発生する。

さらに悪いことに、ユーザーがESCキーを押した際のランタイムエラー(Err.Number = -2147352567 / Automation Error)のハンドリングを毎回記述するのは、コードベースを肥大化させる悪臭(Bad Smell)でしかない。

2. `InitializeUserInput` のビットコード仕様とメモリ・ライフサイクルの真実

`InitializeUserInput` は、次に実行される `Get` 系メソッド(`GetReal`, `GetInteger`, `GetKeyword` など)の入力ルールを一時的に定義する、AutoCAD ActiveX APIの隠れた名機能だ。

このメソッドの第一引数 `BitFlags` は、ビット演算(OR結合)によって複数の制約を同時に課すことができる。実務で最も使用頻度が高く、かつ必須となるビットコードは以下の3つだ。

  • `1` (bit 0): ゼロ(0.0)入力を禁止する
  • ユーザーが `0` を入力した場合、AutoCADは入力を受け付けず、コマンドラインにエラーメッセージを表示して再入力を促す(VBA側に制御を戻さない)。
  • `2` (bit 1): 負数(Negative)入力を禁止する
  • 幾何データや寸法の入力において、負の値は致命的なデータ破損を招く。これをAPIレベルで遮断する。
  • `4` (bit 2): 空入力(Null / Enterのみ)を禁止する
  • 何も入力せずにEnterが押された場合、デフォルト値のフォールバックを強制するか、入力を再試行させる。

ビット演算の組み合わせ

例えば、「ゼロ不可」「負数不可」を同時に適用したい場合、`1 + 2 = 3` を指定する。
すべての防壁を張る場合は `1 + 2 + 4 = 7` となる。

3. 【実装コード】実務レベルの堅牢な入力ラッパー関数

現場のコードベースにそのまま組み込める、極限まで最適化された入力取得関数の実装例を提示する。
このコードでは、ESCキーによるキャンセル(エラー)の適切な捕捉と、メモリ(COMオブジェクト)のライフサイクル管理への配慮も内包している。

Option Explicit

” ==============================================================================
” 堅牢な実数入力を取得するラッパー関数
” @param PromptMessage コマンドラインに表示するプロンプト
” @param AllowZero True: 0を許可 / False: 0を拒否 (Bit 1)
” @param AllowNegative True: 負数を許可 / False: 負数を拒否 (Bit 2)
” @param AllowNull True: 空入力を許可 / False: 空入力を拒否 (Bit 4)
” @param OutValue 取得した数値を格納する変数(参照渡し)
” @return 正常取得時はTrue、キャンセル時はFalse
” ==============================================================================
Public Function GetValidatedReal( _
ByVal PromptMessage As String, _
ByVal AllowZero As Boolean, _
ByVal AllowNegative As Boolean, _
ByVal AllowNull As Boolean, _
ByRef OutValue As Double) As Boolean

Dim bitCode As Integer
bitCode = 0

‘ ビットフラグの構築
If Not AllowZero Then bitCode = bitCode + 1 ‘ 1: ゼロ不可
If Not AllowNegative Then bitCode = bitCode + 2 ‘ 2: 負数不可
If Not AllowNull Then bitCode = bitCode + 4 ‘ 4: 空入力不可

On Error GoTo ErrorHandler

‘ ユーティリティオブジェクトの参照をローカル変数にキャッシュ(COM Interopの最適化)
Dim util As AcadUtility
Set util = ThisDrawing.Utility

‘ 入力ルールの初期化(次のGet系メソッドにのみ有効)
util.InitializeUserInput bitCode, “”

‘ ユーザー入力を取得
OutValue = util.GetReal(PromptMessage)

‘ 正常終了
GetValidatedReal = True
GoTo CleanUp

ErrorHandler:
‘ Err.Number -2147352567 (またはユーザーによるESC中断) の処理
If Err.Number <> 0 Then
‘ キャンセルされた場合は静かにFalseを返す
GetValidatedReal = False
End If

CleanUp:
‘ COMオブジェクトの参照解放(VBAにおけるメモリ最適化の定石)
Set util = Nothing
Exit Function
End Function

このコードのアーキテクチャ的優位性

1. COMインターロップの最適化: `ThisDrawing.Utility` への多重アクセスを避け、ローカル変数 `util` にキャッシュすることで、COMのマーシャリングコストを最小限に抑えている。
2. 確実な参照解放: `Set util = Nothing` により、VBAランタイムとAutoCADプロセス間の参照カウンタを適切にデクリメントし、メモリリークを根絶する。
3. 呼び出し側のクリーンネス: 呼び出し側では `If GetValidatedReal(…) Then …` と記述するだけでよく、複雑なエラーハンドリングやバリデーションロジックから解放される。

4. 応用:システム間連携を見据えたデータ整合性の担保

プラント設計や大規模BIM/CIMデータ連携において、AutoCADから抽出された数値データがそのまま外部データベース(Oracle, SQL Server等)やERPに流し込まれるケースは多い。

もし、ここで「0」や「不正な負の寸法」が紛れ込んでいたらどうなるか?
下流のシステムでトランザクションエラーが発生し、バッチ処理全体がロールバックされるか、最悪の場合はデータベースにゴミデータが永続化(Corrupt)する。

`InitializeUserInput` を用いたバリデーションは、単なる「CADのUIの利便性向上」ではなく、「全社的なエンジニアリング・データベースの整合性を守るための第一線の防壁(First Line of Defense)」なのだ。

5. チーフアーキテクトからの提言

レガシーなVBAコードベースの保守において、動くからといって場当たり的なコードを放置することは、将来の技術的負債に利息を払い続けるようなものだ。

AutoCAD VBAを「おもちゃのスクリプト言語」から「エンタープライズ・エンジニアリング・ツール」へと昇華させるためには、API仕様の底にあるメカニズム(今回で言えば `InitializeUserInput` のビット演算システム)を完全に理解し、コードの隅々にまでその思想を浸透させなければならない。

今日からあなたのプロジェクトのすべての数値入力ロジックを見直し、ビットコードによる厳格なバリデーションを導入せよ。それこそが、プロフェッショナルなAutoCAD自動化エンジニアの証である。

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