グループ階層を取得 - PowerPoint VBA
結論:できないっぽい?調査中
やりたいこと
- PowerPoint 2007
- ネストされたグループに対し、再帰的にその中のグループを取得したい
Group(1) |- Text(2) |- Graph(3) `- Group(4) |- Picture(5) `- Group(6) |- Text(7) `- Text(8)
こんなんがあったとして、親のGroup(1)の子には(2)(3)(4)があり、(4)の下には(5)(6)があり…というのを階層的に辿りたい。
GroupShapesは使えない
グループ内の要素を取得する方法を検索すると、Shape.GroupItemsを使い、GroupShapesオブジェクトを取得する例がよく出てくる。
しかし、GroupItemsは、ツリー構造の“葉”の部分のみを単一階層で取得し、(4)や(6)のGroupは存在ごと消えてしまう。
Public Sub Traverse() Dim sh As Shape Dim gsh As Shape 'スライド中の全アイテムをループ For Each sh In ActivePresentation.Slides(1).Shapes Debug.Print sh.Type '(A) Debug.Print "---" If sh.Type = msoGroup Then 'グループ中のアイテムをループ For Each gsh In sh.GroupItems Debug.Print gsh.Type '(B) Next End If Next End Sub
実行結果: 6 (msoGroup 上図(1)) --- 17 (msoTextBox 上図(2)) 13 (msoPicture 上図(3)) 3 (msoChart 上図(5)) 17 (msoTextBox 上図(7)) 17 (msoTextBox 上図(8))
最初のDebug.Print((A)の箇所)では、Groupを示す“6”が出力される。(最上位にあるのが(1)のGroupのみなので)
続くコードでGroupの中のアイテムを得るのだが、そのループ内の(B)のDebug.Printでは、GroupItemsが“葉”の要素しか返さないので(2)(3)(5)(7)(8)のみ出力されることになる。(4)(6)のGroupを示す“6”は出力されない。
これでは階層的に辿ることはできない。
外側のグループをグループ解除すると内側のグループが現れるのだから、情報としてはどこかに持っていることは間違いないが、それがどこにあるのか、VBAから取得できるのか、というのは探しても出てこない。
-
- 上のコードの参考までに
-
- 「無理だよ。外側のグループを選択したとき、内側にグループがあっても、グループ自体は選択できないでしょ? データ構造がそうなってるんだよ」的な回答
-
- 同様の原因により、グループ化された図形を全解除するマクロも、冗長になってしまうという例
やるとしたら
- スライド内のオブジェクトを探索
- Groupがあれば、以下の処理を行う
- GroupItemsでその葉要素を全取得、IDをどこかに記録
- Groupを解除
- 1に戻る
で、Groupが無くなるまで繰り返す。記録されたIDから、一応、ツリー構造を再現できる。
元に戻すのも、記録されたのが新しい方から順にIDを取得して再グループ化を行っていけばよい。
そんなんより
パワポのスライドの方のグループ化構造をいじった方が良くね?