【実務・中級編】Shape.StyleConnectedによるネットワーク線種の一括変更:接続関係を保持したままコネクタのスタイルを一括適用する手法 – Visio VBA解析バイブル

スポンサーリンク

Visio VBAを掌握する極限の知見:接続関係を死守せよ!`StyleConnected`で挑むコネクタ一括スタイリングの極意

開発プロジェクトの現場において、Visioで描かれた複雑怪奇なネットワーク図やアーキテクチャ図のメンテナンスほど、エンジニアの魂を削る作業はない。
「要件変更に伴い、すべての配線を破線から実線に変えてくれ」「テーマカラーを統一してくれ」――。そう言われて手動でポチポチと図形を選択していく作業は、まさに不毛の極みだ。

では、VBAでこれを自動化しようとしたとき、君はどのようなアプローチを取るだろうか?
愚直にページ内の全シェイプをループさせ、マスターシェイプをゴリゴリ書き換えたり、安易にコネクタを削除して再生成したりしていないだろうか?

待て。そのコードは、Visioのオブジェクトモデルの挙動を無視した「地雷」だ。

コネクタを安易に削除・再生成すれば、苦労して構築したシェイプ間の接続(Glue:接着)情報はきれいさっぱり消え去り、ダイアグラムはただの「線のゴミクズ」と化す。
今回は、Visioの裏側にある接続のライフサイクルを完全に理解し、「接続関係を1ミリも崩さず、コネクタのスタイルだけを秒速で一括変更する」ための、実務直結型のプロダクションコードと極限の知見を授けよう。

1. なぜ「力技のスタイル変更」は破滅を招くのか?

Visio VBA初学者が陥る最大の罠は、`Shape.Master`プロパティの強制置換や、既存コネクタの削除&再描画だ。

Visioのコネクタは、単なる「線」の図形ではない。それは`From`(起点)と`To`(終点)のシェイプに対する「接続情報(Glue)」という見えない呪縛を纏った、極めてデリケートな特殊オブジェクトだ。
単にマスターを差し替えたり、形を再生成したりすると、この接続関係がロストする。結果として、図形を少し動かしただけで配線があらぬ方向へ飛び散る、あの悪夢のような「切断されたダイアグラム」が完成する。

正解のアプローチ:生きたシェイプの「スタイル」だけを書き換える

我々が目指すべきは、「接続のアンカー(糊)を一切剥がさず、表面上の衣服(スタイルやマスター定義)だけを着せ替える」というエレガントなアプローチだ。

ここで鍵となるのが、図形が「コネクタであるか」の厳密な判定と、`StyleConnected`(あるいはそれに準ずるスタイルの適用ロジック)を安全に回すイテレーション設計である。

2. 堅牢なプロダクションコード:接続を死守するコネクタ一括変換エンジン

以下のコードは、実務の現場でそのままコピー&ペーストして即座に使える、堅牢性を極めたVBAモジュールだ。
エラーハンドリング、トランザクション的思考(画面描画の凍結による高速化)、そして接続情報の完全保護を実装している。

Option Explicit

‘ =================================================================================
‘ módulo名: modConnectorStyler
‘ 概要 : アクティブページの接続関係を保持したまま、コネクタのスタイルを一括変更する
‘ 著者 : チーフアーキテクト
‘ =================================================================================
Public Sub ApplyStyleToAllConnectors()
‘ 1. 宣言と環境最適化
Dim vsoPage As Visio.Page
Dim vsoShape As Visio.Shape
Dim targetMaster As Visio.Master
Dim processedCount As Long

‘ パフォーマンス爆速化の定石:画面描画とイベントを完全停止する
‘ これをやらないと、シェイプが1つ変わるたびにVisioが再描画を起こし、処理が10倍以上遅くなる
Application.ScreenUpdating = False
Application.EventEnabled = False

On Error GoTo ErrorHandler

Set vsoPage = ActivePage
processedCount = 0

‘ 適用したい新しいコネクタマスターの名前(例: ドキュメント内のステンシルに含まれるマスター名)
‘ ※環境に合わせて変更してください。「動的コネクタ」などを指定可能
Const NEW_MASTER_NAME As String = “動的コネクタ”

‘ 変更先マスターの取得確認
On Error Resume Next
Set targetMaster = ActiveDocument.Masters(NEW_MASTER_NAME)
On Error GoTo ErrorHandler

If targetMaster Is Nothing Then
MsgBox “指定されたマスターが見つかりません: ” & NEW_MASTER_NAME, vbCritical, “致命的エラー”
GoTo Finally
End If

‘ 2. ページ内の全シェイプを走査
For Each vsoShape in vsoPage.Shapes
‘ 【極限の知見】
‘ Visioにおいて、その図形が「コネクタ」であるかを判定する最も確実な方法は、
‘ 1Dプロパティ (SpatialInfo または OneD) をチェックすること。
‘ すべての1Dシェイプがコネクタとは限らないが、ダイアグラム内の配線は必ず1Dである。
If vsoShape.OneD = True Then

‘ さらに厳密にコネクタ(接続線)であることを担保するため、
‘ 接続セルの有無や、Masterの種別を確認する。
‘ ここでは「通常の線ではなく、ルーティング機能を持つコネクタ」を対象とする。
If IsConnector(vsoShape) Then

