Excelで、全ての図形のグループ化を、全階層解除するVBAの書き方J-POPコード進行解析ブログ邦楽最新曲のコード譜・感想や、アーティスト別のコード進行の傾向をまとめた記事が中心。音楽理論、コード理論についての記事も随時更新。最後にはじめに本記事では、Excelにおいて、あるシート内に複数のグループ化された図形(あるいはテキストボックス、画像など)のグループを、多階層にわたって一斉に解除するマクロをご案内します。この記事を書こうと思ったかと言うと、自分が仕事でそのような処理が必要になってネットを調べてみたところ、1階層のみのグループを解除する方法は多く見つかったのですが、紹介されていた多くの方法ですと、何度もグループ化を連続して行った複雑な図形に対しては、最後のグループ化しか解除できないことが多かったためです。ちなみに、動作確認はExcel2013でのみ行っております。多階層のグループ化って?そもそも、記事の対象にしている多階層のグループ化とはどのようなことを表しているかについて、説明します。テキストボックスと矢印の図形を同時に選択して、右クリック→「グループ化」を選択すると、2つの図形が連結され、以後、移動や拡大・縮小したい時などには、図形のうち1つを選択すれば、同時に複数の図形に対して処理ができるようになります。これがグループ化です。グループ化した図形は、グループ化した図形同士、あるいは、グループ化した図形と単独の図形、と言った具合に、更に新しいグループを何度も作成することができます。このことを、この記事では多階層のグループと呼んでいます。エクセルで図面などを設計していくと、新たに矢印やら注釈やら加えていくうちに、グループが何階層にもなってしまうことがあります。上の図が例で、四角やら星やら矢印やら合計7つのオブジェクトを何段階かを経てグループ化を行いました。1つの大きなオブジェクトとして全体が選択された状態になっています。これを全て解除したくなった場合、もし手動で行うとなると、右クリック→「グループ化の解除」を何度も行う必要があります。グループ化を何段階にも分けて行っていた場合、それぞれのパーツごとにグループ化を解除しなければいけません。オブジェクトを2つに分解して、その両方を3つずつに分解して、更にその3つ(計6つ)を分解...といった具合です。手動で行っていたら解除漏れなどのミスも出てくるでしょうし、何百ページにもわたるシートの場合は、そんなことやってられません。そのような操作を自動で行える構文を考えた、というのが今回の内容の趣旨というわけです。ちなみに、なぜグループを全解除したくなったかと言いますと、僕の場合は、実務において、全てのオブジェクトに対して文字列操作が必要になり、グループ化されたままだと、個々のオブジェクトに書かれた文字にアクセスするのが非常に難しいことがわかっためです。そこで、いったんグループ化されたオブジェクトを全てバラバラにする必要が出てきました。他にも、ごちゃごちゃになった図をいったん整理して作り直したいなどの理由もあるかと思います。全グループ解除のコード例グループ化を階層も考慮して全て解除するVBAのコードは以下の通りです。上記のコードは、2重ループの構文となっています。内側のループは、9行目から17行目までの部分で、シート内にある全てのオブジェクトについて、それがグループ化されたオブジェクトかどうかを検査し、もしそうであればグループ化を1階層分だけ解除し、フラグ(このソースコードでは、変数bGrp)を立てる、という処理を行っています。shapesの構文では、グループ内にあるオブジェクトまではアクセスできないからです(もしかしたら方法は存在するかもしれませんが...。調べた限りはわかりませんでした)。したがって、まずは一番階層の浅いグループを解除し、それがいったん終わったら次の階層を解除・・・という具合に、階層ごとにループを解除しているのです。Loopまで(5行目~23行目)の部分です。Doが実行され、ループを抜けることになります。Falseがないと、無限ループしますので注意してください。上の例は全ての階層のグループを解除する構文ですが、第一階層まで解除したくない場合などは、Do~Loopループをなくして、その中身のループだけ記述すれば可能ですし、回数を指定してループを回せば、浅い方から第3階層までのみ、解除、といったことも可能です。最後に上の構文で、かなり複雑なグループオブジェクトも全解除できることも確認しました。(図は少しわかりにくいかもしれませんが、マクロ実行後の状態です。先ほどはグループ化されていたものが、バラバラの状態で選択できていることがわかるかと思います。)ただ、スピード(効率)に関しては、これが最善の方法かどうかはわかりません。いや、もっと効率的な方法はあるでしょう。いうのも、僕の方法だと、グループ化されていないオブジェクトが、何度もアクセスされてしまうからです。その多くは、12行目の条件文を満たさず、実質的な処理は何もしないため、処理速度的にほとんど影響はないと考えていますが、判定文に入ること自体が無駄であることには変わりがありません。グループ化されているオブジェクトを発見したら、その中に再帰的に入り込んでいくといったコーディングができれば、その方がよいプログラムと言えるでしょう。その辺は方法がわかり次第記事を上げようかと思います。冒頭でネットを見てもよい方法が見つからなかったと書きましたが、これに関しても、単に僕が見つけられなかっただけかもしれませんので、その点は何卒ご了承ください。本記事がどなたか目に留まり、お役に立てたのなら幸いです。当記事では、Wordにおいて本文中にページ番号を貼り付ける方法を紹介します。J-POPコード進行解析ブログ。