Visio VBAの深淵:Geometryセルの「頂点データ」を完全に掌握する
Visioの図形(Shape)を単なる「絵」として扱うのは、初学者の段階で卒業すべきだ。Visioの本質は、各Shapeが保持するShapeSheetという名の「高度な数学的記述」にある。
特に`Geometry`セクションは、図形の魂そのものだ。ここを自在に操作できれば、プログラムによる自動作図はもとより、複雑な回路図のデータ化や、レガシーな図面資産から座標情報を抽出して他システムへ移植するなど、自動化の幅は劇的に広がる。
本稿では、Geometryセルの深層を掘り下げ、頂点座標を抽出・再現するためのアーキテクチャを解き明かす。
—
1. Geometryセルの構造:なぜループ処理だけでは不十分なのか
VisioのGeometryセクションは、単なる座標の羅列ではない。`MoveTo`(開始点)、`LineTo`(直線)、`EllipticalArcTo`(円弧)、`BezierTo`(ベジェ曲線)といった異なる「型」の行が混在する。
頂点座標を正確に取得するには、行の種類(RowType)を判定し、それぞれの数式や値を適切に解釈する必要がある。ここで重要なのは、「Visioの座標系は、デフォルトでインチ単位であり、かつShapeのローカル座標系である」という点だ。これをページ座標(PinX/PinY)に変換するには、`Transform`セルとの行列演算を考慮する必要がある。
—
2. 頂点抽出の極限実装:Geometry走査のVBAコード
以下のコードは、指定したShapeのGeometryセクションを走査し、頂点座標をイミディエイトウィンドウへ出力するプロフェッショナル向けのスニペットだ。
‘ 頂点座標抽出エンジン
Public Sub ExtractShapeGeometry(shp As Visio.Shape)
Dim sec As Visio.Section
Dim rowIdx As Integer
Dim cell As Visio.Cell
Dim rowType As Integer
‘ Geometryセクションの取得
Set sec = shp.Section(visSectionFirstComponent)
For rowIdx = 0 To sec.Count – 1
‘ RowTypeを判定し、パスの挙動を追跡する
rowType = sec.RowType(rowIdx)
Select Case rowType
Case VisRowIndices.visRowVertex
‘ 頂点座標の取得
Dim x As Double, y As Double
x = shp.CellsSRC(visSectionFirstComponent, rowIdx, visX).ResultIU
y = shp.CellsSRC(visSectionFirstComponent, rowIdx, visY).ResultIU
Debug.Print “Row: ” & rowIdx & ” | Type: Move/LineTo | X: ” & x & “, Y: ” & y
Case VisRowIndices.visRowArcTo
‘ 円弧の終点と曲率を解析
Debug.Print “Row: ” & rowIdx & ” | Type: ArcTo”
‘ 必要に応じて他の行タイプ(BezierTo等)を実装
End Select
Next rowIdx
‘ 明示的なオブジェクト解放(メモリリークの防止)
Set sec = Nothing
End Sub
—
3. メモリ管理とパフォーマンスの真実
Visio VBAにおけるメモリ管理は、一見すると自動的に行われるように見えるが、大規模図面をループ処理する際は注意が必要だ。
1. オブジェクトの明示的解放: `Set obj = Nothing` は、VBAでは「参照カウンタを減らす」行為に過ぎないが、Visioの巨大なDOM操作においては、オブジェクトの生存期間を最小化することで、メモリの断片化を確実に抑止できる。
2. イベントの抑止: `Application.DeferRecalc = True` を使用せよ。Geometryを書き換えるたびにVisioが自動再計算を行うと、パフォーマンスは指数関数的に低下する。一括処理の前には必ず `DeferRecalc` を有効にすること。
3. Windows APIの活用: 万が一、座標計算がボトルネックとなる場合は、VBA内部で完結させず、C#などで作成したDLLを呼び出し、メモリ空間で直接行列計算を行うのが、真のアーキテクトの解である。
—
4. レガシー環境とシステム間連携の要諦
社内システムや古いCADデータとの連携において、最も恐ろしいのは「座標系の不一致」である。
- ローカルとグローバルの変換: `Shape.LocalToParent` や `Shape.LocalToPage` といったメソッドを活用し、必ず座標系を統一せよ。
- 単位の罠: `ResultIU`(内部単位であるインチ)を使い、表示上の単位設定(mmやcm)に依存しないコードを書くこと。これは業務自動化において「動くコード」と「壊れるコード」を分かつ境界線だ。
—
結論:Visioを「計算機」として捉えよ
Visio VBAを使いこなすということは、Visioを単なるドローイングソフトとしてではなく、「空間的な意味を持つデータ構造を操作するDBMS」として捉えることと同義だ。
Geometryセルの頂点を取得し、加工し、再構築する。このプロセスをマスターすれば、図面はただの画像から、システムと対話可能なインテリジェントなアセットへと変貌する。
次回の更新では、このGeometryデータをJSON化し、外部Web APIへ送信してクラウド上で図面を自動生成する「サーバーサイドVisioオートメーション」の神髄を解説する予定だ。
技術は裏切らない。ただ、深く潜った者だけが、その真の姿を見ることができる。
