Visioの迷宮を解読する:ConnectedShapesによるトポロジ抽出の極意
多くのエンジニアがVisioのVBAに挫折する理由は、オブジェクトモデルの「非対称性」にある。画面上では繋がっているように見えるコネクタも、内部データ構造においては、Shapeオブジェクトが単なる「図形の集合体」としてメモリ上に散乱しているに過ぎない。
今日語るのは、Visioの描画エンジンを逆手に取り、複雑なフローチャートやネットワーク図から「接続リスト」を抽出し、Excelへ再構築するアーキテクチャ設計だ。これは単なるマクロではない。Visioのデータ層を裸にする、リバースエンジニアリングの技術である。
—
1. なぜ「ConnectedShapes」なのか?
かつて、我々は`Connects`コレクションをイテレートし、`FromSheet`と`ToSheet`を泥臭く追いかけていた。だが、それはメモリリークとパフォーマンス低下の温床だった。
`ConnectedShapes`メソッドは、Visio 2010で導入された至高のインターフェースだ。これは内部的にインデックス化された接続マップを叩くため、大規模な図面であっても再帰呼び出しを最小限に抑えられる。
接続方向のパラメーター設計
- `visConnectedShapesIncoming`: 自分に向かってくる矢印の始点を引く。
- `visConnectedShapesOutgoing`: 自分が指し示す先の終点を引く。
- `visConnectedShapesAllNodes`: 方向を問わず接続されている全ノードを引く。
—
2. 実行時パフォーマンスを極限まで高めるコード実装
単なるコードの羅列はしない。ここでは、数百の図形を持つドキュメントでもフリーズしないよう、オブジェクトのスコープとメモリ管理を徹底した実装を示す。
‘ 【重要】大規模図面ではDoEventsを適切に挟まないとVisioの描画スレッドがスタックする
‘ また、Shapeオブジェクトをループ内で何度も参照するとCOMのオーバーヘッドが重なるため
‘ IDによる管理を推奨する。
Sub ExportTopologyToExcel()
Dim vsoPage As Visio.Page
Dim vsoShape As Visio.Shape
Dim connectedShapes() As Long
Dim i As Long
‘ オブジェクトの明示的解放を見据えた宣言
Set vsoPage = ActivePage
‘ 出力先のExcel準備(簡易的なコード)
Dim wb As Object: Set wb = CreateObject(“Excel.Application”)
wb.Visible = True
Dim ws As Object: Set ws = wb.Workbooks.Add.Sheets(1)
Dim rowIdx As Long: rowIdx = 1
For Each vsoShape In vsoPage.Shapes
‘ コネクタ自体はスキップ(コネクタの接続先ではなく、ノード同士を抽出する)
If vsoShape.OneD = 0 Then
‘ Outgoing(指し先)を取得
connectedShapes = vsoShape.ConnectedShapes(visConnectedShapesOutgoing, “”)
If UBound(connectedShapes) >= 0 Then
For i = LBound(connectedShapes) To UBound(connectedShapes)
ws.Cells(rowIdx, 1).Value = vsoShape.Name
ws.Cells(rowIdx, 2).Value = vsoPage.Shapes.ItemFromID(connectedShapes(i)).Name
rowIdx = rowIdx + 1
Next i
End If
End If
Next vsoShape
‘ メモリ最適化:参照の解放
Set vsoShape = Nothing
Set vsoPage = Nothing
‘ Excelへの参照も適切に破棄すること
End Sub
—
3. シニアエンジニアが意識すべき「隠れた罠」
1. `ItemFromID` のコスト
`Shapes.ItemFromID` は便利だが、内部的にはIDからShapeオブジェクトを解決するハッシュテーブルを叩いている。数万の処理を行う際は、事前にShape情報を配列(またはDictionary)にキャッシュしてから処理を回すのが、プロの設計だ。
2. コネクタの「浮き」現象
Visioの図面において、コネクタがノードに「スナップ」しているように見えて、実は「接着」していないケースが頻発する。`ConnectedShapes`は「接着」されていない接続は無視する。もし接続リストが欠落する場合、それはVBAのバグではなく、図面データの整合性欠如である。この場合、`vsoShape.GlueTo`の再適用を促す検証ロジックを前段に噛ませるのが、堅牢なシステム構築への近道だ。
3. メモリ解放の徹底
VBAはガベージコレクタが甘い。特にCOMオブジェクトの参照はスコープを抜けても即座に解放されないことがある。大規模なループ内では、`Set vsoShape = Nothing` を明示的に呼び出し、オブジェクトのライフサイクルを制御せよ。
—
4. 最後に:レガシーとの対峙
Visioというソフトウェアは、四半世紀以上の歴史を持つ巨大なブラックボックスだ。しかし、その内部構造(ShapeSheet)は今なお極めて論理的である。
今回紹介した`ConnectedShapes`による解析は、単にExcelへリストを出すだけではない。あなたの組織にある「ブラックボックス化したフロー図」の正体を暴き、ドキュメントの信頼性を再定義するための武器となるはずだ。
技術とは、魔法ではない。詳細な仕様の積み重ねと、泥臭いメモリ管理の先にある「最適解」のことである。健闘を祈る。
