プログレスバーで進捗状況をビジュアルで表示する記事を紹介していますが、そこで使うユーザフォームはあらかじめ設定済みのものを使って表示しています。そのユーザーフォームを使う時だけVBAのコード内で動的に作成し、使わなくなったら解放できないかやってみたいと思います。
それってどういうことですか? そんなことできるんですか?
例えば、プログレスバーや独自のメッセージボックスを表示させる場合、あらかじめVBA作成時につくっておかなくても、使う時だけその都度つくるものいいのかなと 思うんですよね。
今回は UserForm を作成するところまでやってみましょう(^^)/
そのプログレスバーの記事がこちらです。
【この記事でわかることは】
・UserForm を動的に作成する方法
・作成した UserForm を使用後に削除する方法
VBAで動的にユーザーフォームを作成追加する
プロジェクトにユーザーフォームを追加する場合の動作は、VBE(Visual Basic Edtor)を使います。VBEを操作するためのオブジェクトやプロパティを確認してみました。
VBE もオブジェクトで Applicationオブジェクトの配下す。VBE 内には VBAProject があり、VBComponents コレクションが VBComponent オブジェクトの標準モジュールやフォーム(UserForm)などの各種モジュールを管理しています。
VBE からユーザーフォームを追加作成するということは、フォームモジュールを追加するということです。追加するなら、使うのは Add メソッドですよね。ということで、Add メソッドからたどってみました。
MSリファレンスでAdd メソッド (VBA アドイン オブジェクト モデル)を確認してみました。
【構文】object.Add (component)
引数 component の定数に vbext_ct_MSForm がありました。
vbext_ct_MSForm は、コレクションにフォームを追加してくれます。
引数 component オブジェクトのTypeプロパティは次表のように「vbext_ComponentType列挙型」の値(定数)でモジュールの種別を指定できるようになっています。
vbext_ComponentType | 値 | コレクションに追加される種別 |
---|---|---|
vbext_ct_StdModule | 1 | 標準モジュールを追加 |
vbext_ct_ClassModule | 2 | クラス モジュールを追加 |
vbext_ct_MSForm | 3 | ユーザーフォームを追加 |
vbext_ct_ActiveXDesigner | 11 | ActiveXデザイナを追加 |
vbext_pt_StandAlone | 100 | 独立したプロジェクトを追加 |
object には VBComponent オブジェクトが該当します。VBComponent オブジェクトは VBProjects コレクションのメンバーですので、
VBProject.VBComponent.Add(vbext_ct_MSForm) とこんな感じでいけそうですね。
それでは、実際にユーザーフォームを作成できるかさっそく試してみましょう。
VBE オブジェクトを使用できるように準備します
「Microsoft Visual Basic for Applications Extensibility 5.3」を参照設定する必要があります。
単純にユーザーフォームを作成するコード
'ユーザーフォームを作成する
Sub FormAddTest01()
Dim Frm As VBIDE.VBComponent
'ユーザフォームを追加
Set Frm = ThisWorkbook.VBProject.VBComponents.Add(vbext_ct_MSForm)
With Frm
.Properties("Caption") = "ユーザーフォーム"
.Properties("Height") = 100
.Properties("Width") = 250
End With
End Sub
フォームを追加して、いくつかプロパティーを設定しました。
テストしている際の動画がこちらです。
VBAProject に UserForm1 モジュールが追加されました。
ユーザーフォームを解放(削除)します
こんどは、追加した UseForm を解放(削除)します。
当初 Subプロシージャ だけで処理させてみたのですが、初回はうまくいくのですが2回目の実行でエラー「パス/ファイルのアクセス エラー (エラー 75)」が発生します。そこで、UserForm 作成部分を Function(関数)にして UserForm 名を返すようにしてエラー発生を回避するようにしました。
'UserForm の作成/解放はここから実行
Sub FrmMakeSample()
Dim obj As Object
Dim frmName As String
'UserForm作成関数を呼び出す(作成フォーム名が返る)
frmName = FormAddTest01
'UserForm表示
UserForms.Add(frmName).Show
'ここにやりたい作業を入れる
'作成したUserFormを解放(削除)する
For Each obj In ThisWorkbook.VBProject.VBComponents
With obj
If .Type = vbext_ct_MSForm And .Name = frmName Then
Application.VBE.ActiveVBProject.VBComponents.Remove obj
Exit For
End If
End With
Next obj
Set obj = Nothing
End Sub
'UserForm を作成する関数
Function FormAddTest01()
Dim Frm As VBIDE.VBComponent
'UserFormを追加
Set Frm = ThisWorkbook.VBProject.VBComponents.Add(vbext_ct_MSForm)
With Frm
FormAddTest01 = .Name '作成下UserForm名取得
.Properties("Caption") = "ユーザーフォーム"
.Properties("Height") = 100
.Properties("Width") = 250
End With
End Function
シートの「実行ボタン」から実行させてみた際の動画がこちらです。
・まず、出来上がった空の UserForm が表示されます。
・VBAProject に UserForm が追加されています。
・ UserForm の「×」クリックと同時に VBAProject から UserForm が解放され、消えて無くなるのを確認できます。
まとめ(おわりに)
以上、Excel VBA で UserForm を動的に追加して利用できることが確認できたました。
次回は UserForm に動的に各種コントロールを追加設定する方法をプラスしていきます。
最終的には、プログレスバーを動かすところまでを目標として行きたいと思います。
サンプルファイルをダウンロードできるように登録していますので是非お試しください。
まとめと感想など
空の UserForm だけですがうまく作成と解放ができました。独自のメッセージボックスならすぐに作れそうですね。いかがでしたか(^^)
ちょっと難しかったけど、仕組みが何となくわかったのですごく勉強になりました(^^ゞ
★★★ ブログランキング参加中! クリックしてね(^^)/ ★★★
【今後の記事について】
今回の記事はいかがだったでしょうか。皆さまのお役に立てたなら幸いです(^^;
「汎用でだれでも使えて活用できるように考えてる」というポリシーで、記事を継続して書いていきたいと思っています。どうぞよろしくお願いしますm(_ _)m
【検討中の今後の記事内容は・・・・】
・実務に役立つものを提供できるよう常に検討しています(^^ゞ
・その他雑記的に「プチネタなど」もいろいろ考えていきたいと思っています・・・・
・今後の記事にご期待ください(^^)/
過去記事のサンプルファイルをダウンロードできます
今回記事のサンプルファイルをリンク先に登録しています!
過去の記事で使用したサンプルファイルをダウンロードできるようにページを設置していますので、こちら(このリンク先)からご利用ください
【今回わかったことは】
・UserForm を動的に作成する方法がわかりました
・UserForm を解放する方法がわかりました