简体   繁体   中英

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).

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. This would be very tedious.

Therefore, simplified:

I created new 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

 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. 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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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