【テクニカル・上級編】Shape.AddRowを用いたConnection Points(接続点)の動的追加とカスタムコネクタ分岐 – Visio VBA解析バイブル

スポンサーリンク

Visio VBAの深淵:Shape.AddRowによる動的接続点生成とメモリ管理の鉄則

Visioのオートメーションにおいて、最も「泥沼」にはまりやすいのが接続点(Connection Points)の動的操作だ。多くの初学者は、GUIで接続点を追加することに慣れているが、大規模な自動レイアウトシステムや、外部データベースから接続構成を動的に反映させるシステムにおいて、`AddRow`メソッドを理解することは避けて通れない。

今日は、単なるマニュアルの引き写しではない、実務で生き残るための「接続点自動生成」の極意を伝授する。

1. なぜ「AddRow」なのか:ShapeSheetの真実

Visioの図形は、その本質が「ShapeSheet」という強力なスプレッドシート型データ構造にある。接続点は`Section`(`visSectionConnectionPts`)として定義されており、ここをVBAで叩くことは、図形の筋肉を直接外科手術するに等しい。

`AddRow`は、単に行を増やすメソッドではない。「インデックスと既存のセル定義の整合性を維持しつつ、セクション内にメモリを再割り当てする」という重い処理だ。これをループ内で無計画に実行すれば、Visioの描画エンジンに過度な負荷をかけ、最悪の場合、メモリリークやオートメーションエラーを引き起こす。

2. 実装の要諦:動的接続点追加のコード例

以下のコードは、指定したShapeに対して、X/Y座標を指定して接続点を追加する堅牢な実装である。ポイントは、エラーハンドリングとオブジェクトの解放、そして`visSectionConnectionPts`の指定にある。

‘ @description: 指定したShapeに接続点を動的に追加する
‘ @param shp: 対象のShapeオブジェクト
‘ @param x: 接続点のX座標 (inch単位)
‘ @param y: 接続点のY座標 (inch単位)
Public Sub AddConnectionPoint(ByRef shp As Visio.Shape, ByVal x As Double, ByVal y As Double)
Dim rowIdx As Integer

‘ 1. セクションの存在確認と追加
If Not shp.SectionExists(Visio.VisSectionIndices.visSectionConnectionPts, Visio.VisExistsFlags.visExistsAnywhere) Then
shp.AddSection Visio.VisSectionIndices.visSectionConnectionPts
End If

‘ 2. 行の追加 (AddRowは追加された行番号を返す)
‘ visRowConnectionPts は接続点セクションの行定数
rowIdx = shp.AddRow(Visio.VisSectionIndices.visSectionConnectionPts, visRowLast, Visio.VisRowTags.visTagDefault)

‘ 3. 座標の書き込み (ShapeSheetへの直接書き込み)
‘ 誤った座標系を防ぐため、常にPinX/PinYと同期させる計算が必要になる場合がある
shp.CellsSRC(Visio.VisSectionIndices.visSectionConnectionPts, rowIdx, Visio.VisCellIndices.visCnnctX).FormulaU = x
shp.CellsSRC(Visio.VisSectionIndices.visSectionConnectionPts, rowIdx, Visio.VisCellIndices.visCnnctY).FormulaU = y

‘ 4. メモリと描画の最適化
‘ 大量に操作する場合は、Application.ScreenUpdating = False を検討せよ
End Sub

3. チーフアーキテクトからの警鐘:レガシー保守の知見

オブジェクトの明示的解放

VBAはガベージコレクションが甘い。特に`Visio.Application`や`Document`を跨ぐ処理では、`Set obj = Nothing`を徹底せよ。これを怠ると、バックグラウンドで`visio.exe`がゾンビプロセスとして残り、後続のバッチ処理で共有違反が発生する。

Windows APIとの連携(パフォーマンスの壁)

もし数千個の接続点を一括処理する必要があるなら、VBAの単一スレッド処理は限界を迎える。その場合、Windows API `SendMessage` を用いてVisioの再描画を一時的にフリーズさせるか、あるいはC#でCOMラッパーを書き、プロセス間通信を最適化するアーキテクチャへの移行を強く推奨する。

座標系の罠

`CellsSRC`で設定する座標は、図形内座標(Local)であることに注意せよ。グローバル座標(Page)で計算した値をそのまま放り込んでも、図形が回転・反転している場合、接続点は期待した位置には現れない。`Transform`行列を用いた座標変換を挟むのが、プロの仕事だ。

結論

接続点の動的生成は、Visioを「ただの作図ツール」から「動的な情報モデル」へと昇華させるための鍵だ。`AddRow`による外科手術をマスターすれば、複雑なネットワーク図やプロセスフローの自動結線など、自動化の領域は無限に広がる。

ただし、忘れるな。「自動化できること」と「自動化すべきこと」は違う。 構造が複雑になりすぎたShapeSheetは、手動編集を拒むブラックボックスと化す。保守性とのバランスを常に考慮し、コードの背後に「誰がこの図形を修正するのか」という問いを置いておくことこそが、エンジニアの美学である。

明日から、君のコードでVisioを震わせてほしい。

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