【実務・中級編】グループ化された図形の罠:GroupShapesコレクションを再帰的に走査して子シェイプを操作する – Visio VBA解析バイブル

スポンサーリンク

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自動化の泥沼から脱却してほしい。あなたのコードが、より洗練されたものになることを期待している。

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