如何使用.OnAction作为ActiveX复选框

时间:2016-12-01 18:33:56

标签: excel vba checkbox

我有一个按钮,可以根据用户选择的单元格范围生成ActiveX复选框。这些复选框链接到相应的单元格。此外,还会生成一个主复选框,用于选中/取消选中其余复选框。

我要做的是在选中此主复选框时会发生事件,最后检查其余部分。

我在想这样的东西,就是我的Master Checkbox的创建:

Sub AddMasterCheckbox(cbNum As Integer, cbIdent As String, Rng As Range)
Dim name
With ActiveSheet.OLEObjects.Add(ClassType:="Forms.CheckBox.1", _
    Left:=1033.5, Top:=Rng.Top, Width:=150.5, Height:=20.75)
    If cbNum < 10 Then
        .name = "NewCheckBox" & cbIdent & "0" & cbNum
    Else
        .name = "NewCheckBox" & cbIdent & cbNum
    End If
    name = .name
    .Object.Caption = "Select all for this Machine"
    .Object.OnAction = "'SelectAll ""name""'"
End With
End Sub

但是,我收到错误,声明不支持此操作。 基本上,我有另一个名为SelectAll的子程序,理想情况下,当单击主复选框时会调用它。

我该如何做到这一点?

2 个答案:

答案 0 :(得分:0)

ActiveX控件没有.OnAction方法。仅供参考:Forms.CheckBox.1是指MS表单复选框,而不是Excel表单控件。

或者,您可以使用Excel Forms Control:

Sub AddMasterCheckbox(cbNum As Integer, cbIdent As String, Rng As Range)
    Dim name
    With ActiveSheet.CheckBoxes.Add(Left:=1033.5, Top:=Rng.Top, Width:=150.5, Height:=20.75)
        If cbNum < 10 Then
            .name = "NewCheckBox" & cbIdent & "0" & cbNum
        Else
            .name = "NewCheckBox" & cbIdent & cbNum
        End If
        name = .name
        .Caption = "Select all for this Machine"
        .OnAction = "'SelectAll ""name""'"
    End With
End Sub

注意:如果您更喜欢使用ActiveX控件,则可以使用用户定义的类对COntrols事件进行分组。请参阅我对Returning an index value from a group of ActiveX Option Buttons

的回答

答案 1 :(得分:0)

最简单的解决方案是简单地使用表单控件而不是ActiveX控件。那说......

ActiveSheet.OLEObjects.Add的结果将是OLEObject,其MSForms.CheckBox.Object。它没有OnAction成员。

然而,它确实是源自动化事件(在没有它们的表单上它将毫无价值)。这意味着您可以获取引用,存储它并处理其事件:

'This code can't be in a module.
Private WithEvents master As MSForms.CheckBox

Sub AddMasterCheckbox(cbNum As Integer, cbIdent As String, Rng As Range)
    Set master = ActiveSheet.OLEObjects.Add(ClassType:="Forms.CheckBox.1", _
                    Left:=1033.5, Top:=Rng.Top, Width:=150.5, Height:=20.75).Object
    With master
        If cbNum < 10 Then
            .Name = "NewCheckBox" & cbIdent & "0" & cbNum
        Else
            .Name = "NewCheckBox" & cbIdent & cbNum
        End If
        Name = .Name
        .Object.Caption = "Select all for this Machine"
    End With
End Sub

Private Sub master_Change()
    SelectAll master.Name
End Sub

请注意,事件处理程序的生命周期将是您存储master所在类的生命周期。如果您需要&#34;重新连接&#34;在工作簿关闭后,您需要在Workbook_Open或其他处理程序中执行此操作,这些处理程序将在可访问复选框之前触发。如果是这样,那么创建一个简单的包装类可能会更好:

'In a class module named CheckboxWrapper.
Private WithEvents m_wrapped As MSForms.CheckBox

Public Property Get WrappedCheckBox() As MSForms.CheckBox
    Set WrappedCheckBox = m_wrapped
End Property

Public Sub GenerateCheckbox(cbNum As Integer, cbIdent As String, Rng As Range)
    Set m_wrapped = Rng.Parent.OLEObjects.Add(ClassType:="Forms.CheckBox.1", _
                    Left:=1033.5, Top:=Rng.Top, Width:=150.5, Height:=20.75).Object

    With m_wrapped
        If cbNum < 10 Then
            .Name = "NewCheckBox" & cbIdent & "0" & cbNum
        Else
            .Name = "NewCheckBox" & cbIdent & cbNum
        End If
        .Object.Caption = "Select all for this Machine"
    End With
End Sub

Private Sub m_wrapped_Change()
    SelectAll master.Name
End Sub

您可以使用以下内容:

Private checkboxes As Collection

Private Sub Workbook_Open()
    Dim ole As OLEObject
    For Each ole In Sheet1.OLEObjects   'Or whatever sheet they're on
        If TypeName(cbx) = "CheckBox" Then
            Dim cbx As CheckboxWrapper
            Set cbx = New CheckboxWrapper
            Set cbx.WrappedCheckBox = ole.Object
            checkboxes.Add cbx
        End If
    Next
End Sub