AutoCAD VBAを掌握する極限の知見:RealToStringがもたらす図面単位の完全調停
AutoCAD VBAによる自動化の現場において、最も初歩的な、そして最も致命的なバグの温床となるのが「数値と単位のミスマッチ」である。
`CStr()` や `Str()` といったVBAのネイティブな文字列変換関数を、図面上の座標や寸法値の生成に安易に使っていないだろうか。もしそうであれば、あなたのコードは異なる単位系(ミリメートル、メートル、インチ)を持つ図面や、建築Inch/Feet表記が混在する環境において、必ず破綻する。
今回は、AutoCADのドキュメントが持つ内部状態――すなわち図面単位系(UNITS)と精度設定を完全にリスペクトし、数値を生きたCADの言葉へと翻訳する `AcadDocument.Utility.RealToString` の極限の活用法を解説する。
—
1. なぜ `CStr` や `Format` では実務に耐えないのか?
AutoCADの内部データベースは、常に「無名の実数(浮動小数点数)」で世界を認識している。しかし、人間(あるいはクライアントの検図基準)は、それを特定の単位とフォーマットで解釈する。
ここで発生するのが、「図面設定と出力文字列の乖離」である。
- `LUNITS`(長さ単位の形式:十進、建築、工学、分数など)
- `LUPREC`(長さの精度:小数点以下の桁数)
- `INSUNITS`(挿入単位:mmなのかmなのか)
これらは図面ごとに `DrawingDefaults` やシステム変数として保持されている。VBAの `CStr(1234.5)` は、図面が「建築表記(フィート・インチ)」であろうと、単に `”1234.5″` という冷たい文字列を返すだけだ。結果として、生成された文字オブジェクト(`AcadText` / `AcadMText`)は、図面のルールを無視した異物となる。
この根本問題を一発で解決するのが、`AcadUtility.RealToString` メソッドである。
—
2. `RealToString` の本質と仕様の罠
まずは、このメソッドのシグネチャと挙動の真髄を確認する。
RetVal = object.RealToString(Real, Unit, Precision)
一見すると単純だが、実務でこれを扱う際には、VBA特有の型安全性とAutoCADのCOMインターフェースの仕様に起因する「罠」が存在する。
引数の仕様
- Real (Double): 変換したい実数。
- Unit (AcDwgUnitDec / AcLinearUnit 等): 変換時の単位フォーマット。
- Precision (Integer): 精度(小数点以下の桁数、または分母の限界値)。
ここで重要なのは、第一引数の `Real` に渡す値のメモリ管理と、第2引数・第3引数を省略あるいは明示的に図面設定と同期させるアプローチである。
—
3. 【実践】図面設定を完全自動追従する高精度変換エンジン
実務の現場では、「現在の図面がどのような単位設定であっても、それに完全に追従し、かつエラーハンドリングが堅牢であること」が求められる。
以下に、シニアエンジニアのプロダクションコードとしてそのまま投入できる、堅牢なラッパー関数を提示する。
Option Explicit
” ==============================================================================
” 凄腕エンジニアのための図面単位調停ユーティリティ
” @param TargetValue 変換対象の数値(図面単位系)
” @param ForceUnit 省略可能:特定の単位形式に強制する場合に指定 (AcLinearUnit)
” @param ForcePrec 省略可能:特定の精度に強制する場合に指定
” @return 図面設定に完全に準拠した文字列
” ==============================================================================
Public Function GetLocalizedDimensionString( _
ByVal TargetValue As Double, _
Optional ByVal ForceUnit As Variant, _
Optional ByVal ForcePrec As Variant) As String
On Error GoTo ErrorHandler
Dim acadDoc As AcadDocument
Set acadDoc = ThisDrawing ‘ 実行中のアクティブドキュメントをキャプチャ
Dim util As AcadUtility
Set util = acadDoc.Utility
Dim targetUnit As Integer
Dim targetPrec As Integer
‘ 1. 単位形式の決定(引数指定がなければ現在の図面設定システム変数 LUNITS を取得)
If IsMissing(ForceUnit) Then
targetUnit = acadDoc.GetVariable(“LUNITS”)
Else
targetUnit = CInt(ForceUnit)
End If
‘ 2. 精度の決定(引数指定がなければ現在の図面設定システム変数 LUPREC を取得)
If IsMissing(ForcePrec) Then
targetPrec = acadDoc.GetVariable(“LUPREC”)
Else
targetPrec = CInt(ForcePrec)
End If
‘ 3. RealToString による高精度変換の実行
‘ COMオブジェクトのライフサイクルを意識し、一時変数を経由して確実に評価
Dim convertedStr As String
convertedStr = util.RealToString(TargetValue, targetUnit, targetPrec)
GetLocalizedDimensionString = convertedStr
‘ 4. 明示的なオブジェクト解放(VBAのCOM参照リークを防ぐ鉄則)
Set util = Nothing
Set acadDoc = Nothing
Exit Function
ErrorHandler:
‘ 異常系:フォールバックとして標準のCStrを返す(ログ出力等をここに挟むべき)
Set util = Nothing
Set acadDoc = Nothing
GetLocalizedDimensionString = CStr(TargetValue)
End Function
—
4. チーフアーキテクトが教える:実務における応用とパフォーマンスの極意
オブジェクトの明示的解放(COMリーク対策)
上記のコードで `Set util = Nothing` や `Set acadDoc = Nothing` を明示的に行っている点に注目してほしい。
VBAのガベージコレクションは頼りにならない。特にAutoCADのCOMオブジェクト(`AcadDocument`, `AcadUtility`など)は、プロシージャを抜けた後も参照カウントが残存し、大規模なバッチ処理を行うとメモリリークやAutoCAD自体のクラッシュ(致命的なエラー)を引き起こす。
オブジェクト変数は使い終わったら即座に `Nothing` を代入して解放する――これがレガシー環境を生き抜くエンジニアの鉄則だ。
システム間連携(Excel・外部DBとのブリッジ)
AutoCAD図面からデータを抽出し、Excelの帳票や外部データベース(SQL Server等)に流し込むシステムを構築する際、「図面上の表記ゆえのパースエラー」が頻発する。
例えば、建築単位(例: `1′-6 1/2″`)の文字列をそのまま外部システムに入れると、数値計算ができなくなる。
逆に、外部システムから受け取った数値を図面に書き戻す際は、今回紹介した `RealToString` の逆、あるいは `RealToString` が解釈できるフォーマットへの変換が必要となる。
Excel側で計算した座標や寸法を、`RealToString` を通してテキスト化し、そのまま `ModelSpace.AddText` に渡すことで、人間が目視で確認する図面と、データベース上の数値の整合性を100%保つことが可能になる。
Sub CreateAnnotationOnDrawing()
Dim acadDoc As AcadDocument
Set acadDoc = ThisDrawing
Dim mSpace As AcadModelSpace
Set mSpace = acadDoc.ModelSpace
Dim insertPoint(0 to 2) As Double
insertPoint(0) = 0#: insertPoint(1) = 0#: insertPoint(2) = 0#
‘ 例:外部から取得した生データ(例:1234.5678)
Double rawVal As Double
rawVal = 1234.5678
‘ 図面設定に合わせた文字列を生成
Dim labelStr As String
labelStr = “測定値: ” & GetLocalizedDimensionString(rawVal)
‘ 図面上の注釈として配置
Dim txtObj As AcadText
Set txtObj = mSpace.AddText(labelStr, insertPoint, 2.5) ‘ 高さは2.5
‘ クリーンアップ
Set txtObj = Nothing
Set mSpace = Nothing
Set acadDoc = Nothing
End Sub
—
総括
`AcadDocument.Utility.RealToString` は、単なるフォーマット関数ではない。それは「AutoCADのデータベースと言語表現を繋ぐ唯一無二の公式通訳」である。
場当たり的な文字列操作でコードを汚すのではなく、図面のメタデータ(`LUNITS`, `LUPREC`)と同期した堅牢なパイプラインを構築すること。それこそが、保守性に優れ、環境の変化に動じないプロフェッショナルなAutoCAD自動化システムの基盤となる。
極限まで最適化されたコードと正しいオブジェクト管理で、あなたのVBAソリューションを次のステージへ引き上げてほしい。
