色々と思うことが有って、VBAのFormに取り組んでいるのですが
知識が足りず悩んでます。
UserFromにコマンドボタンを動的に追加し、イベントも動的に発生させたいです。
こちらで教わったのですが
Formの内容を、DrawTableに反映する - C#ATIA
こちらを参考にしてみました。
VBA。フォームにコントロールを動的に追加する - Qiita
が、こちらのコード、色々とまずかったのでこんな風に
してみました。
まず、フォームモジュールですが作りましたが何もしません。
とにかく作るだけで、名前は "UserForm1" です。
続いて、クラスモジュール。 名前は "Class1" です。
Option Explicit
Private WithEvents mBtn As MSForms.CommandButton
Sub InitBtn(ByVal Btn As MSForms.CommandButton)
Set mBtn = Btn
End Sub
Private Sub mBtn_Click()
Dim Msg$
Msg = "オートコンプリートで、" & vbNewLine & _
"ControlTipText出ませんが" & vbNewLine & _
"このボタンでは[ " & mBtn.ControlTipText & " ]です"
MsgBox Msg
End Sub
続いて標準モジュール。 名前は "Module1" です。
Option Explicit
Sub FormTest()
Dim CapAry As Variant: CapAry = Split("hoge,piyo,fuga", ",")
Dim TipAry As Variant: TipAry = Split("foo,bar,baz", ",")
Dim BtnInfoAry() As Variant: ReDim BtnInfoAry(UBound(CapAry))
Dim i&
For i = 0 To UBound(CapAry)
BtnInfoAry(i) = Array(CapAry(i), TipAry(i))
Next
Call Init_Form(BtnInfoAry)
End Sub
Private Function Init_Form(ByVal InfoAry As Variant) As UserForm1
Dim BtnCnt&: BtnCnt = UBound(InfoAry)
Dim Uf As UserForm1: Set Uf = UserForm1
With Uf
.Width = 70
.Height = (BtnCnt + 1) * 20 + 30
End With
Dim i&, Btn As MSForms.CommandButton
Dim BtnAry() As Class1: ReDim BtnAry(BtnCnt)
For i = 0 To BtnCnt
Set Btn = Uf.Controls.Add("Forms.CommandButton.1", i, True)
With Btn
.Top = 5 + (i) * 20
.Left = 5
.Height = 20
.Width = 70
.Caption = InfoAry(i)(0)
.ControlTipText = InfoAry(i)(1)
End With
Set BtnAry(i) = New Class1
Call BtnAry(i).InitBtn(Btn)
Next
UserForm1.Show
End Function
Init_Form関数は戻り値返していないのですが、後のテストの為です。
この関数のキモは、こちら
Dim Uf As UserForm1: Set Uf = UserForm1
インスタンスを生成しているのではなく、最初に作った空っぽのForm自体を
受け取っています。
で、この状態であれば無事動き、イベントも発生します。
自宅なのでExcelでやってますが、CATIAでも同じでした。
問題はここから。先程の部分をインスタンスに変更します。
Dim Uf As UserForm1: Set Uf = New UserForm1
これだと、イベントが発生しません・・・。
又、インスタンスではなく最初の状態に戻し、
Option Explicit
Sub FormTest()
・・・
Dim Uf As UserForm1
Set Uf = Init_Form(BtnInfoAry)
Uf.Show
End Sub
Private Function Init_Form(ByVal InfoAry As Variant) As UserForm1
Dim BtnCnt&: BtnCnt = UBound(InfoAry)
Dim Uf As UserForm1: Set Uf = UserForm1
・・・
Next
Set Init_Form = Uf
End Function
FormTest側で戻り値を受け取り、FormTest側でShowさせても
同様にイベントが発生しません。
(本当はこうしたかったので、関数名をInit_Formしたのに…)
こんなもんなのでしょうか?
追記です。 教えていただきました。
フォームモジュールは空っぽではなく、この様にしました。
Option Explicit
Private mAry As Variant
Sub SetBtn(ByVal Ary As Variant)
mAry = Ary
End Sub
標準モジュールはこの様に
Option Explicit
Sub FormTest()
・・・
Dim Uf As UserForm1
Set Uf = Init_Form(BtnInfoAry)
Uf.Show
End Sub
Private Function Init_Form(ByVal InfoAry As Variant) As UserForm1
Dim BtnCnt&: BtnCnt = UBound(InfoAry)
Dim Uf As UserForm1: Uf = New UserForm1
・・・
Next
Call Uf.SetBtn(BtnAry)
Set Init_Form = Uf
End Function
これで上手く行きました。 ありがとうございます。