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

スポンサーリンク

Visio VBAの深淵:再帰的探索で「グループの罠」を完全制圧する

Visioの自動化において、多くのエンジニアが最初の壁として突き当たるのが「グループ化された図形の操作」だ。表面上は単一のオブジェクトに見えても、その内側には多重の階層構造が潜んでいる。

`ActivePage.Shapes`をループさせるだけで満足しているようでは、実務レベルの複雑な図面を制御することはできない。今回は、グループ構造を再帰的に走査し、階層の深さを問わず子シェイプを安全に操作するための「プロフェッショナルな設計術」を伝授する。

1. なぜ「単純なループ」では破綻するのか

Visioのオブジェクトモデルにおいて、`Shapes`コレクションは「その階層直下のオブジェクト」しか保持しない。もしグループの中に別のグループがある場合、単純なループでは子グループが「一つの塊」として認識され、そのさらに奥にあるシェイプには手が届かない。

ここで陥りがちなのが、場当たり的な`If TypeOf … Is Group`判定を繰り返すコードだ。これはメンテナンス性を著しく低下させ、コードをスパゲッティ化させる元凶となる。

真の解決策は「再帰呼び出し(Recursive Call)」にある。 階層の深さを意識せず、関数自身が自分を呼び出すことで、ツリー構造を深部まで掘り下げるアプローチこそが、堅牢な自動化の鍵だ。

2. 堅牢な再帰走査アルゴリズム(プロダクションコード)

以下のコードは、指定したシェイプ(またはページ全体)を起点として、すべての階層の子シェイプを走査し、特定の条件に合致するシェイプのみを操作する汎用的な設計である。

‘ ==========================================================
‘ 関数名: ProcessShapesRecursive
‘ 概要: シェイプを再帰的に走査し、子シェイプを操作する
‘ ==========================================================
Public Sub ProcessShapesRecursive(ByVal shpParent As Visio.Shape)
Dim shp As Visio.Shape

‘ 親がグループであるか確認
If shpParent.Type = Visio.VisShapeTypes.visTypeGroup Then
‘ グループ内の全シェイプをループ
For Each shp In shpParent.Shapes
‘ ここで「操作対象の判定」を行う
‘ 例: 名前が “Target” で始まるシェイプのみ操作
If shp.Name Like “Target” Then
Call ModifyShape(shp)
End If

‘ 再帰呼び出し: もしshpがさらにグループなら内部へ潜る
If shp.Type = Visio.VisShapeTypes.visTypeGroup Then
ProcessShapesRecursive shp
End If
Next shp
End If
End Sub

‘ 操作を分離することで保守性を担保する
Private Sub ModifyShape(ByVal shp As Visio.Shape)
‘ データベースや外部データとの連携を行う際は、
‘ ここでエラーハンドリングを徹底すること
On Error Resume Next
shp.Cells(“FillForegnd”).Formula = “RGB(255,0,0)”
On Error GoTo 0
End Sub

3. 実務で「バグらせない」ための3つの鉄則

現場でコードを動かす際、以下の視点がないと必ず手戻りが発生する。

① グループ解除に依存しない

「一度グループを解除して処理し、再グループ化する」という手法は最悪のアンチパターンだ。グループ解除はシェイプのIDや接続関係を破壊し、座標の相対関係を崩すリスクがある。あくまで「階層を維持したままアクセスする」のがプロの作法である。

② エラーハンドリングは「操作単位」で

Visioはファイルの状態や保護設定によって、特定のシェイプのプロパティ書き換えが拒否されることがある。ループ全体を止めるのではなく、`ModifyShape`関数の内部で`On Error Resume Next`を使用し、特定のシェイプのスキップを許容する設計にせよ。

③ 外部データ連携時の注意点

ExcelやDBから取得したデータをシェイプに反映させる際は、`Shape.Name`ではなく、一意なIDである`Shape.UniqueID`または`Shape.ID`をキーとして管理すること。名前(Name)はユーザーがUI上で自由に変更できるため、ビジネスロジックの参照キーとしては脆弱すぎる。

4. 最後に:アーキテクトからの助言

Visio VBAは、オブジェクトのライフサイクルを正しく理解すれば、極めて強力な自動化エンジンとなる。今回紹介した再帰処理は、単にシェイプの色を変えるためだけのものではない。

  • 図面内の全部品リストの抽出
  • 動的なパラメータのドキュメント間同期
  • 複雑なネットワーク構成図の自動バリデーション

これら全てに応用できる「基盤」だ。まずはこの再帰アルゴリズムを自分のツールに組み込み、階層構造に怯える必要のない、真に自由な自動化の世界へ足を踏み入れてほしい。

コードは美しく、そして深く。それが我々エンジニアの矜持だ。

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