CobaltDev
CobaltDev

Reputation: 33

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. 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:

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.

How can I go about to doing this?

Upvotes: 1

Views: 1617

Answers (2)

Comintern
Comintern

Reputation: 22195

The easiest solution is to simply use Form Controls instead of ActiveX controls. That said...

The result of ActiveSheet.OLEObjects.Add is going to be an OLEObject that contains a MSForms.CheckBox as its .Object. It doesn't have an OnAction member.

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. 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

Upvotes: 0

user6432984
user6432984

Reputation:

ActiveX controls do not have an .OnAction method. FYI: Forms.CheckBox.1 refers to an MS Forms Checkbox not an Excel Forms Control.

Alternatively, you could use an 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. See my answer to Returning an index value from a group of ActiveX Option Buttons

Upvotes: 1

Related Questions