创建一个名为 CEventClass 的自定义类模块(插入 - 类模块,F4 更改名称)。将此代码输入到类模块中
'These are declared WithEvents so the events are
'exposed to us
Public WithEvents cmdEvent As MSForms.CommandButton
Public WithEvents tbxEvent As MSForms.TextBox
'This will fire for any control
'assigned to cmdEvent
Private Sub cmdEvent_Click()
MsgBox cmdEvent.Caption
End Sub
'This will fire for any control
'assigned to tbxEvent
Private Sub tbxEvent_Change()
If Len(tbxEvent.Text) < 6 Then
tbxEvent.BackColor = vbYellow
Else
tbxEvent.BackColor = vbWhite
End If
End Sub
现在创建一个没有控件的用户窗体。将此代码放入表单的代码模块中
'These will keep the class instances in
'scope for as long as the form is loaded
Private mEventButtons As Collection
Private mEventTexts As Collection
Private Sub UserForm_Initialize()
Dim cmd As MSForms.CommandButton
Dim txt As MSForms.TextBox
Dim clsEventClass As CEventClass
Set mEventButtons = New Collection
Set mEventTexts = New Collection
'Create two commandbuttons
Set cmd = Me.Controls.Add("Forms.CommandButton.1", "FirstName")
cmd.Top = 10
cmd.Left = 10
cmd.Caption = "First"
'Create a new instance of CEventClass and
'assign the button to cmdEvent
Set clsEventClass = New CEventClass
Set clsEventClass.cmdEvent = cmd
mEventButtons.Add clsEventClass
Set cmd = Me.Controls.Add("Forms.CommandButton.1", "SecondName")
cmd.Top = 50
cmd.Left = 10
cmd.Caption = "Second"
Set clsEventClass = New CEventClass
Set clsEventClass.cmdEvent = cmd
mEventButtons.Add clsEventClass
'Create two textboxes and assign them to new instances
'of the class
Set txt = Me.Controls.Add("Forms.TextBox.1", "ThirdName")
txt.Top = 10
txt.Left = 150
Set clsEventClass = New CEventClass
Set clsEventClass.tbxEvent = txt
mEventTexts.Add clsEventClass
Set txt = Me.Controls.Add("Forms.TextBox.1", "FourthName")
txt.Top = 50
txt.Left = 150
Set clsEventClass = New CEventClass
Set clsEventClass.tbxEvent = txt
mEventTexts.Add clsEventClass
End Sub
现在,当您运行表单时,如果您单击/更改控件,这两个事件将触发。
您可能会注意到文本框没有更新后事件。该事件实际上不是文本框事件,而是文本框的控件容器的事件,因此您不能以这种方式公开它。这就是我更喜欢在设计时创建所有控件并根据需要隐藏或取消隐藏它们的原因之一。我仍然可以将 WithEvents 用于某些控件,这样我就不必过多地重复代码。但是对于像 TextBox_AfterUpdate 这样的东西,我只是在设计时创建了所有的事件过程。
更新:
如果您希望事件创建新按钮,您必须做更多的事情。首先,您必须在用户窗体之外公开集合。你把它添加到你的用户表单模块中
Public Property Get EventButtons() As Collection
Set EventButtons = mEventButtons
End Property
然后你改变你的命令按钮事件代码来创建一个新按钮
Private Sub cmdEvent_Click()
Dim cmd As MSForms.CommandButton
Dim clsEventClass As CEventClass
Set cmd = cmdEvent.Parent.Controls.Add("Forms.CommandButton.1", cmdEvent.Caption & "1")
cmd.Top = cmdEvent.Top + 40
cmd.Left = cmdEvent.Left
cmd.Caption = cmdEvent.Caption & "1"
Set clsEventClass = New CEventClass
Set clsEventClass.cmdEvent = cmd
cmdEvent.Parent.EventButtons.Add clsEventClass
End Sub
这将创建一个新按钮,该按钮位于被单击的位置下方 40 点处。你没有说你的命名或定位逻辑是什么,所以我假设你可以解决这个问题。使用 cmdEvent.Parent 获取对 Userform 的引用。