Excel 宏用户窗体 - 处理多个复选框的单个代码

Excel Macro Userform - single code handling multiple checkboxes

我有一个如下图所示的用户表单,带有标识级别和位置的命名约定(如图片上方的示例)。我也有下面的当前代码 - 但我还没有为每个 "Port" 复选框添加代码,最终我会 inserting/removing 一个特定于每个复选框的值到数组中基于他们是否 checked/un-checked.

我想了解以下内容:

我一直盯着这个看这么久,我有点脑残 - 我不确定我在这里问的问题是否正确,或者还有什么要问的。从本质上讲,我想避免一遍又一遍地重复几乎相同的事情(就像我现在所做的那样)。

Private Sub UserForm_Initialize()
Dim chBox As Control
Dim comboBox As Control
Dim arrFreq() As String
Dim i As Long


    'Use the Split function to create two zero based one dimensional arrays.
    arrFreq = Split("Unused|700|850|1900|2100", "|")
    For Each comboBox In ADSinputform.Controls
        If TypeOf comboBox Is MSForms.comboBox Then
            For i = 0 To UBound(arrFreq)
                'Use .List property to write array data to all the comboBoxes
                comboBox.List = arrFreq
            Next i
        End If
    Next
    'Empty NameTextBox
    SiteNameTextBox.Value = siteName


End Sub

Private Sub AlphaSectCheckbox_Click()

    If AlphaSectCheckbox.Value = True Then AlphaAnt_Frame.Visible = True
    If AlphaSectCheckbox.Value = False Then
        AlphaAnt_Frame.Visible = False
        For Each chBox In AlphaAnt_Frame.Controls
            If TypeOf chBox Is MSForms.CheckBox Then chBox.Value = False
        Next
    End If

End Sub

Private Sub BetaSectCheckbox_Click()

    If BetaSectCheckbox.Value = True Then BetaAnt_Frame.Visible = True
    If BetaSectCheckbox.Value = False Then
        BetaAnt_Frame.Visible = False
        For Each chBox In BetaAnt_Frame.Controls
            If TypeOf chBox Is MSForms.CheckBox Then chBox.Value = False
        Next
    End If

End Sub

Private Sub GammaSectCheckbox_Click()

    If GammaSectCheckbox.Value = True Then GammaAnt_Frame.Visible = True
    If GammaSectCheckbox.Value = False Then
        GammaAnt_Frame.Visible = False
        For Each chBox In GammaAnt_Frame.Controls
            If TypeOf chBox Is MSForms.CheckBox Then chBox.Value = False
        Next
    End If

End Sub

Private Sub DeltaSectCheckbox_Click()

    If DeltaSectCheckbox.Value = True Then DeltaAnt_Frame.Visible = True
    If DeltaSectCheckbox.Value = False Then
        DeltaAnt_Frame.Visible = False
        For Each chBox In DeltaAnt_Frame.Controls
            If TypeOf chBox Is MSForms.CheckBox Then chBox.Value = False
        Next
    End If

End Sub

Private Sub A1Checkbox_Click()

    If A1Checkbox.Value = True Then A1Port_Frame.Visible = True
    If A1Checkbox.Value = False Then
        A1Port_Frame.Visible = False
        For Each chBox In A1Port_Frame.Controls
            If TypeOf chBox Is MSForms.CheckBox Then chBox.Value = False
        Next
    End If

End Sub

Private Sub A2Checkbox_Click()

    If A2Checkbox.Value = True Then A2Port_Frame.Visible = True
    If A2Checkbox.Value = False Then
        A2Port_Frame.Visible = False
        For Each chBox In A2Port_Frame.Controls
            If TypeOf chBox Is MSForms.CheckBox Then chBox.Value = False
        Next
    End If

End Sub

Private Sub A3Checkbox_Click()

    If A3Checkbox.Value = True Then A3Port_Frame.Visible = True
    If A3Checkbox.Value = False Then
        A3Port_Frame.Visible = False
        For Each chBox In A3Port_Frame.Controls
            If TypeOf chBox Is MSForms.CheckBox Then chBox.Value = False
        Next
    End If

End Sub

