t-hom’s diary

主にVBAネタを扱っているブログ…とも言えなくなってきたこの頃。

VBA オートシェイプのグループを再帰的にグループ解除する。

今回は多重的にグループ化されたシェイプを全てグループ解除するマクロを紹介する。
f:id:t-hom:20180602054150p:plain

グループ化されたもの同士がさらにグループ化されていると、一度解除しても以下のようにまだ子グループが残る。
f:id:t-hom:20180602054313p:plain

もう一度解除するとようやくすべてのシェイプが分解される。
f:id:t-hom:20180602054615p:plain

これをマクロでやるには、プロシージャの再帰呼び出しを利用する。再帰とは、プロシージャ内で自分自身のプロシージャを呼び出すこと。

メインの再帰部分はこちら。
※単体では使えない。

Sub RecUngroupShape(sh As Shape)
    Dim memberShape As Shape
    If sh.Type = msoGroup Then
        For Each memberShape In sh.Ungroup
            Call RecUngroupShape(memberShape)
        Next
    End If
End Sub

RecUngroupShapeはシェイプを受け取るとグループかどうかを判定し、グループだったらUngroupメソッドを実行する。
UngroupメソッドはShapeRangeを返す。
ShapeRangeをFor Eachで回すとmemberShape変数に各シェイプが入る。
このmemberShape変数を引数としてさらに自分自身を呼び出す。

このRecUngroupShapeを呼び出すためのマクロがこちら。

Sub hoge()
    Dim sh As Shape
    For Each sh In ActiveSheet.Shapes
        Call RecUngroupShape(sh)
    Next
End Sub

今回はActiveSheetの全シェイプをグループ解除してみた。
もちろんも、特定のシェイプグループを渡すことも可能。

再帰についてよくわからなければ、以下の記事で仕組みを説明してるのでどうぞ。
thom.hateblo.jp

最近そういえば、再帰プロシージャはRec~という接頭辞をよく付ける。
どこかで見て気に入ってるからだけどRecursive(再帰的)の略で、プログラマーにはRecが浸透してるイメージがあるけど、省略せずにRecursiveと書いたほうが良いか悩む。

当ブログは、amazon.co.jpを宣伝しリンクすることによってサイトが紹介料を獲得できる手段を提供することを目的に設定されたアフィリエイト宣伝プログラムである、 Amazonアソシエイト・プログラムの参加者です。