ワークシート上のフォームコントロールはどうやって取得する?【VBA】
最近書いた「サクラクレパスクーピーの柄をランダムに生成するExcelマクロを考えてみた」の続きです。ワークシート上でフォームコントロールの図形を扱っていたときに少し引っかかった話です。
フォームコントロールのボタンが消えてしまった
このクーピー柄生成マクロを作っている際に、シート上に生成した図形をすべて消すため、以下のマクロを書きました。
見ておわかりの通り、アクティブなシート上に存在する図形をすべて消去するマクロです。このマクロをフォームコントロールのボタンに登録し、そのあとボタンを押して実行したのですが、
押したボタンまで消えてしまった……
まあ「そんなの当たり前だろ」って話なのですが、Shapeオブジェクト=オートシェイプくらいの認識しかなかった私は、このとき初めて「フォームコントロールもShapeオブジェクトに含まれるのか…」と思ったわけです。
ではフォームコントロールをどうプログラムに識別させる?
というわけで、deleteメソッドで図形のうちボタンだけを消去せずに残す対策を考えることに。Shapeオブジェクトのプロパティの中に、必ずフォームコントロールであることを指定するプロパティがあるはずなので、それを探すことにしました。
繰り返しますが、私の中でShapeオブジェクトはオートシェイプのイメージしかなかったので、当初このフォームコントロールを探すのに、AutoShapeTypeプロパティのどれに該当するのかなーという発想になり、それを探してました。ちなみに以下が公式リファレンスです。
当然、該当するものは見つかりません…
フォームコントロールはTypeプロパティで指定する
その後、ある人のブログを見てようやく判明。Shapeオブジェクトには、Typeプロパティというのがあって、そこでAutoShape以外のShape(例えば画像とかフォームコントロールとかテキストボックスとか)の種類を指定できるのですね。ちなみに以下が公式リファレンスです。
今回探していたフォームコントロールはmsoFormControlでと書くようです。というわけで最初に紹介したマクロは以下のように修正するのがよいでしょう。
こうすれば、ボタンは消去されません。あと今回のクーピー柄生成マクロでは、柄の上にクーピーの商品名が書いてある画像ファイルを貼り付けてあり、それも消去の対象から外したいので、それも上記コード中に書いてあります。画像はmsoPictureというType名です。
まぁ「オートシェイプだけを消す」という目的なら
If shp.type = msoautoshape
と書いて、「オートシェイプに該当したら消去」というロジックでもいいんですけどね。
以上、Shapeオブジェクト=オートシェイプと恥ずかしい思い込みをしていた私のちょっとした失敗談でした。