Private Sub A4Checkbox_Click()

    If A4Checkbox.Value = True Then A4Port_Frame.Visible = True
    If A4Checkbox.Value = False Then
        A4Port_Frame.Visible = False
        For Each chBox In A4Port_Frame.Controls
            If TypeOf chBox Is MSForms.CheckBox Then chBox.Value = False
        Next
    End If

End Sub

Private Sub A5Checkbox_Click()

    If A5Checkbox.Value = True Then A5Port_Frame.Visible = True
    If A5Checkbox.Value = False Then
        A5Port_Frame.Visible = False
        For Each chBox In A5Port_Frame.Controls
            If TypeOf chBox Is MSForms.CheckBox Then chBox.Value = False
        Next
    End If

End Sub

Private Sub A6Checkbox_Click()

    If A6Checkbox.Value = True Then A6Port_Frame.Visible = True
    If A6Checkbox.Value = False Then
        A6Port_Frame.Visible = False
        For Each chBox In A6Port_Frame.Controls
            If TypeOf chBox Is MSForms.CheckBox Then chBox.Value = False
        Next
    End If

End Sub

Private Sub B1Checkbox_Click()

    If B1Checkbox.Value = True Then B1Port_Frame.Visible = True
    If B1Checkbox.Value = False Then
        B1Port_Frame.Visible = False
        For Each chBox In B1Port_Frame.Controls
            If TypeOf chBox Is MSForms.CheckBox Then chBox.Value = False
        Next
    End If

End Sub

Private Sub B2Checkbox_Click()

    If B2Checkbox.Value = True Then B2Port_Frame.Visible = True
    If B2Checkbox.Value = False Then
        B2Port_Frame.Visible = False
        For Each chBox In B2Port_Frame.Controls
            If TypeOf chBox Is MSForms.CheckBox Then chBox.Value = False
        Next
    End If

End Sub

Private Sub B3Checkbox_Click()

    If B3Checkbox.Value = True Then B3Port_Frame.Visible = True
    If B3Checkbox.Value = False Then
        B3Port_Frame.Visible = False
        For Each chBox In B3Port_Frame.Controls
            If TypeOf chBox Is MSForms.CheckBox Then chBox.Value = False
        Next
    End If

End Sub

Private Sub B4Checkbox_Click()

    If B4Checkbox.Value = True Then B4Port_Frame.Visible = True
    If B4Checkbox.Value = False Then
        B4Port_Frame.Visible = False
        For Each chBox In B4Port_Frame.Controls
            If TypeOf chBox Is MSForms.CheckBox Then chBox.Value = False
        Next
    End If

End Sub

Private Sub B5Checkbox_Click()

    If B5Checkbox.Value = True Then B5Port_Frame.Visible = True
    If B5Checkbox.Value = False Then
        B5Port_Frame.Visible = False
        For Each chBox In B5Port_Frame.Controls
            If TypeOf chBox Is MSForms.CheckBox Then chBox.Value = False
        Next
    End If

End Sub

Private Sub B6Checkbox_Click()

    If B6Checkbox.Value = True Then B6Port_Frame.Visible = True
    If B6Checkbox.Value = False Then
        B6Port_Frame.Visible = False
        For Each chBox In B6Port_Frame.Controls
            If TypeOf chBox Is MSForms.CheckBox Then chBox.Value = False
        Next
    End If

End Sub

Private Sub C1Checkbox_Click()

    If C1Checkbox.Value = True Then C1Port_Frame.Visible = True
    If C1Checkbox.Value = False Then
        C1Port_Frame.Visible = False
        For Each chBox In C1Port_Frame.Controls
            If TypeOf chBox Is MSForms.CheckBox Then chBox.Value = False
        Next
    End If

End Sub

Private Sub C2Checkbox_Click()

    If C2Checkbox.Value = True Then C2Port_Frame.Visible = True
    If C2Checkbox.Value = False Then
        C2Port_Frame.Visible = False
        For Each chBox In C2Port_Frame.Controls
            If TypeOf chBox Is MSForms.CheckBox Then chBox.Value = False
        Next
    End If

End Sub

Private Sub C3Checkbox_Click()

    If C3Checkbox.Value = True Then C3Port_Frame.Visible = True
    If C3Checkbox.Value = False Then
        C3Port_Frame.Visible = False
        For Each chBox In C3Port_Frame.Controls
            If TypeOf chBox Is MSForms.CheckBox Then chBox.Value = False
        Next
    End If

