要点
・まずVBIDE.VBComponent
型の変数を宣言し、VBProject.VBComponents.Add
メソッドで生成したインスタンスを格納する
Dim foo = VBIDE.VBComponent
Set foo = ThisWorkbook.VBProject.VBComponents.Add(vbext_ct_MSForm)
・プロパティは.Properties
コレクションで設定するが、.Name
の様に直接設定できるものもある
With foo
.Name = "bar"
.Properties("BackColor") = &HF4F5F6
....
End With
・コントロールの追加は.Designer
プロパティで
Dim con as MSForms.Control
Set con = foo.Designer.Controls.Add("Forms.Label.1")
With con
.BackColor = &HF4F5F6
....
End With
・イベント等を書くのは.CodeModule
プロパティで
With foo.CodeModule
.InsertLines(1, "Private Sub UserForm_Initialize()")
.InsertLines(2, "[codes here]")
.InsertLines(3, "End Sub")
.InsertLines(4, ....)
....
End With
・生成したVBComponentのインスタンス化はUserForms.Add
メソッド、受けるインスタンスはObject
型で
Dim hoge as Object
Set hoge = UserForms.Add("bar")
・インスタンスを.Show
で表示
hoge.Show
・削除はインスタンスのUnload
後に
Call ThisWorkbook.VBProject.VBComponents.Remove(foo)
補足
・.Designer.Controls.Add
で作成したコントロールを受けるオブジェクト(上記con
)は、使い回しがきく。複数・多種のコントロールを追加する場合でも、一つMSForms.Control
型オブジェクトを用意すればいい。
・一方、MSForms.TextBox
等の個別のコントロールに存在してMSForms.Control
に存在しないプロパティは多く、例えばMSForms.Control.Font
とするとエラーが返る。MSForms.Control
には.Properties([property name])
も用意されていないのでプロパティ名からの設定もできない。作成するコントロールの型に合わせてオブジェクトを作ればエラー回避できるが、オブジェクト数が増えて使い回しメリットが減る。
・「追加」と「属性設定」のプロシージャを分けて、追加するプロシージャではMSForms.Control
で受けた後、属性を設定するプロシージャに渡し、その際に(ByRef [paramname] As MSForms.TextBox)
のように個別のコントロール型で受ける手はある。
・同種のコントロールを反復処理で追加するとき、属性の反映が不十分なまま描画進行してしまう(例えば.Height
がまちまちな)ときは、反復処理中にDoEvents
してみる。
・.Designer
プロパティの引数やオプションについてはMicrosoft Docs参照(下記)。
・VBComponentのインスタンス(上記hoge
)をObject
型ではなくMSForms.UserForm
型で受けるとエラー。
・.CodeModule.InsertLines
で設定する行番号は、モジュールオプションの自動挿入を考慮する(例えば、Option Explicit
が自動挿入される設定であれば、行番号は2からスタートする、等)。
・.CodeModule.InsertLines
でプロシージャを書き込むと、ブレークポイント設定もStop
コマンドも許されない(「中断モードでは入力できません」→「継続」or「終了」の選択を迫られる)。デバッグの妨げになるので、静的に生成したUserFormで完成させてから動的UserFormに移行するのが無難。
・インスタンスのUnload
前にVBComponents.Remove
するとExcelが落ちる。
参考サイト
[Microsoft Docs: Properties (Visual Basic Add-in Model)]
https://docs.microsoft.com/ja-jp/office/vba/language/reference/visual-basic-add-in-model/properties-visual-basic-add-in-model
[Reference Dynamic UserForm Name]
https://www.excelvbasolutions.com/2017/08/reference-dynamic-userform-name.html