Visio VBAの深淵:グループ化された図形の罠と「再帰的走査」による完全制圧
Visioの自動化において、最も多くのエンジニアが「泥沼」にはまる瞬間。それは、複雑な階層構造を持つ図形(グループ)に対して、一括でプロパティ変更を試みた時だ。
「なぜか子要素の色が変わらない」「特定の階層だけ見逃される」――。
Visioのオブジェクトモデルを浅く理解している者は、ここで`Shapes`コレクションをループして途方に暮れる。だが、真のプロフェッショナルは知っている。Visioの図形構造は「木構造(Tree Structure)」であり、それを制するには再帰処理(Recursion)という武器が不可欠であることを。
本稿では、Visioのグループ化の罠を解き明かし、堅牢なプロダクションコードを実装するための極意を伝授する。
—
1. なぜ「単純なループ」では勝てないのか
Visioの`Shapes`コレクションは、あくまで「その階層にある直下の子要素」しか保持していない。
例えば、グループAの中にグループBがあり、その中にシェイプCがある場合、Aを走査してもCには辿り着けない。多くの初心者がここに`For Each`を二重・三重にネストしてコードを汚染させるが、これは保守性を破壊する最悪の設計だ。
Visioオブジェクトモデルの鉄則:
- `Shape.Type` が `visTypeGroup` である場合、その内部には `Shapes` コレクションが新たに存在する。
- この構造は無限にネスト可能である。したがって、プロシージャは自分自身を呼び出し、階層を掘り下げる「再帰」でなければならない。
—
2. 堅牢な再帰処理:プロダクションコード
以下のコードは、選択した図形(またはページ全体)から再帰的に潜り込み、特定の条件に合致するシェイプを確実に捕獲・操作するテンプレートだ。
‘ @description 再帰的にグループを走査し、全シェイプを操作するコアプロシージャ
‘ @param shp Target Shape (Group or Normal)
Public Sub ProcessShapesRecursive(ByVal shp As Visio.Shape)
Dim subShp As Visio.Shape
‘ 1. ここで現在のシェイプに対する処理を行う
‘ 例: 特定のカスタムプロパティを更新する、色を変える等
Call ApplyBusinessLogic(shp)
‘ 2. もし現在のシェイプがグループなら、内部を走査
If shp.Type = Visio.VisShapeTypes.visTypeGroup Then
For Each subShp In shp.Shapes
‘ 自己呼び出し(再帰)
Call ProcessShapesRecursive(subShp)
Next subShp
End If
End Sub
‘ 実際の業務ロジックを分離することで、保守性を飛躍的に高める
Private Sub ApplyBusinessLogic(ByVal shp As Visio.Shape)
‘ エラーハンドリングを忘れずに。保護されたシェイプやロックされた図形でのクラッシュを防ぐ
On Error Resume Next
‘ 例: 全てのシェイプの枠線を赤にする(業務要件に合わせて変更)
shp.Cells(“LineColor”).Formula = “RGB(255,0,0)”
On Error GoTo 0
End Sub
—
3. 実務で「死なない」ための3つの知見
① エラーハンドリングの境界線
Visioの図形には「ロック(Lock)」や「保護(Protection)」がかけられている場合がある。再帰処理中にこれらに触れると、コードは容赦なく停止する。`On Error Resume Next` を処理の最小単位に閉じ込め、スキップするロジックを必ず組み込むこと。
② パフォーマンスの重み
巨大なVisioドキュメントにおいて、全シェイプを走査するのは重い処理だ。
- 不必要な走査を避ける: 画面の更新を止める (`Application.ScreenUpdating = False`) は必須。
- イベントの無効化: `Application.EventsEnabled = False` を検討せよ。不要なイベント連鎖によるオーバーヘッドを排除できる。
③ 外部連携(DB/Excel)との接点
もしこの処理結果を外部のデータベースやExcelに書き出す場合、「処理済みの図形」を識別するID(UniqueID) を活用せよ。Visioのシェイプ名は変更可能で信頼できない。`shp.UniqueID(visGetOrMakeGUID)` を使用し、常に一意なキーで管理することが、データ整合性を保つ唯一の道だ。
—
結びに:エンジニアとしての矜持
「動けばいい」というコードは、半年後の自分を苦しめる負債となる。特にVisioのような複雑なオブジェクトを扱う際は、「再帰」という計算機科学の基本に立ち返ることが、最も近道であり、最も堅牢な解決策だ。
あなたが今書いているそのコードは、数千個のシェイプが動的に増減する環境でも耐えうるものか?
この「再帰的走査」のパターンを身体に叩き込み、Visio自動化の泥沼から脱却してほしい。あなたのコードが、より洗練されたものになることを期待している。