End Sub

Private Sub C4Checkbox_Click()

    If C4Checkbox.Value = True Then C4Port_Frame.Visible = True
    If C4Checkbox.Value = False Then
        C4Port_Frame.Visible = False
        For Each chBox In C4Port_Frame.Controls
            If TypeOf chBox Is MSForms.CheckBox Then chBox.Value = False
        Next
    End If

End Sub

Private Sub C5Checkbox_Click()

    If C5Checkbox.Value = True Then C5Port_Frame.Visible = True
    If C5Checkbox.Value = False Then
        C5Port_Frame.Visible = False
        For Each chBox In C5Port_Frame.Controls
            If TypeOf chBox Is MSForms.CheckBox Then chBox.Value = False
        Next
    End If

End Sub

Private Sub C6Checkbox_Click()

    If C6Checkbox.Value = True Then C6Port_Frame.Visible = True
    If C6Checkbox.Value = False Then
        C6Port_Frame.Visible = False
        For Each chBox In C6Port_Frame.Controls
            If TypeOf chBox Is MSForms.CheckBox Then chBox.Value = False
        Next
    End If

End Sub

Private Sub D1Checkbox_Click()

    If D1Checkbox.Value = True Then D1Port_Frame.Visible = True
    If D1Checkbox.Value = False Then
        D1Port_Frame.Visible = False
        For Each chBox In D1Port_Frame.Controls
            If TypeOf chBox Is MSForms.CheckBox Then chBox.Value = False
        Next
    End If

End Sub

Private Sub D2Checkbox_Click()

    If D2Checkbox.Value = True Then D2Port_Frame.Visible = True
    If D2Checkbox.Value = False Then
        D2Port_Frame.Visible = False
        For Each chBox In D2Port_Frame.Controls
            If TypeOf chBox Is MSForms.CheckBox Then chBox.Value = False
        Next
    End If

End Sub

Private Sub D3Checkbox_Click()

    If D3Checkbox.Value = True Then D3Port_Frame.Visible = True
    If D3Checkbox.Value = False Then
        D3Port_Frame.Visible = False
        For Each chBox In D3Port_Frame.Controls
            If TypeOf chBox Is MSForms.CheckBox Then chBox.Value = False
        Next
    End If

End Sub

Private Sub D4Checkbox_Click()

    If D4Checkbox.Value = True Then D4Port_Frame.Visible = True
    If D4Checkbox.Value = False Then
        D4Port_Frame.Visible = False
        For Each chBox In D4Port_Frame.Controls
            If TypeOf chBox Is MSForms.CheckBox Then chBox.Value = False
        Next
    End If

End Sub

Private Sub D5Checkbox_Click()

    If D5Checkbox.Value = True Then D5Port_Frame.Visible = True
    If D5Checkbox.Value = False Then
        D5Port_Frame.Visible = False
        For Each chBox In D5Port_Frame.Controls
            If TypeOf chBox Is MSForms.CheckBox Then chBox.Value = False
        Next
    End If

End Sub

Private Sub D6Checkbox_Click()

    If D6Checkbox.Value = True Then D6Port_Frame.Visible = True
    If D6Checkbox.Value = False Then
        D6Port_Frame.Visible = False
        For Each chBox In D6Port_Frame.Controls
            If TypeOf chBox Is MSForms.CheckBox Then chBox.Value = False
        Next
    End If

End Sub

复选框命名约定:

In "Sectors" frame: "AlphaSectCheckbox", "BetaSectCheckbox", "GammaSectCheckbox", "DeltaSectCheckbox" 

In "Antennas" frames: (Alpha) "A1Checkbox", "A2Checkbox", "A3Checkbox", etc / (Beta) "B1Checkbox", "B2Checkbox", "B3Checkbox", etc / (Gamma) "C1Checkbox", "C2Checkbox", "C3Checkbox", etc, etc 

In "Port" frames: (Alpha - Ant 1) "A1P1Checkbox", "A1P2Checkbox", etc / (Alpha - Ant 2) "A2P1Checkbox", "A2P2Checkbox", etc / (Beta - Ant1) "B1P1Checkbox", "B1P2Checkbox", etc / (Beta Ant2) "B2P1Checkbox", "B2P2Checkbox", etc / (Gamma - Ant1) "C1P1Checkbox", "C1P2Checkbox", etc, etc

