Visio VBAの深淵:Geometryセルの「頂点データ」を完全に掌握し、幾何構造を再構築する
Visioの図形(Shape)を単なる「絵」として扱っているうちは、アマチュアの域を出ません。エンジニアとして、Visioが内部で保持するGeometry(幾何)データを構造的に読み解き、プログラムで再定義できるようになれば、自動作図や図面変換の自動化において無敵の領域に到達できます。
今回は、Visio VBAにおいて最も難解かつ強力な「Geometryセルのパス解析」の核心を突き、実務で耐えうる堅牢なコードを授けます。
—
1. なぜ「Geometry」の理解が重要なのか
多くの初心者が `Shape.Cells(“Width”)` や `Height` でサイズを操作しようとしますが、複雑な多角形や自由曲線はこれでは制御できません。Visioの図形は、Geometryセクションという「座標のリスト」によって定義されています。
この内部構造を理解せず、`Shape.Duplicate` やコピー&ペーストに頼る自動化は、いずれ「予期せぬ図形の崩れ」という負債を生みます。頂点座標を直接抽出し、別の図形として再構築する。これが、再現性の高い自動化への唯一の正攻法です。
—
2. Geometry構造の解剖学:行とセルの関係
Geometryセクションは複数の行(Row)で構成されます。重要なのは以下の3つの行タイプです。
- MoveTo: パスの開始点。
- LineTo: 直線で結ぶ次の点。
- ArcTo/EllipticalArcTo: 円弧。今回は多角形解析の基本として、MoveToとLineToの解析に焦点を絞ります。
VBAでこれらを処理する際、`Section` -> `Row` -> `Cell` という階層構造を正確に辿る必要があります。
—
3. プロダクションレベルの頂点取得・再構築コード
以下のコードは、選択した図形の頂点座標を配列として抽出し、それを基に全く新しい図形を作成するテンプレートです。
Option Explicit
‘ 選択した図形の頂点座標を取得し、新しいページに同じ形状を描画する
Public Sub ReconstructShapeFromGeometry()
Dim shpSource As Visio.Shape
Dim vsoSection As Visio.Section
Dim vsoRow As Visio.Row
Dim i As Integer, j As Integer
Dim points() As Double
Dim pointCount As Integer
If ActiveWindow.Selection.Count = 0 Then Exit Sub
Set shpSource = ActiveWindow.Selection(1)
‘ Geometryセクションは複数存在する場合がある(通常はGeometry1)
Set vsoSection = shpSource.Section(visSectionFirstComponent)
pointCount = 0
ReDim points(0 To 1, 0 To 0)
‘ 行をループして座標を収集
For i = 0 To vsoSection.Count – 1
Set vsoRow = vsoSection.Item(i)
‘ MoveTo または LineTo のみ対象とする
If vsoRow.RowType = visTagMoveTo Or vsoRow.RowType = visTagLineTo Then
ReDim Preserve points(0 To 1, 0 To pointCount)
‘ Visioの単位は常に内部単位(インチ)で取得すること
points(0, pointCount) = vsoRow.Cell(“X”).ResultIU
points(1, pointCount) = vsoRow.Cell(“Y”).ResultIU
pointCount = pointCount + 1
End If
Next i
‘ 収集したデータで新しい図形を作成
Call CreateShapeFromPoints(points)
End Sub
Private Sub CreateShapeFromPoints(ByRef coords() As Double)
Dim vsoPage As Visio.Page
Dim vsoShp As Visio.Shape
Set vsoPage = ActivePage
‘ DrawPolylineメソッドは頂点配列を受け取って図形を作る
Set vsoShp = vsoPage.DrawPolyline(coords, visPolyline1D)
vsoShp.Text = “再構築された図形”
End Sub
—
4. 堅牢な設計のための「3つの鉄則」
現場でバグを生まないための、アーキテクトとしての助言です。
1. 単位系を統一せよ: `ResultIU` プロパティを使ってください。`Result(“mm”)` などを使うと、図面の表示単位設定に依存してしまい、計算誤差や予期せぬオフセットが発生します。常に内部単位(インチ)で計算し、最後に必要な単位へ変換するのがプロの流儀です。
2. グループ化(Group)の考慮: 対象の図形がグループ化されている場合、頂点座標は「グループ内座標系」になります。必要に応じて `GlueTo` や `Transform` を組み合わせ、親グループの座標を考慮した変換(行列演算)を行う必要があります。
3. データベース連携の罠: 座標をDBに保存する場合、JSON形式で `[{“x”:0.1, “y”:0.2}, …]` のようにシリアライズしてください。浮動小数点数をそのままSQLに投げると、ロケール設定によりカンマとドットが混在し、データが破損します。
—
5. 次のステップへ
この手法を応用すれば、Excel上の表データからフローチャートを自動生成したり、CADデータから変換したCSVをVisioに流し込んで自動作図することが可能です。
Geometry解析はVisio APIの中でも「黒魔術」に近い領域ですが、一度習得すれば、あなたの作成するツールは単なる「お助けスクリプト」から、「組織の生産性を根底から変える基盤システム」へと進化します。
コードをコピペして終わりにするのではなく、なぜその行が必要なのか、なぜそのプロパティを使うのかを自問自答してください。それが、真のエンジニアへの道です。
