Visio自動化の真髄:Selectionオブジェクトを制する者が業務を制す
Visioの自動化において、初心者が陥る最大の罠は「ループで全図形を走査しようとすること」です。`ActivePage.Shapes`をインデックスで回し、条件分岐で判定する……そんなコードは、図形が増えた瞬間に破綻する「レガシーの墓場」となります。
プロフェッショナルなエンジニアは、「ユーザーの意思(選択状態)」を起点にしたイベント駆動型の設計を好みます。ユーザーがマウスで選んだ図形群、すなわち`Selection`オブジェクトこそが、最も効率的かつ直感的な操作のフックとなるからです。
今日は、現場で使い捨てられない、堅牢で拡張性の高い「選択図形一括処理」の作法を伝授します。
—
1. なぜ「Selection」にこだわるのか
理由は単純です。パフォーマンスとUX(ユーザー体験)のトレードオフを最小化できるからです。
- 処理コストの最適化: ページ内の数千個の図形をループで判定するオーバーヘッドは無視できません。`ActiveWindow.Selection`は、ユーザーが既に特定した対象のみを対象にするため、計算量は常にO(n)であり、極めて高速です。
- 安全性の担保: 意図しない図形(枠線やレイヤーロックされた図形)への誤操作を、ユーザーの「選択」というフィルタリングを通すことで物理的に防げます。
—
2. プロダクションコード:保守性を担保した一括処理のテンプレート
以下のコードは、選択中の図形に対して「カスタムプロパティ(Shape Data)の一括更新」と「スタイル適用」を行う際のベストプラクティスです。
Option Explicit
‘ ———————————————————
‘ 選択された図形に対して一括で処理を行うメインプロシージャ
‘ ———————————————————
Public Sub ProcessSelectedShapes()
Dim sel As Visio.Selection
Dim shp As Visio.Shape
‘ 1. Selectionオブジェクトの取得
Set sel = Visio.ActiveWindow.Selection
‘ 2. 選択状態のバリデーション(堅牢なコードの第一歩)
If sel.Count = 0 Then
MsgBox “処理対象の図形が選択されていません。”, vbExclamation
Exit Sub
End If
‘ 3. エラーハンドリングを組み込み、処理を安全に実行
On Error GoTo ErrorHandler
‘ 画面更新を停止してパフォーマンスを最大化
Application.ScreenUpdating = False
For Each shp In sel
‘ 図形の種類や状態に応じたフィルタリング
If Not shp.OneD Then ‘ 1D図形を除外したい場合など
Call ApplyBusinessLogic(shp)
End If
Next shp
CleanExit:
Application.ScreenUpdating = True
Exit Sub
ErrorHandler:
MsgBox “エラー発生: ” & Err.Description, vbCritical
Resume CleanExit
End Sub
‘ ———————————————————
‘ 個別のロジックを切り離す(保守性の鍵)
‘ ———————————————————
Private Sub ApplyBusinessLogic(ByRef shp As Visio.Shape)
‘ Shape Data(カスタムプロパティ)への書き込み例
If shp.CellExists(“Prop.Status”, visExistsAnywhere) Then
shp.Cells(“Prop.Status”).Formula = “””Completed”””
End If
‘ スタイルの強制適用
shp.LineStyle = “Standard”
shp.FillStyle = “Standard”
End Sub
—
3. 現場で生き残るためのアーキテクチャ設計論
処理を「ロジック」と「イテレータ」に分離せよ
上記のコードで最も重要なのは、`ApplyBusinessLogic`というプロシージャを分離している点です。多くのエンジニアは、`For Each`の中に複雑な条件分岐を詰め込みます。しかし、将来的に「データ連携(DB更新)」や「ログ出力」を追加したくなった際、ロジックが分離されていれば、メインループを汚すことなく機能を拡張できます。
外部連携(DB/Excel)の鉄則
もしこのマクロからデータベースやExcelへデータを書き出す場合、「図形ID (`shp.ID`)」をキーにすることを強く推奨します。
- 図形の名前(`shp.Name`)はユーザー操作で重複したり変更されたりするため、DBの主キーとしては脆弱です。
- `shp.UniqueID`(GUID)を使用すれば、図形を別ページに移動させても追跡可能な高度なトレーサビリティが確保できます。
ユーザーへのフィードバック
数秒以上かかる処理を行う場合、`Application.StatusBar` を活用してください。
Application.StatusBar = “処理中: ” & i & “/” & sel.Count & ” 個の図形を更新中…”
これがないツールは、ユーザーにとって「フリーズしたのか、動いているのか分からない不安なブラックボックス」です。プロフェッショナルは、常にプロセスの可視化を怠りません。
—
最後に:ツールは「道具」であって「目的」ではない
Visio VBAを書いていると、つい「いかに高度なコードを書くか」に熱中しがちです。しかし、真の目的は業務効率化です。
- 複雑なコードを書くな: 誰か(あるいは半年後の自分)が読んで3分で理解できるコードこそが最高です。
- 選択(Selection)を信頼せよ: ユーザーの操作意図を尊重する設計は、バグの温床となる「全探索」を排除します。
この設計パターンをマスターすれば、貴方は単なる「マクロ作成者」から、組織のVisio運用を最適化する「アーキテクト」へと進化できるはずです。さあ、次はあなたの現場で、その「選択」を価値に変えてください。
