使用一个事件处理程序处理多个用户窗体控件 - VBA Excel
Handling Multiple UserForm Controls With One Event Handler - VBA Excel
我动态创建了许多按钮(创建计划)并希望所有按钮在 Click 事件 (OnClick 属性) 期间做同样的事情。
当然,我可以预先在窗体上创建最大数量的按钮并将它们设置为不可见,等等,同时考虑到可以有超过一千个按钮,同时在它们的 Click 事件上添加 "call SomeEvent"。这会很乏味。
因此,简化:
我创建了新的 class btnClass`
Public WithEvents ButtonEvent As MsForms.CommandButton
Private Sub ButtonEvent_Click()
MsgBox "hey"
End Sub
然后,在我的用户窗体中,我在动态创建按钮的地方添加了这个(我也有集合,稍后删除按钮),其简化形式:
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
但是当我点击动态创建的按钮时没有任何反应。我错过了什么?
---更新
---@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
这样,只为最后创建的按钮分配一个事件。你必须声明一个类的数组...我也玩了一下新创建的按钮的Left
属性,只是为了有可能测试他们的点击事件。请尝试下一种方法:
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
我动态创建了许多按钮(创建计划)并希望所有按钮在 Click 事件 (OnClick 属性) 期间做同样的事情。
当然,我可以预先在窗体上创建最大数量的按钮并将它们设置为不可见,等等,同时考虑到可以有超过一千个按钮,同时在它们的 Click 事件上添加 "call SomeEvent"。这会很乏味。
因此,简化:
我创建了新的 class btnClass`
Public WithEvents ButtonEvent As MsForms.CommandButton
Private Sub ButtonEvent_Click()
MsgBox "hey"
End Sub
然后,在我的用户窗体中,我在动态创建按钮的地方添加了这个(我也有集合,稍后删除按钮),其简化形式:
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
但是当我点击动态创建的按钮时没有任何反应。我错过了什么?
---更新 ---@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
这样,只为最后创建的按钮分配一个事件。你必须声明一个类的数组...我也玩了一下新创建的按钮的Left
属性,只是为了有可能测试他们的点击事件。请尝试下一种方法:
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