Visio VBAを掌握する極限の知見:Page.DropConnectedによる配線自動化の極意
開発プロジェクトの現場で、Visioを使ったネットワーク構成図やフローチャートの自動生成を任されたことはないだろうか。
「図形を `Drop` メソッドで配置し、それぞれの座標を計算して、さらに `GlueTo` や `Connect` メソッドでコネクタを一本ずつ繋いでいく……」
もし、あなたが未だにそんな泥臭いコードを書いているとしたら、今すぐその手を止めてほしい。そのアプローチは、コード量が増大するだけでなく、図形のレイアウト変更や接続ズレのバグに一生振り回される「非効率の極み」だ。
Visioのオブジェクトモデルを深く理解した者であれば常識だが、Visio 2010以降、この地獄のような座標計算と配線作業を劇的に簡略化する神機能が備わっている。それが `Page.DropConnected` メソッドだ。
今回は、この `DropConnected` を完全に手懐け、実務で即戦力となる堅牢かつ美しい自動生成ロジックの構築手法を伝授する。
—
1. なぜ従来の「配置&接続」は破綻するのか?
まず、なぜ従来のコードが非効率なのかを整理しておこう。
通常、図形を配置してコネクタで結ぶ場合、以下のステップを踏む。
1. `ActivePage.Drop` でマスターシェイプを配置(X, Y座標の指定が必須)。
2. 配置した図形のピンチポイントや接続ポイント(Cell)をイミディエイトウィンドウやコードで特定。
3. コネクタをドロップし、その始点と終点をターゲット図形のグルー(糊付け)セルに強制接続。
これを数珠つなぎにやろうとすると、図形が1つ増えるたびに「前の図形の座標+幅+余白」を計算する複雑なロジックが必要になる。さらに、図形のサイズが変わった途端に配線がねじ曲がり、Visio特有の「謎の接続切れ」エラー(エラー番号が分かりにくい代表格だ)に悩まされることになる。
DropConnected 本来の思想
`Page.DropConnected` は、「既存の図形の特定のポート(方向)めがけて新しい図形を投げ込み、Visioのエンジンに自動でコネクタをルーティング・接続させる」機能である。
人間がVisioのUI上で、図形の矢印(オートコネクト)をドラッグして次の図形をポンと置く、あの直感的な操作をそのままコードに落とし込める。座標計算の呪縛から解放されるための唯一無二の武器なのだ。
—
2. DropConnected メソッドの仕様と罠
まずはメソッドのシグネチャを確認する。
Set targetShape = Page.DropConnected (ObjectNameToDrop, ObjectToConnectTo, ConnectDirection)
一見シンプルだが、プロダクションコードに組み込む上では、いくつかの「知見」と「罠」がある。
1. `ObjectNameToDrop` はマスター名ではなくUIGuidかオブジェクト指定が良い場合がある
ステンシルから正確に取得した `Master` オブジェクトを渡すのが最も確実。文字列指定はローカライズや同名マスターの混同でバグの温床になる。
2. `ConnectDirection` の方向定数
`VisConnected Dir` 列挙体を使用する(上・下・左・右)。
3. 戻り値は「新しくドロップされた図形」
ここが重要だ。返ってくるのはコネクタではなく、新しく配置された図形である。連続してチェーン(連鎖)を組む場合、この戻り値を次の起点に回すことで、流れるような連続生成が可能になる。
—
3. 【実務向け】データ駆動型・自動フローチャート生成エンジン
ここからは、実務の現場でそのまま使えるプロダクションコードを提示する。
外部のDBや配列からデータを読み込み、左から右へ、あるいは上から下へ、自動的にノードとコネクタを爆速で生成するパターンだ。
プロダクションコード例
Option Explicit
‘ =========================================================================
‘ 業務自動化プロフェッショナル向け:DropConnectedによる連鎖的図形生成
‘ =========================================================================
Public Sub GenerateProcessFlow()
Dim vsoPage As Visio.Page
Set vsoPage = ActivePage
‘ 画面描画を停止してパフォーマンスを極限まで高める(鉄則)
Visio.Application.ScreenUpdating = False
On Error GoTo ErrorHandler
‘ 1. マスターシェイプの事前取得(ドキュメントを開くコストをループ外に排除)
Dim masterProcess As Visio.Master
Set masterProcess = GetMasterFromStencil(“基本フローチャート図形”, “プロセス”)
If masterProcess Is Nothing Then
MsgBox “指定されたマスターが見つかりません。”, vbCritical
Exit Sub
End If
‘ 2. 生成するデータの定義(実務ではここでDBやExcelからRecordsetを取得する)
Dim processSteps(3) As String
processSteps(0) = “要件定義”
processSteps(1) = “基本設計”
processSteps(2) = “詳細設計”
processSteps(3) = “実装・テスト”
‘ 3. 起点となる最初の図形を配置(ここだけは絶対座標が必要)
Dim currentShape As Visio.Shape
Set currentShape = vsoPage.Drop(masterProcess, 2.0, 9.0) ‘ インチ単位
currentShape.Text = processSteps(0)
‘ プロパティやシェイプデータ(Prop)の初期化もここで行う
Call SetShapeMetadata(currentShape, “Step-001”)
‘ 4. 連鎖的生成ループ
Dim i As Integer
Dim nextShape As Visio.Shape
For i = 1 To UBound(processSteps)
‘ 【核心】DropConnectedの呼び出し
‘ currentShape の右側 (visModeledCode 等の方向指定) に新しい図形をドロップし、自動配線する
Set nextShape = vsoPage.DropConnected(masterProcess, currentShape, visSLConnectorRight)
‘ テキストの設定
nextShape.Text = processSteps(i)
‘ メタデータの付与
Call SetShapeMetadata(nextShape, “Step-00” & (i + 1))
‘ 次のループのためにポインタを更新
Set currentShape = nextShape
Next i
ErrorHandler:
‘ 5. 確実に画面描画を復元する
Visio.Application.ScreenUpdating = True
If Err.Number <> 0 Then
MsgBox “エラーが発生しました: ” & Err.Description, vbCritical
End If
End Sub
‘ — ヘルパー関数:ステンシルからマスターを安全に取得 —
Private Function GetMasterFromStencil(stencilName As String, masterName As String) As Visio.Master
Dim docs As Visio.Documents
Set docs = Visio.Application.Documents
Dim targetDoc As Visio.Document
Dim i As Long
‘ 開いているステンシルから検索
For i = 1 To docs.Count
If InStr(1, docs(i).Name, stencilName, vbTextCompare) > 0 Then
Set targetDoc = docs(i)
Exit For
End If
Next i
‘ もし開いていなければ開く(必要に応じてパスを指定)
If targetDoc Is Nothing Then
‘ 例: Set targetDoc = docs.OpenEx(Visio.Application.GetPath & “¥somename.vssx”, visOpenRO)
‘ 今回はすでに開いている前提、または組み込みマスターを想定
End If
If Not targetDoc Is Nothing Then
Set GetMasterFromStencil = targetDoc.Masters.ItemU(masterName)
End If
End Function
‘ — ヘルパー関数:シェイプデータ(カスタムプロパティ)の設定 —
Private Sub SetShapeMetadata(targetShape As Visio.Shape, id As String)
‘ Visioのシェイプデータ行を追加する安全なラッパー
On Error Resume Next
targetShape.AddNamedRow visSectionProp, “ProcessID”, visTagDefault
targetShape.CellsU(“Prop.ProcessID.Value”).FormulaU = “””” & id & “”””
On Error GoTo 0
End Sub
—
4. プロジェクトを成功させるためのアーキテクチャ上の注意点
このコードを実際のエンタープライズ環境(数十〜数百ノードの大規模図面生成)に投入する場合、以下の設計思想を必ず死守してほしい。
1. `ScreenUpdating = False` の徹底
Visio VBAは、図形が1つ生成されるたびに画面の再描画とレイアウトエンジンの再計算走査を行おうとする。これを放置すると、処理時間が幾何級数的に跳ね上がる。
上記のコード例の通り、処理の最初に画面描画を止め、エラーハンドラを含めて確実に最後に復元すること。これだけで体感速度が10倍以上変わる。
2. コネクタスタイルの制御
`DropConnected` を使うと、Visioのデフォルト設定(またはドキュメントのデフォルトマスター)に依存したコネクタが自動生成される。もし「直角コネクタ」に統一したい、あるいは特定のテーマカラーを適用したい場合は、`DropConnected` の戻り値である「図形」側から `.FromConnects` や接続を辿ってコネクタシェイプを特定し、一括でプロパティを変更する後処理を挟むと完璧だ。
‘ 例:生成後にコネクタのスタイルを調整する場合のイメージ
‘ Dim conn As Visio.Shape
‘ Set conn = nextShape.FromConnects(1).ToSheet
‘ conn.CellsU(“LineColor”).FormulaU = “RGB(0,120,215)”
3. トランザクション的な発想
データベース連携やExcelからの大量データインポートを行う場合、途中でエラーが起きると中途半端な図面が残る。本番環境では、`Visio.Application.UndoScopeBegin` と `UndoScopeEnd` を使って、処理全体を1つの「アンドゥスコープ」で囲むべきだ。エラー時に一括でロールバックできるように設計するのが、シニアエンジニアの務めである。
—
終わりに:ツールに作業をさせ、人間は価値ある設計に集中せよ
座標の計算に悩み、コネクタの接続エラーのデバッグに何時間も費やす時代は終わった。
`Page.DropConnected` を正しく理解し、データ駆動型の設計と組み合わせることで、数千行に及ぶスパゲッティコードを、わずか数十行の洗練されたエンジンへと昇華させることができる。
あなたの手元の業務自動化ツールを、今すぐアップデートしてほしい。背中を預けるに足る、強靭なコードベースがそこには築かれるはずだ。
