Visio VBAの深淵:グループ化された「迷宮」を再帰処理で攻略する
こんにちは。自動化の現場でVisioと格闘し続けてきた諸君、ようこそ。
Visio VBAを触り始めると、誰もが一度は「グループ化」という壁にぶつかります。マクロの記録で操作した図形はうまくいくのに、いざ複雑な構成の図面を操作しようとすると、「なぜか中の図形が反応しない」「エラーで止まる」……そんな経験はありませんか?
今日は、Visioのオブジェクトモデルの中でも特に「沼」にハマりやすい`GroupShapes`コレクションと再帰処理について、その本質を解き明かします。
—
1. なぜ「グループ」は厄介なのか?
Visioにおいて、グループ化された図形は単なる集合体ではありません。Visioのオブジェクトモデルにおいて、`Shape`オブジェクトは「自分の配下に別の`Shape`を持ち得る」という再帰的な構造をしています。
- `Shapes`コレクション: その階層(ページ全体やグループ内)にある直下の子要素。
- `GroupShapes`コレクション: `Shapes`のうち、グループであるものだけが持つ「中身」への入り口。
初学者が陥る罠は、「グループの中のグループ」という多重構造を考慮せず、表面的な階層しか見ていないことです。マトリョーシカを外から眺めて満足している状態、と言えば伝わるでしょうか。
—
2. 迷宮を突破する「再帰処理」の考え方
あるグループの中に別のグループがあるかもしれない。そんな時、個別にコードを書いていてはキリがありません。ここで登場するのが「再帰関数(Recursive Function)」です。
再帰処理とは、「自分自身を呼び出す関数」のこと。
1. 今見ている図形がグループか?
2. もしグループなら、その中の子要素に対して「もう一度この関数を実行する」。
3. グループでなければ、目的の処理(色を変える、テキストを置換するなど)を実行する。
このロジックを組めば、どれほど深い階層の図形であっても、漏らさず確実に操作できます。
—
3. 実装コード:グループの深淵を走査する
以下に、ページ上のすべての図形を走査し、グループの中まで潜り込んで特定の処理を行う汎用的なテンプレートを提示します。
‘ メイン処理:ページ内の全図形を走査する起点
Sub ProcessAllShapesInPage()
Dim shp As Visio.Shape
‘ ページ上のすべてのトップレベル図形を順にチェック
For Each shp In ActivePage.Shapes
Call TraverseShapes(shp)
Next shp
MsgBox “全図形の走査と処理が完了しました。”
End Sub
‘ 再帰処理を行う関数
Sub TraverseShapes(ByRef shp As Visio.Shape)
‘ 1. この図形がグループかどうかを判定
If shp.Type = Visio.visTypeGroup Then
‘ グループの場合は、その中身(GroupShapes)に対して自分自身を再帰呼び出し
Dim subShp As Visio.Shape
For Each subShp In shp.Shapes
Call TraverseShapes(subShp)
Next subShp
Else
‘ 2. グループでない(個別の図形)場合の処理
‘ ここにやりたい処理を記述(例:テキストを大文字にする)
If shp.OneD = False Then ‘ 1D図形を除外するなどの制御もここで行う
Debug.Print “処理対象: ” & shp.Name
‘ shp.Cells(“FillForegnd”).ResultIU = 6 ‘ 例:色を赤に変える
End If
End If
End Sub
コードのポイント解説
- `shp.Type`: 図形がグループかどうかを判定する重要なプロパティです。`visTypeGroup`をチェックすることで、分岐を制御します。
- `Call TraverseShapes(subShp)`: これが魔法の行です。自分自身を呼び出すことで、階層がいくつあっても自動的に潜っていきます。
- `ByRef`: オブジェクトを直接操作するため、参照渡し(ByRef)で渡すのが効率的です。
—
4. 開発現場で生き残るための「心構え」
最後に、一つだけ現場の知見を授けましょう。
Visioのオブジェクトを扱う際、「処理対象の図形が本当に操作可能か」を常に疑ってください。例えば、`Lock`(保護)されている図形や、マスターシェイプ、あるいは非表示のレイヤーにある図形などは、エラーの原因になります。
コードを書く際は、以下の防御的プログラミングを意識すると格段に安定感が増します。
1. エラーハンドリング: `On Error Resume Next` を特定のブロックで使い、操作できない図形をスキップさせる。
2. 型確認: `If shp.OneD`(1D図形か)や `shp.Cells(“LockDelete”).ResultIU`(保護されているか)を事前にチェックする。
—
まとめ:この壁を越えれば、あなたはもう初心者ではない
グループの再帰処理をマスターするということは、Visioの「構造」を支配下に置くということです。これができれば、何千もの部品が組み合わさった複雑な図面であっても、一瞬ですべてのテキストを置換したり、色を一括変更したりすることが可能になります。
Visio VBAは、マクロの記録から一歩踏み出した先にこそ、真の自由が待っています。ぜひ、このコードをあなたの武器に加えてください。
何か詰まったら、いつでも戻ってきてください。コードは裏切りませんよ。それでは、良い自動化ライフを!