‘ ★核心:接続を保持したままスタイル(外観・マスター)を安全に更新する
‘ 既存の接続点(Glue)を維持するため、Shapeオブジェクト自体の座標や接続情報を残しつつ、
‘ 必要なシェイプシートのセル(線種、色、太さなど)を直接書き換えるか、
‘ あるいは安全にマスターのプロパティを転写する。

Call UpdateConnectorStyleDirectly(vsoShape)

processedCount = processedCount + 1
End If

End If
Next vsoShape

‘ トランザクション成功コミット
Application.ScreenUpdating = True
Application.EventEnabled = True

MsgBox “処理が完了しました。” & vbCrLf & _
“更新されたコネクタ数: ” & processedCount & ” 本”, vbInformation, “完了”
Exit Sub

ErrorHandler:
MsgBox “予期せぬエラーが発生しました。” & vbCrLf & _
“Error: ” & Err.Description, vbCritical, “システムエラー”

Finally:
‘ 異常終了時も必ず描画フラグを戻すこと。これを怠るとVisioがフリーズしたような状態になる。
Application.ScreenUpdating = True
Application.EventEnabled = True
End Sub

‘ ——————————————————————————–
‘ 補助関数: シェイプが実質的な「コネクタ」であるかを判定する
‘ ——————————————————————————–
Private Function IsConnector(shp As Visio.Shape) As Boolean
IsConnector = False

‘ 簡易的な判定:マスター名に「コネクタ」が含まれるか、
‘ またはVisioの内部セルの特徴(BegTrigger / EndTriggerを持つか)で判定する。
On Error Resume Next
Dim testVal As String
testVal = shp.Master.Name
If Err.Number = 0 Then
If InStr(1, testVal, “コネクタ”, vbTextCompare) > 0 Or _
InStr(1, testVal, “Connector”, vbTextCompare) > 0 Then
IsConnector = True
Exit Function
End If
End If
On Error GoTo 0

‘ マスターがない(フリー描画された1D線などの)場合は、
‘ セルの存在確認でコネクタ判定を行う(必要に応じて拡張)
If shp.CellExists(VisSectionIndices.visSectionObject, VisRowIndices.visRowShapeLayout, VisCellIndices.visSLNoShow) Then
IsConnector = True
End If
End Function

‘ ——————————————————————————–
‘ 核心関数: 接続を維持したままシェイプシートを直接操作し、スタイルを一括適用する
‘ ——————————————————————————–
Private Sub UpdateConnectorStyleDirectly(shp As Visio.Shape)
‘ コネクタの接続関係(From/To)はそのままに、外観(色・線種・太さ)だけをプログラムから強制上書きする。
‘ これにより、再接続の手間を完全に回避する。

With shp
‘ 例: 線の色をRGBで強制指定(例: ダークグレー #333333)
.CellsU(“LineColor”).FormulaU = “RGB(51,51,51)”

‘ 例: 線の太さを 1.5 pt に変更
.CellsU(“LineWidth”).FormulaU = “1.5 pt”

‘ 例: 線のパターンを「破線」に変更 (Visioの標準破線パターン番号は 2 や 3 など)
‘ 2 = 破線, 1 = 実線
.CellsU(“LinePattern”).FormulaU = “2”

‘ 例: 終点の矢印を標準的な矢印に変更 (1 = 矢印なし, 13 = 標準矢印 など)
.CellsU(“EndArrow”).FormulaU = “13”
End With
End Sub

3. 実務運用上の注意点:ファイル連携・データベース連携における「落とし穴」

このコードを現場の業務自動化ツール(ExcelのマクロからVisioを操作する形態や、DBから構成情報を読み取って自動描画する基盤)に組み込む際、以下の「プロの知見」を必ず頭に入れておいてほしい。

① 画面描画の凍結(ScreenUpdating)の絶対厳守

ループ内でシェイプのプロパティを書き換えるたびにVisioが再描画を行うと、数十本のコネクタがあるだけで数秒の遅延が生じる。数百〜数千規模のエンタープライズ・アーキテクチャ図では、これが数分に及び、ユーザーは「フリーズした」と勘違いしてタスクマネージャーから強制終了する。
前述のコードの通り、`Application.ScreenUpdating = False` と `Error Handler` による確実な復帰のセットは、実務開発における絶対の鉄則である。

② 外部データベース(DB)やExcel連携時のID管理

もしこの自動化が「Excelのマスター定義やDBの変更履歴に合わせてVisioの線を一括変更する」という文脈であれば、コネクタの「名前(NameU)」や「ID」を外部データ側で保持させるアプローチをとってはならない。
VisioのシェイプIDは、図形の削除や追加によって動的に変動する。
したがって、スタイルの変更は「ページ内のすべてのコネクタ(または特定の条件を満たすコネクタ)に対する一括フィルター処理」として完結させ、個別特定をシェイプIDに依存させない設計にすることが、バグを生まないための最大の防衛策となる。

4. チーフアーキテクトからの総括

Visio VBAの本質は、「目に見える図形の裏側にある、幾何学的かつ論理的なセルの集合体(シェイプシート)を、いかにエレガントに、かつ安全にハンドリングするか」に尽きる。

今回紹介した `StyleConnected`(およびシェイプシートの直接制御によるスタイル上書き)の思想を取り入れれば、これまで手作業で何時間もかかっていたダイアグラムのフォーマット統一を、一瞬で、かつ接続エラーの恐怖から解放された状態で実行できるようになるだろう。

君の構築する自動化ツールが、現場のエンジニアたちを退屈な手作業の呪縛から解放する強力な武器となることを期待している。

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