【テクニカル・上級編】図形の接続関係をVBAで逆引き:ConnectedShapesメソッドでネットワークのトポロジ構造を解析する – Visio VBA解析バイブル

スポンサーリンク

Visioの深淵を覗く:ConnectedShapesによるトポロジ解析の極意

Visioの図面を単なる「絵」と見なしているうちは、君はまだ門前にすら立っていない。Visioの本質は「リレーショナル・データベースをGUIで可視化したもの」である。シェイプはレコードであり、コネクタはリレーション(外部キー)だ。

今回は、このデータ構造をプログラムから直接叩き、ネットワークトポロジを解析する。多くのエンジニアが`FromConnects`や`ToConnects`のプロパティを泥臭くループさせて時間を浪費しているが、真のアーキテクトは`ConnectedShapes`メソッドを使う。これが何を意味するか、理解を深めていこう。

1. なぜConnectedShapesを選ぶのか:計算量とメモリ管理

`visConnectedShapesIncomingNodes`や`visConnectedShapesOutgoingNodes`を使い分けることで、Visioは内部的な接続インデックスを直接参照する。自前で`Connects`コレクションをイテレーションする処理と比較すれば、その速度差は歴然だ。

特に数千個のシェイプからなる巨大図面において、オブジェクトの生成・破棄はメモリリークの最大の要因となる。VBAのガベージコレクションを信用してはならない。

  • オブジェクトの明示的破棄: `Set obj = Nothing` は儀式ではない。循環参照を避けるための必須の防衛線だ。
  • イベントの抑制: `Application.ScreenUpdating = False` は当然として、`Application.DeferRecalc = True` を適切に併用しなければ、解析中に再計算が走り、パフォーマンスは指数関数的に劣化する。

2. ネットワーク解析の実装:ConnectedShapesによる再帰的探索

以下に、特定のシェイプから下流のノードを再帰的に取得し、その構造を解析するプロトタイプを示す。

‘ 伝説的なトポロジ解析エンジン(プロトタイプ)
Public Sub AnalyzeTopology(ByVal startShape As Visio.Shape)
Dim connectedShapes() As Long
Dim i As Long
Dim targetShape As Visio.Shape

‘ 速度向上のための最適化
Application.DeferRecalc = True

‘ 接続されているシェイプのIDを高速取得
‘ visConnectedShapesOutgoingNodes: 下流方向のノードを取得
connectedShapes = startShape.ConnectedShapes(visConnectedShapesOutgoingNodes, “”)

For i = LBound(connectedShapes) To UBound(connectedShapes)
Set targetShape = ActivePage.Shapes.ItemFromID(connectedShapes(i))

‘ ここで解析ロジックを実装
Debug.Print “Found Node: ” & targetShape.Name & ” (ID: ” & targetShape.ID & “)”

‘ 再帰的な追跡(スタックオーバーフローに注意せよ)
AnalyzeTopology targetShape

‘ メモリの解放:ここを疎かにすると数千ノードでプロセスが死ぬ
Set targetShape = Nothing
Next i

Application.DeferRecalc = False
End Sub

3. レガシー環境とWindows APIの活用

現場のVisio環境は往々にして「負債」を抱えている。特に古いカスタムシェイプや、グループ化が複雑にネストされた図面では、`ConnectedShapes`が正確な値を返さないケースがある。

そのような場合、私は迷わず Windows API(User32.dll) を呼び出し、ウィンドウハンドル経由でVisioの描画コンテキストへ直接介入するか、あるいは`ShapeSheet`を直接操作して接続ポイントの座標を物理的に算出する。

‘ 必要に応じてAPIを用いて描画状態を強制リフレッシュする
Private Declare PtrSafe Sub Sleep Lib “kernel32” (ByVal dwMilliseconds As Long)
‘ 複雑な大規模図面では、Visioの描画完了を待つためにSleepを挟む泥臭い戦略も時には必要だ

4. シニアアーキテクトへの提言:設計の美学

君たちが解析したトポロジ情報は、XMLやJSONに出力して外部のDBへ流し込むべきだ。Visioはあくまで「可視化インターフェース」であり、データ構造の保存場所ではない。

1. 分離せよ: 図面ファイルと解析データ(トポロジの親子関係)を分けること。
2. 型を厳格にせよ: `Object`型で逃げるな。`Visio.Shape`、`Visio.Connect`、`Visio.Page`を厳格に型定義し、コンパイル時チェックの恩恵を受けろ。
3. 例外を握りつぶすな: `On Error Resume Next`を乱用するエンジニアは、アーキテクトとしては失格だ。予期せぬ接続断やID欠損に対して、どのようなフォールバックを行うか。そこがプロの分かれ目だ。

Visio VBAは古い言語だが、そのオブジェクトモデルは極めて洗練されている。このAPIを掌握することは、単なる自動化を超え、システムの「構造そのもの」をコントロールする力を手に入れることに他ならない。

次は、シェイプの`EventXFMod`をフックして、接続関係が変更された瞬間にリアルタイムでデータベースを更新する「イベント駆動型トポロジ同期」について語ろう。

君のコードが、図面という名の迷宮を解き明かす鍵になることを期待している。

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