【问题标题】:Handling Multiple UserForm Controls With One Event Handler - VBA Excel使用一个事件处理程序处理多个用户窗体控件 - VBA Excel
【发布时间】:2020-05-11 19:23:50
【问题描述】:

我动态创建了许多按钮(创建计划),并希望所有按钮在 Click 事件(OnClick 属性)期间都做同样的事情。

当然,我可以预先在表单上创建最大数量的按钮并将它们设置为不可见,等等,同时考虑到可能有超过一千个按钮,在他们的 Click 事件中添加“调用 SomeEvent”。这将非常乏味。

因此,简化:

我创建了新类 btnClass`

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

然后,在我的 UserForm 中,我动态地创建按钮,我添加了这个(我也有 Collection,以便稍后删除按钮),以简化形式:

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

【问题讨论】:

    标签: excel vba events onclick handler


    【解决方案1】:

    这样,只为最后创建的按钮分配一个事件。你必须声明一个类数组...我还玩了一点新创建按钮的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
    

    【讨论】:

    • 也许不需要单独的集合来保存按钮,因为Buttons 的每个元素都有一个ButtonEvent 字段,它是底层按钮对象?
    • @Tim Williams:我认为他使用该集合来删除新创建的按钮......他谈到了这方面,这就是我将其保留在我的代码中的原因。正如我想象的那样,我还将发布删除按钮代码。为了,也许,更有意义......
    • @FaneDuru:谢谢。我明天会检查它是否有效。关于向右移动按钮,我只是不小心删除了更改 .Left 属性。我想我尝试了下面的数组解决方案,但是当后来我想通过集合删除按钮时出现错误......在循环中分配 Buttons.ButtonEvent = theButton 是否会添加所有处理程序?将再次检查以查看问题所在...代码很大,很难追踪所有内容。不过,我会处理数组并将整个代码发布在这里并删除......再次感谢您的大力帮助
    • @ulviii:我会说,不需要发布所有内容。请尝试测试上面的代码(同时保留我设置的变量声明)并在看到它工作后(我对其进行了测试并且它在我的计算机上工作)我们可以在必要时考虑其他改进......关于数组问题,在要创建的新按钮处成为Redim 很重要。否则,它可能会返回错误。无论如何,等你有机会测试它后,我会等待一点反馈。
    • @FaneDuru:完美运行,非常感谢!我第一次尝试自己使用数组时忘记添加第二维,如果没有你的帮助,我会完全放弃!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-09
    • 2015-07-15
    • 2012-10-31
    • 1970-01-01
    • 1970-01-01
    • 2017-02-04
    • 2011-09-26
    相关资源
    最近更新 更多