目次

グループ階層を取得 - PowerPoint VBA

結論:できないっぽい?調査中

やりたいこと

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から取得できるのか、というのは探しても出てこない。

やるとしたら

  1. スライド内のオブジェクトを探索
  2. Groupがあれば、以下の処理を行う
    1. GroupItemsでその葉要素を全取得、IDをどこかに記録
    2. Groupを解除
    3. 1に戻る

で、Groupが無くなるまで繰り返す。記録されたIDから、一応、ツリー構造を再現できる。

元に戻すのも、記録されたのが新しい方から順にIDを取得して再グループ化を行っていけばよい。

そんなんより

パワポのスライドの方のグループ化構造をいじった方が良くね?