在 VBA 中动态定义复选框的事件

Posted

技术标签:

【中文标题】在 VBA 中动态定义复选框的事件【英文标题】:Dynamically define the events of the checkboxes in VBA 【发布时间】:2016-09-21 08:04:35 【问题描述】:

我已经为我的用户窗体动态定义了复选框。 见代码:

If rs.EOF = False Then
    i = 1
    Do Until rs.EOF Or i = 6
        With frmOne.Controls("Version" & i)
            .Visible = True
            .Caption = rs!versNo & "#" & rs!Vers_From
            .tag = rs!versNo & "_" & rs!noID & ".pdf"
        End With
        i = i + 1
        rs.MoveNext
    Loop
End If

嗯,对于这些复选框,我需要一个“点击”事件。例如:

Private Sub Version1_Click()
   If FilterOk = True Then
       VersNr = Mid(frmOne.Version1.tag, 1, InStr(frmOne.Version1.tag, "_") - 1)
       Call funcVersion
       Exit Sub
   End If
   ...
End Sub

我怎样才能使动态?我不需要命令按钮。这意味着,当用户单击复选框时,事件处理程序就会启动。

【问题讨论】:

控件使用基本相同的代码吗? @Rory 是的! 那么这基本上是这个问题的重复:***.com/questions/10592641/… @rory 但我不需要命令按钮 我知道但是原理和其他控件完全一样。 【参考方案1】:

Rory 说这是一个副本是对的,但由于我已经写了一点 sn-p,所以我会在这里发布。我希望它不违反规则。您需要使用将处理事件的启用事件的对象创建一个自定义类。然后,您可以将您的复选框的引用分配给这些对象。

一个简单的演示示例:

创建一个名为CheckBoxEventHandler 的类模块,并将以下代码放入该类模块中。

' This will store a reference to a checkbox and enable handling its events.
Private WithEvents m_chckBox As MSForms.CheckBox

' Method to assign a reference to a checkbox to your event handler
Public Sub AssignCheckBox(c As MSForms.CheckBox)
    Set m_chckBox = c
End Sub

' Private sub to execute something on the event
Private Sub m_chckBox_Click()
    MsgBox "Checkbox" + m_chckBox.Caption + "clicked"
End Sub

创建一个带有一些复选框的用户表单,并将以下代码放入其模块中:

' Define a collection to store your event handlers while the userform is active.
Private eventHandlerCollection As New Collection

Private Sub UserForm_Initialize()
    Dim chckBoxEventHandler As CheckBoxEventHandler, c As Control

    For Each c In UserForm1.Controls
        If TypeName(c) = "CheckBox" Then
            'Create event handler instance
            Set chckBoxEventHandler = New CheckBoxEventHandler
            'Assign it reference to a checkbox
            chckBoxEventHandler.AssignCheckBox c
            'Store the event handler in the userform's collection,
            eventHandlerCollection.Add chckBoxEventHandler
        End If
    Next
End Sub

这是一种在您的情况下实现此功能的可能方法

(我没有你的确切代码,所以我无法测试它,但我相信它应该给你一个大致的想法。)

1.创建一个名为CheckboxEventHandler的新类

Public WithEvents chckBox As MSForms.CheckBox

Private Sub chckBox_Click()
    Debug.Print "Checkbox" + chckBox.Caption + "clicked"
    ' Do your click-handler logic here.
    ' If you need private variables that are defined elsewhere, you can define the function
    ' whereever you need it and use the eventhandler only to call it and pass it a reference to the clicked checkbox:
    Call somefunction(chckBox)
    ' Or you could define the function as a public method in frmOne and call it from here like this:
    Call frmOne.somefunction(chckBox)
End Sub

2.在frmOne 用户表单的代码开头添加以下内容:

' Define a collection to store event handlers.
Private eventHandlerCollection As New Collection

' Method for adding clickhandlers to checkBoxes dynamically
Public Sub createClickHandler(c As MSForms.CheckBox)
    Dim eventHandler As New CheckBoxEventHandler
    eventHandler.chckBox = c
    Call eventHandlerCollection.Add(eventHandler)
End Sub

3.将事件处理程序附加到复选框

If rs.EOF = False Then
    i = 1
    Do Until rs.EOF Or i = 6

        With frmOne.Controls("Version" & i)
            .Visible = True
            .Caption = rs!versNo & "#" & rs!Vers_From
            .Tag = rs!versNo & "_" & rs!noID & ".pdf"
        End With

        'register event listener
        frmOne.createClickHandler (frmOne.Controls("Version" & i))
        i = i + 1
        rs.MoveNext
    Loop
End If

【讨论】:

有点难理解,分别和我的代码结合。 @yuro 我编辑了我的答案并添加了一个更直接适用于您的代码的示例。【参考方案2】:

使用复选框的AfterUpdate 事件

Private Sub MyCheckBox_AfterUpdate()

   ' If the checkbox is unchecked, do nothing
   If MyCheckbox = False Then Exit Sub  

   ' If the checkbox is checked, do whatever you want:
   If FilterOk = True Then
       VersNr = Mid(frmOne.Version1.tag, 1, InStr(frmOne.Version1.tag, "_") - 1)
       Call funcVersion
       Exit Sub
   End If
   ...
End Sub

【讨论】:

以上是关于在 VBA 中动态定义复选框的事件的主要内容,如果未能解决你的问题,请参考以下文章

动态添加基于工作表名称的新表单控件复选框(Excel VBA)

通过单击事件传递动态值时,它在控制台中显示未定义

动态创建的复选框单击事件选择整行,而不仅仅是 jquery 数据表中的复选框。这是为啥?

在由 AJAX 插入的动态创建元素上绑定事件(复选框)

如何将事件侦听器添加到动态创建的复选框并检查是不是选中了复选框。 JavaScript

Excel VBA 复选框英语与法语