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