【実務・中級編】【中級】コネクタの接続関係を逆引き解析:ConnectedShapesメソッドでネットワーク構造を抽出する – Visio VBA解析バイブル

スポンサーリンク

Visioの「暗黙の接続」を掌握せよ:ConnectedShapesによるネットワーク構造の完全抽出

Visioの図面は単なる「絵」ではない。それは、背後に数学的なグラフ構造を隠し持つ「データセット」だ。

多くのエンジニアが陥る罠は、Shapeの座標を力技で計算して接続関係を導き出そうとすることだ。それは無意味だ。Visioには、接続情報をミリ秒単位で引き出すための強力なAPI `ConnectedShapes` が用意されている。

本稿では、このAPIを正しく制御し、フローチャートやネットワーク図から「接続リスト」を抽出する、プロダクションレベルの堅牢なコードを授ける。

—

なぜ「力技の座標計算」をしてはいけないのか

初心者は `PinX` や `PinY` を比較して、図形が重なっているか、あるいはコネクタの終点がどこにあるかを判定しようとする。だが、これはVisioの真の力を殺している。

  • グループ化の罠: グループ化された図形の中にあるShapeの座標は親からの相対値になる。
  • 動的コネクタの挙動: コネクタは常に「接着点」を保持している。座標ではなく、`Connects` オブジェクトと `FromSheet`/`ToSheet` プロパティを追うのが、Visio APIにおける唯一の「正攻法」だ。

`ConnectedShapes` メソッドは、この複雑な接続管理を抽象化し、直接的に「つながっている相手」を配列で返してくれる。これを使わない手はない。

—

堅牢な接続抽出エンジン:実装コード

このコードは、アクティブページ上の全Shapeを走査し、接続関係をExcelのシートに書き出すための基盤となる。

Option Explicit

‘ 接続リスト抽出のメインプロシージャ
Public Sub ExportConnectionList()
Dim vsoPage As Visio.Page
Dim vsoShape As Visio.Shape
Dim vsoConnectedShapes() As Long
Dim i As Long, j As Long

Set vsoPage = ActivePage

‘ エラーハンドリング:オブジェクトの破棄を確実に行う
On Error GoTo ErrHandler

‘ ここでExcelのシートを準備(Application.CreateObject等で)
‘ Debug.Print “FromID, FromName, ToID, ToName”

For Each vsoShape In vsoPage.Shapes
‘ コネクタ自体はスキップする(両端の図形から辿るため)
If Not vsoShape.OneD Then

‘ 接続されているShapeのIDを取得(visConnectedShapesOutgoing: 出力方向)
vsoConnectedShapes = vsoShape.ConnectedShapes(visConnectedShapesOutgoing, “”)

For i = LBound(vsoConnectedShapes) To UBound(vsoConnectedShapes)
Dim targetShape As Visio.Shape
Set targetShape = vsoPage.Shapes.ItemFromID(vsoConnectedShapes(i))

‘ 接続情報をログ出力(ここにExcel書き込み処理を実装)
Debug.Print vsoShape.NameID & ” -> ” & targetShape.NameID
Next i
End If
Next vsoShape

Exit Sub

ErrHandler:
MsgBox “接続情報の抽出中にエラーが発生しました: ” & Err.Description, vbCritical
End Sub

この設計のポイント

1. `OneD` プロパティの活用: `OneD` が `True` のShapeはコネクタだ。処理対象を「図形(2D)」のみに絞ることで、計算コストを大幅に削減している。
2. `ItemFromID` による直接参照: オブジェクトのメモリポインタを追い回す必要はない。`ConnectedShapes` が返したIDを `Page.Shapes.ItemFromID` に渡すのが、最も高速でメモリ消費が少ないアクセス方法だ。
3. `visConnectedShapesOutgoing` の指定: ネットワークの「流れ」を明確に定義できる。双方向を含めたい場合は、フラグを適宜変更せよ。

—

現場で生き残るための「保守性」への配慮

ツールを開発する際、以下の3点に注意を払うだけで、君のコードの寿命は劇的に延びる。

1. データベース連携時のIDの扱い

Visioの `ID` はページ内での一時的なものだ。もしこのデータを外部DBで管理するなら、`Name` プロパティや、ユーザー定義セル(`User.UniqueID` 等)にGUIDを持たせ、それをキーとして紐付ける設計にすること。`ID` だけをキーにすると、図面を修正した瞬間に整合性が崩壊する。

2. 巨大図面へのスケーラビリティ

`Shapes` コレクションのループは重い。図面内に数千の図形がある場合、`Application.ScreenUpdating = False` を設定し、Visioの描画リフレッシュを止めることで、処理速度は数倍から数十倍に向上する。

3. エラーの「握りつぶし」禁止

`On Error Resume Next` を多用するエンジニアを私は認めない。接続が切れているコネクタや、グループ化で親子関係が複雑化したShapeを扱う際は、必ず `If vsoShape.Connects.Count > 0 Then` のように、存在チェックを挟むこと。

—

プロフェッショナルへの道

VisioのAPIをマスターするということは、「Visioが内部でどうやってグラフを維持しているか」というデータ構造そのものを理解することと同義だ。

`ConnectedShapes` を極めた先には、VBAによる自動レイアウト生成や、Excelの表データから自動で配線図を構築する「ジェネレーティブ・ダイアグラム」の世界が待っている。

さあ、コードを書いてくれ。君の自動化ツールが、誰かの退屈な手作業を根絶することを期待している。

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