A checkbox that refers to itself in Excel VBA

后端 未结 1 971
后悔当初
后悔当初 2021-01-23 01:54

I have an excel spreadsheet that sets a cell\'s value to the number of checked boxes in a group. I would like to assign a macro to each that looks like this:

Sub         


        
相关标签:
1条回答
  • 2021-01-23 02:29

    It really depends if you're tied into ActiveX controls or Form Controls. Either can work, and either path likely directs how to clearly implement it.

    Using ActiveX Controls (checkboxes):

    You have two options to code your "click handlers" for ActiveX controls. The first is hard-coding a public sub for each control:

    control on Thisworkbook.Sheets("Sheet1"): CheckBox1

    code in Excel Object Sheet1:

    Private groupCheckBoxCount As Integer
    
    Private Sub CheckBox1_Click()
        Debug.Print "Control on " & Me.Name & " is now " & Me.CheckBox1.Value
        RegisterCheckedValue Me.CheckBox1.Value
    End Sub
    
    Private Sub RegisterCheckedValue(cbVal As Boolean)
        If cbVal = True Then
            Range("CheckBoxCount") = Range("CheckBoxCount") + 1  'choose to store on the sheet
            groupCheckBoxCount = groupCheckBoxCount + 1          'or in a variable
        Else
            Range("CheckBoxCount") = Range("CheckBoxCount") - 1
            groupCheckBoxCount = groupCheckBoxCount - 1
        End If
    End Sub
    

    Then if you have ten checkboxes, you'll have ten CheckBox(x)_Click subs, each specifically tied to a single ActiveX control. Each of these click handlers can increment or decrement your counter in stored in a worksheet cell (or in a module private variable).

    The second option is to create a class module that you can instantiate for any number of CheckBoxes.

    code for class module MyCheckBoxClass

    Dim WithEvents cbControl As MSForms.CheckBox
    
    Private controlName As String
    
    Public Sub cbControl_Click()
        Debug.Print controlName & " is now " & cbControl.Value
        If cbControl.Value = True Then
            Range("CheckBoxCount") = Range("CheckBoxCount") + 1  'choose to store on the sheet
            groupCheckBoxCount = groupCheckBoxCount + 1          'or in a variable
        Else
            Range("CheckBoxCount") = Range("CheckBoxCount") - 1
            groupCheckBoxCount = groupCheckBoxCount - 1
        End If
    End Sub
    
    Public Sub Attach(newCB As MSForms.CheckBox, newName As String)
        Set cbControl = newCB
        controlName = newName
    End Sub
    
    Private Sub Class_Initialize()
        controlName = ""
    End Sub
    

    code in a regular code module:

    Public groupClickCount As Integer
    Private cbCollection As Collection
    
    Public Sub SetUpControlsOnce()
        Dim thisCB As MyCheckBoxClass
        Dim ctl As OLEObject
        Dim cbControl As MSForms.CheckBox
    
        If cbCollection Is Nothing Then
            Set cbCollection = New Collection
        End If
    
        For Each ctl In ThisWorkbook.Sheets("Sheet1").OLEObjects
            If TypeName(ctl.Object) = "CheckBox" Then
                '--- this is an ActiveX CheckBox
                Set thisCB = New MyCheckBoxClass
                thisCB.Attach ctl.Object, ctl.name
                cbCollection.Add thisCB
            End If
        Next ctl
    End Sub
    

    Using Form Controls (checkboxes):

    While there are several ways to catch the click event for a Form checkbox, the simplest is to connect ALL checkboxes in a group to a single macro:

    Public groupClickCount As Integer
    
    Public Sub cbControl_Click()
        '--- loop through all the controls on the form and filter for
        '    only checkboxes, then count up how many are checked
        Dim ctl As Shape
        Dim checkCount As Integer
        checkCount = 0
        For Each ctl In ActiveSheet.Shapes
            If ctl.Type = msoFormControl Then
                On Error Resume Next
                If ctl.ControlFormat = xlCheckBox Then
                    If ctl.ControlFormat.Value = 1 Then
                        checkCount = checkCount + 1
                    Else
                        checkCount = checkCount - 1
                    End If
                End If
            End If
        Next ctl
        Range("CheckBoxCount") = checkCount 'choose to store on the sheet
        groupClickCount = checkCount        'or in a variable
    End Sub
    

    Either solution can be adapted in many ways, depending on your needs and how you'd like to track your checkboxes.

    0 讨论(0)
提交回复
热议问题