=========================2016 年 1 月 11 日编辑 这是我在 sous2817 回答后实现的,效果很好,我可以从这里继续使用一小部分代码。这是一个名为 "clsUFCheckBox":

的新 Class 模块
Option Explicit

Public WithEvents aCheckBox As msforms.CheckBox

Private Sub aCheckBox_Click()
Dim chBox As Control
Dim actFrmStr As String

     MsgBox aCheckBox.Name & " was clicked" & vbCrLf & vbCrLf & _
        "It refers to the frame: " & aCheckBox.Tag & vbCrLf & vbCrLf & _
        "Its Checked State is currently " & aCheckBox.Value, vbInformation + vbOKOnly, _
        aCheckBox.Name & " & State"

    actFrmStr = aCheckBox.Tag

    If aCheckBox.Value = True Then ADSinputform.Controls(actFrmStr).Visible = True
    If aCheckBox.Value = False Then
        ADSinputform.Controls(actFrmStr).Visible = False
        For Each chBox In ADSinputform.Controls(actFrmStr).Controls
            If TypeOf chBox Is msforms.CheckBox Then chBox.Value = False
        Next
    End If

End Sub

您可以像这样调用处理函数,其中每个复选框只传递键字符串。 然后将所有类似的代码放入处理相关帧的处理函数中

Private Sub cbA1_Click()
     handleCB ("A1")
End Sub


Private Sub cbA2_Click()
    handleCB ("A2")
End Sub


Public Function handleCB(cb As String)

    Dim formObj As Control
    Set formObj = Me("cb" & cb)
    MsgBox formObj.Name & Chr(10) & formObj.Value

    'do code with the other controls that have the string cb in them
    'such as your frames etc

End Function

Change/click 事件应该不会太重要

这对于评论来说太长了,但希望它能让您接近(或至少开始)解决方案。

首先,将 class 添加到您的项目中。在这个例子中我调用的是clsUFCheckBox。将以下代码添加到 class:

Option Explicit

Public WithEvents aCheckBox As msforms.CheckBox

Private Sub aCheckBox_Click()
     MsgBox aCheckBox.Name & " was clicked" & vbCrLf & vbCrLf & _
        "Its Checked State is currently " & aCheckBox.Value, vbInformation + vbOKOnly, _
        "Check Box # & State"
End Sub

上面创建了一个点击事件,该事件将被触发到集合中的每个复选框(很快就会出现)。此测试代码将向您显示一个消息框,告诉您单击了哪个复选框以及当前状态。显然,您将更改它以适应解决当前问题所需的任何逻辑,但这将帮助您入门。

现在,在您的用户表单代码中,将这一行添加到顶部(就在您的 Option Explicit 行下方)

Dim myCheckBoxes() As clsUFCheckBox

这会创建一个 class 数组,其中包含您在上面创建的 class 以保存表单上的所有复选框。现在在您的 Userform_Initialize() 事件中,添加此代码:

Dim ctl As Object, pointer As Long
ReDim myCheckBoxes(1 To Me.Controls.Count)

    For Each ctl In Me.Controls
        If TypeName(ctl) = "CheckBox" Then
            pointer = pointer + 1
            Set myCheckBoxes(pointer) = New clsUFCheckBox
            Set myCheckBoxes(pointer).aCheckBox = ctl
        End If
    Next ctl

ReDim Preserve myCheckBoxes(1 To pointer)

此代码将遍历用户窗体上的所有控件,并将复选框添加到您在上面创建的数组中。此外,由于您将所有复选框与您创建的 class 相关联,因此您为它们提供了一个共同的点击事件。因此,您单击的每个复选框,运行 都是相同的单击事件。

好了。您在开始时创建的几十个复选框,它们都是 运行 相同的 _click() 事件。您可以在该单个事件中放置逻辑来处理每个分组。好处是,您只需编写一次代码,而不必将其添加到每个单独的 checkbox_click 事件中。

如果您需要测试工作簿以便查看所有内容,请告诉我,我会看看是否可以找到一个地方上传一个供您查看。

希望对您有所帮助。如果您卡住了,请 post 回来,我们会继续努力。