【问题标题】:A checkbox that refers to itself in Excel VBA在 Excel VBA 中引用自身的复选框
【发布时间】:2015-07-24 05:26:27
【问题描述】:

我有一个 Excel 电子表格,它将单元格的值设置为组中复选框的数量。我想为每个看起来像这样的宏分配一个宏:

Sub clickedBox()
    If thisBox(or however you would do it).Checked = True Then
        Range("D9").Value = Range("D9").Value + 1
    Else
        Range("D9").Value = Range("D9").Value - 1
    End If
End Sub

单元格默认为 0,所有框默认为未选中。这样一来,勾选一个盒子会增加计数,取消勾选它会将其击倒一个,并且它永远不会低于零或高于盒子的数量。

我意识到我也应该这样做,以便宏在复选框的状态发生变化时触发,不仅是在单击它时,而且我想首先确保这是可能的。

有没有办法让复选框像这样引用自己?

【问题讨论】:

  • 复选框在哪里?在用户窗体上还是工作表上的 ActiveX 控件?
  • ActiveX 控件,理想情况下

标签: excel vba


【解决方案1】:

这真的取决于您是绑定到 ActiveX 控件还是表单控件。任何一个都可以工作,并且任何一个路径都可能指导如何清楚地实施它。

使用 ActiveX 控件(复选框):

您有两种选择来编写 ActiveX 控件的“单击处理程序”。第一个是为每个控件硬编码一个公共子:

控制Thisworkbook.Sheets("Sheet1"): CheckBox1

Excel对象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

如果您有十个复选框,那么您将有十个CheckBox(x)_Click 子,每个子都专门绑定到一个 ActiveX 控件。这些点击处理程序中的每一个都可以增加或减少存储在工作表单元格(或模块私有变量)中的计数器。

第二个选项是创建一个类模块,您可以为任意数量的 CheckBox 实例化它。

类模块代码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

常规代码模块中的代码:

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

使用表单控件(复选框):

虽然有多种方法可以捕获表单复选框的点击事件,但最简单的方法是将组中的所有复选框连接到单个宏:

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

这两种解决方案都可以通过多种方式进行调整,具体取决于您的需求以及您希望如何跟踪复选框。

【讨论】:

  • 太棒了,感谢您的建议!我想我将使用表单控件并制作一个 WinForms 应用程序。这正是我想要的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-11-01
  • 1970-01-01
  • 2011-08-29
  • 1970-01-01
  • 2020-05-20
  • 2013-10-23
  • 2016-06-25
相关资源
最近更新 更多