多个类似动态创建的命令按钮的操作

时间:2014-07-03 15:48:20

标签: excel vba excel-vba dynamic commandbutton

我正在Excel VBA中编写一个程序,基本上从一个文本框和一个命令按钮开始,命令按钮将在其下面创建一个新的文本框和命令按钮,该命令按钮将依次创建一个新的文本框和命令按钮,等等。希望你能跟上这个烂摊子。

我可以创建初始按钮没问题(它必须动态创建,以便以后有机会删除)。我的问题是创建click()事件处理程序。我需要所有click()事件做同样的事情,但是将新对象命名为相对于它自己的名字。这一切都让我大吃一惊,我真的很感激一点帮助。

随意询问具体信息,但我还没有真正能够完全掌握这个主题,以便编写一些测试代码。

1 个答案:

答案 0 :(得分:2)

创建一个名为CEventClass的自定义类模块(Insert - Class Module,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

现在创建一个没有控件的Userform。将此代码放在表单的代码模块

'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

现在,当您运行表单时,如果单击/更改控件,则会触发这两个事件。

您可能会注意到文本框没有AfterUpdate事件。该事件实际上不是文本框事件,而是文本框的控件容器事件,因此您无法以这种方式公开它。这就是我喜欢在设计时创建所有控件并根据需要隐藏或取消隐藏它们的原因之一。我仍然可以使用WithEvents进行一些控制,所以我不必重复代码。但是对于像TextBox_AfterUpdate这样的东西,我只是在设计时创建所有的事件过程。

<强>更新

如果您希望活动创建新按钮,则必须执行更多操作。首先,您必须在userform之外公开集合。您可以将其添加到Userform模块

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的引用。