【テクニカル・上級編】Visio固有の単位系に悩まない:VisioInternalUnitsと実寸・ポイント値の相互変換マクロ – Visio VBA解析バイブル

スポンサーリンク

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

”’

”’ 指定したミリメートル値をVisio内部単位(インチ)に変換する
”’

Public Function MmToInternal(ByVal mmValue As Double) As Double
‘ ConvertResultを通さず直接演算することで、計算コストを最小化する
MmToInternal = mmValue MM_TO_INCH
End Function

”’

”’ Visio内部単位(インチ)をミリメートル値に変換する
”’

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ピクセルの狂いも許さないプロフェッショナルなアーキテクチャの構築につながる。

コードを書くとき、いつも自問せよ。
「この変換は、本当にその単位系が必要か? それとも、内部値で計算できるのではないか?」と。

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