Visioの「内部単位」を制する:ピクセルとインチの呪縛からの解放
Visioの自動化において、多くのエンジニアが「なぜか配置が数ミリずれる」「計算結果と画面上の座標が一致しない」という壁に突き当たる。その原因は単純だ。Visioというアプリケーションが、GUI上の表示単位(mm, inch, pt)と、内部的に保持する浮動小数点数(Internal Units)を、極めて独自のアルゴリズムで分離しているからに他ならない。
この記事では、Visioの描画エンジンが何を考え、我々開発者がどう介入すべきか、その「極限の知見」を共有する。
—
1. Visio内部単位の真実:なぜ `0.03937` なのか
Visioの内部座標系は、常にインチ(inch)をベースとした浮動小数点数値だ。たとえ図面設定がミリメートル(mm)であっても、ShapeSheetに書き込まれる値は、内部的にはインチに換算された値として処理される。
多くの初心者が犯す過ちは、`Application.ConvertResult` を乱用することだ。これは便利だが、ループ処理の中で数万回呼び出すにはオーバーヘッドが大きすぎる。我々が扱うべきは、常に内部値(Double型)であり、変換は最小限に抑えるのが鉄則である。
内部単位変換の定石
以下の定数は、Visioのコアに深く刻まれている。
- 1 inch = 25.4 mm
- 1 inch = 72 pt
これらをハードコーディングするのではなく、`Application.ConvertResult` の挙動をシミュレートする「高速変換関数」を定義しておくことが、システム全体のパフォーマンスを決定づける。
—
2. 実装:高速かつ正確な単位変換クラス
オブジェクトのライフサイクルを意識し、`Application` オブジェクトへの参照を最適化した関数を提示する。VBAにおいて `Application` への頻繁なアクセスはメモリリークやラグの温床となるため、可能な限り呼び出しを制御する。
‘ 単位変換を統括するモジュール
Option Explicit
‘ 高速変換用の定数
Private Const INCH_TO_MM As Double = 25.4
Private Const MM_TO_INCH As Double = 1 / 25.4
”’
”’
Public Function MmToInternal(ByVal mmValue As Double) As Double
‘ ConvertResultを通さず直接演算することで、計算コストを最小化する
MmToInternal = mmValue MM_TO_INCH
End Function
”’
”’
Public Function InternalToMm(ByVal internalValue As Double) As Double
InternalToMm = internalValue INCH_TO_MM
End Function
—
3. シニアエンジニアが留意すべき「精度」の境界線
数値変換において無視できないのが、浮動小数点演算の誤差(Double Precision Error)だ。Visioの座標系は Double 型で保持されるため、非常に微細な差分が累積し、複雑な図形構造では図形の「ねじれ」や「不整合」を引き起こす。
オブジェクトの明示的解放と最適化
大量の図形をループで配置する際、`Shape` オブジェクトを解放し忘れることは、Visioのプロセスを肥大化させる直接の原因となる。
Public Sub BatchLayoutUpdate(ByRef targetPage As Visio.Page, ByVal xPosMm As Double, ByVal yPosMm As Double)
Dim shp As Visio.Shape
Dim xInternal As Double: xInternal = MmToInternal(xPosMm)
Dim yInternal As Double: yInternal = MmToInternal(yPosMm)
‘ 描画の更新を一時停止(パフォーマンスの劇的な向上)
Application.ScreenUpdating = False
For Each shp In targetPage.Shapes
‘ 座標の強制指定(PinX, PinYは常に内部単位)
shp.Cells(“PinX”).ResultIU = xInternal
shp.Cells(“PinY”).ResultIU = yInternal
Next shp
‘ 最後に参照を破棄
Set shp = Nothing
Application.ScreenUpdating = True
End Sub
—
4. 極限の知見:なぜ `ResultIU` なのか
VisioのCellオブジェクトには、`Result` と `ResultIU` という二つのプロパティが存在する。
- Result: 現在のドキュメント設定(mmならmm)に基づいて計算される。
- ResultIU (Internal Units): ドキュメント設定に関わらず、常にインチ(Internal Unit)で値を設定・取得する。
これが最も重要な教訓だ。
システム間連携や異なるテンプレート間でVBAを使い回す際、`Result` を使用するとドキュメントの単位設定に依存してしまい、バグの温床となる。常に `ResultIU` を使い、インチ単位で計算を完結させる。 これこそが、Visio自動化において「ズレを排除する」唯一にして絶対の解である。
—
結論:Visioを「数値の集合体」として捉える
VisioをGUIのドローイングツールとして見ているうちは、中級者から脱却できない。Visioは「座標と数式(ShapeSheet)の巨大なデータベース」である。
単位系の変換に悩まされた時は、常に `ResultIU` に立ち返り、インチベースの浮動小数点計算に集中せよ。それが、何千枚もの図面を自動生成してもなお、1ピクセルの狂いも許さないプロフェッショナルなアーキテクチャの構築につながる。
コードを書くとき、いつも自問せよ。
「この変換は、本当にその単位系が必要か? それとも、内部値で計算できるのではないか?」と。
