简体   繁体   English

如何将.OnAction用于ActiveX复选框

[英]How can I use .OnAction for an ActiveX Checkbox

I have a button that generates ActiveX checkboxes based on a range of cells that the user selects. 我有一个按钮,可根据用户选择的单元格范围来生成ActiveX复选框。 These checkboxes are linked to their corresponding cell. 这些复选框链接到其对应的单元格。 Additionally, a master checkbox is generated along with them that is intended to check/uncheck the rest of the checkboxes. 此外,还将生成一个主复选框,用于选中/取消选中其余复选框。

What I am trying to do is have an event occur when this master checkbox is checked and ends up checking the rest. 我想做的是,当选中此主复选框并最终检查其余复选框时,发生了一个事件。

I was thinking of something like this which is the creation of my Master Checkbox: 我在想这样的事情,那就是我的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

However, I am getting an error, stating that this is not supported. 但是,我收到一个错误,指出不支持此操作。 Essentially, I have another subprogram called SelectAll which ideally would be called when the master checkbox is clicked. 本质上,我还有另一个名为SelectAll的子程序,最好在单击主复选框时将其调用。

How can I go about to doing this? 我该怎么做呢?

ActiveX controls do not have an .OnAction method. ActiveX控件没有.OnAction方法。 FYI: Forms.CheckBox.1 refers to an MS Forms Checkbox not an Excel Forms Control. 仅供参考: Forms.CheckBox.1指的是MS Forms Checkbox,而不是Excel Forms Control。

Alternatively, you could use an Excel Forms Control: 或者,您可以使用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

Note: If you prefer to use ActiveX controls you could use a User Defined Class to group the COntrols events. 注意:如果您更喜欢使用ActiveX控件,则可以使用“用户定义的类”对COntrols事件进行分组。 See my answer to Returning an index value from a group of ActiveX Option Buttons 请参阅我关于从一组ActiveX选项按钮返回索引值的答案

The easiest solution is to simply use Form Controls instead of ActiveX controls. 最简单的解决方案是仅使用窗体控件而不是ActiveX控件。 That said... 那个...

The result of ActiveSheet.OLEObjects.Add is going to be an OLEObject that contains a MSForms.CheckBox as its .Object . ActiveSheet.OLEObjects.Add的结果将是一个包含MSForms.CheckBox作为其.ObjectOLEObject It doesn't have an OnAction member. 它没有OnAction成员。

It does, however, source automation events (it would be pretty worthless on a form without them). 但是,它确实会执行源自动化事件(如果没有它们,在表单上将毫无价值)。 That means you can grab a reference, store it, and handle its events: 这意味着您可以获取引用,进行存储并处理其事件:

'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

Note that the life-time of the event handler will be the life-time of whatever class you store master in. If you need to "re-wire" it after the workbook is closed, you'll need to do that in Workbook_Open or some other handler that will fire before the checkboxes are accessible. 请注意,事件处理程序的生命周期将是存储master的任何类的生命周期。如果在关闭工作簿后需要“重新连接”它,则需要在Workbook_Open或一些其他处理程序,这些处理程序将在可访问复选框之前触发。 If that's the case, it might be better to create a simple wrapper class: 如果是这种情况,最好创建一个简单的包装器类:

'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

You'd use it something like this: 您将使用如下所示的内容:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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