[ExcelVBA] UserForm上で複数コントロールを動的に追加&イベント検出する

[ExcelVBA] UserForm上で複数コントロールを動的に追加&イベント検出する

ExcelVBAのフォームで、コントロールを動的に作成していくことってできないのかなと思って調べてまとめました。クラスを使えばイベントも拾えるので、いろいろ使えるかもしれません。


背景

VBAで作ったシステムで、UserFormがこんな感じになってるのがあって。赤字がコントロール名で、最後のXが下に行くごとに連番になってるような。

各10個だったので、まあまあめんどくさかったですけど、コントロール名を1個ずつ設定して、それに対してクラスを使ってChangeイベントを拾って、ということをしてました。

そしたら仕様変更があって、ここの数もうちょい増やせない? という話に。あっ、めんどくさそうな予感! 多めに見積もったら100ほしいって! マジか!!

イベント処理のためにコントロール名が「文字列&連番」という形になっててほしいので、当初、TextBoxをコピペで100個くらい作っておいて、

こういうことはできないのかなー、と試してみたのですが、実行時にNameプロパティの変更はできないぜって怒られました。考えてみりゃ、そりゃそうか。

それで他の方法を探してたら、コントロールを追加するAddメソッドのページにたどり着きまして、

ここの最後のほうに書いてあるんですが、

コントロールの Name プロパティを実行時に変更できるのは、Add メソッドで実行時にそのコントロールを追加した場合だけです。

おお、これだ!! という流れです。

実装

フォームの高さ設定

まずは100個ずらーっと並んでもいいように、ユーザーフォームにスクロールバーをつけてやります。フォームのプロパティでこのように。

「ScrollHeight」がスクロールできる高さになります。

フォーム読み込み時にコントロールを追加

コントロールを描写したいフォームモジュールに以下のように書きます。フォームの名前はEditFormにしてあります。

フォームモジュール(EditForm)

1行目が繰り返し描写したいコントロールの総数。ラベル、テキストボックス2つ、チェックボックスを100個描写します。位置や大きさはお好みで。

標準モジュール

標準モジュールにフォーム表示のコードを書きます。

実行してみればこんな感じに。ちゃんと100個できます。フォームのScrollHeightが足りないと切れちゃうので調節してください。(やってみたら全然1000pxじゃ足らなかった!)

これで、動的に配置された各コントロールも、名前はちゃんと文字列&数値になってるので、

こんな感じにチェックしたりできます。

動的追加されるコントロールのイベントを検出する

右側列のテキストボックスのイベントを拾って、変更されたときになにか動くようにしてみましょう。EventClassという名前のクラスモジュールを作ります。

クラスモジュール(EventClass)

テキストボックスの動きを定義しておきます。必要であればラベルでもチェックボックスでもOK。

7~13行目がChangeイベントのときに走るプロシージャで、変更されたテキストボックスのコントロール名と値をメッセージボックスに出します。コントロール名から数値だけ取り出せば、同じ行の他コントロール(ここではチェックボックス)の操作が可能です(11~12行)。

フォームモジュール(EditForm)

さっきのフォームのコードにハイライト部分を追加。数量用のテキストボックスにだけ適用されます。

結果

実行して、適当な場所に変更を加えるとメッセージボックスが開きます。

メッセージボックスを閉じると、同じ行のチェックボックスがオンに。

ただ、テキストボックスのChangeイベントは一文字変更されるごとに走ってウザいので、実用ではもうちょい工夫したほうがいいかもです。

公開日:2018/05/02

コメントを残す




*印は必須項目です。コメントは承認制ですので、反映までしばらくお待ち下さい。(稀にですがスパムの誤判定にて届かないこともあるようですので、必要な際はお問い合わせからお願い致します。)