简体   繁体   English

使用一个事件处理程序处理多个用户窗体控件 - VBA Excel

[英]Handling Multiple UserForm Controls With One Event Handler - VBA Excel

I created many buttons dynamically (creating schedule) and want all of them do the same thing during Click event (OnClick property).我动态创建了许多按钮(创建计划),并希望它们在 Click 事件(OnClick 属性)期间都做同样的事情。

Of course, I can create max number of buttons on the form beforehand and set them invisible, and so forth, while adding "call SomeEvent" on their Click event considering that there can be over a thousand buttons.当然,我可以事先在表单上创建最大数量的按钮并将它们设置为不可见,等等,同时考虑到可能有超过一千个按钮,在他们的 Click 事件中添加“调用 SomeEvent”。 This would be very tedious.这将非常乏味。

Therefore, simplified:因此,简化:

I created new class btnClass`我创建了新的 class btnClass`

Public WithEvents ButtonEvent As MsForms.CommandButton
Private Sub ButtonEvent_Click()
    MsgBox "hey"
End Sub

Then, in my UserForm, where I dynamically create buttons I added this (I also have Collection, to remove buttons later), in its simplified form:然后,在我的用户窗体中,我在其中动态创建按钮,我添加了这个(我也有集合,稍后删除按钮),以简化的形式:

Dim btnColl As Collection
Dim Buttons As New btnClass

Set btnColl = New Collection
Set Buttons = New btnClass

For i = 0 To btnCount

         Set theButton = Controls.Add("Forms.CommandButton.1", "btn" & i, True)
         With theButton
            .Height = 17
            .Caption = "btn" & i
          End With


        Set Buttons.ButtonEvent = theButton
        btnColl.Add theButton, theButton.Name


Next i

But nothing happens when I click dynamically created buttons.但是当我单击动态创建的按钮时什么也没有发生。 What am I missing?我错过了什么?

---UPDATED ---@FaneDuru Provided solution which worked for me ---已更新 ---@FaneDuru 提供了对我有用的解决方案

 ReDim Buttons(0 To btnCount, 0 To dtDiff)


For labelcounter = 0 To dtDiff 'add date labels
    Set theLabel = Controls.Add("Forms.Label.1", "lblDay" & labelcounter, True)
    With theLabel

        .Caption = VBA.Format(DateAdd("d", labelcounter, bDate), "d-mm-yy")
        .Left = 15 + 44 * labelcounter
        .BackColor = vbBlack
        .Font.Bold = True
        .ForeColor = vbWhite
        .Height = 13
        .Width = 40
        .Top = 85
    End With
    For i = 0 To btnCount 'add time buttons
        pTime = DateAdd("n", i * dur, begTime)
        Set theButton = Controls.Add("Forms.CommandButton.1", "btn" & CDate(theLabel.Caption & " " & TimeValue(pTime)), True)
        With theButton
            .Height = 17
            .Caption = VBA.Format(TimeValue(pTime), "hh:mm")
            '.Caption = CDate(theLabel.Caption & " " & TimeValue(pTime))
            .Left = 15 + 44 * labelcounter
            .BackColor = vbGreen
            .Width = 40
            .Top = 100 + 18 * i
        End With


    Set Buttons(i, labelcounter).ButtonEvent = theButton
    btnColl.Add theButton, theButton.Name



    Next i

Next labelcounter

In this way, only for the last created button an event is allocated.这样,只为最后创建的按钮分配一个事件。 You must declare an array of classes... I also played a little with the Left property of the newly created buttons, only to have the possibility to test their click event.你必须声明一个类数组...我还玩了一点新创建按钮的Left属性,只是为了有可能测试它们的点击事件。 Try the next approach, please:请尝试下一种方法:

Option Explicit

Private btnColl As New Collection
Dim Buttons() As New btnClass

Private Sub btCreate_Click()
 Dim btnCount As Long, theButton As CommandButton, i As Long

 btnCount = 3
 ReDim Buttons(0 To btnCount)
 For i = 0 To btnCount

         Set theButton = Me.Controls.aDD("Forms.CommandButton.1", "btn" & i, True)
         With theButton
            .height = 17
            .Caption = "btn" & i
            .left = 50 * i
          End With

        btnColl.aDD theButton, theButton.Name
        Set Buttons(i).ButtonEvent = theButton
 Next i
End Sub

Private Sub btdelete_Click() 'buttons deletion...
 Dim i As Long
   For i = 1 To btnColl.count
       Me.Controls.Remove (btnColl(i).Name)
   Next
End Sub

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM