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

时间:2015-11-30 21:13:11

标签: excel excel-vba userform vba

我有一个类似下图的用户表单,其中有一个命名约定来识别级别&位置(如图片上方的例子)。我也有下面的当前代码 - 但我还没有为每个“端口”复选框添加代码,最终我将根据它们是否插入/删除特定于每个复选框的值到数组中检查/未选中。

我想了解以下内容:

  • 条件是基于检查还是取消选中复选框,通过阅读是否选中/取消选中(如下所示),或选择“更改”?

  • 我是否可以将表单上任何复选框的操作编码的次数缩短为一个(或几个)个案,而不是编写每一个(我最终会分配一个)根据检查(或未检查)的内容对数组赋值(或删除一个数组)?

  • 我可以将一个复选框的名称的一部分(比如前4个或6个字符)作为一个值来确定我在处理#2时可以处理的内容吗?

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

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

enter image description here

enter image description here

enter image description here

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

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

2 个答案:

答案 0 :(得分:2)

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

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

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

这会创建一个您在上面创建的类的数组,以保存表单上的所有复选框。现在,在您的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)

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

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

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

希望有所帮助。如果你被卡住了,请回发,我们会继续锤击它。

答案 1 :(得分:0)

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

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

更改/点击事件不应该太重要