【问题标题】:code multiple comboboxes on excel userform在 Excel 用户窗体上编写多个组合框
【发布时间】:2016-07-24 06:30:47
【问题描述】:

我有一个包含多个相关组合框的用户表单。我想将以下代码添加到 10 个 Comboboxes Change 事件中。要编码的 Combobox 编号为 11 到 20(Combobox11、Combobox 12 等),而依赖的 Combobox 编号为 21 到 30。

我可以复制粘贴代码10次,然后找到并替换相关的Combobox Nos。

有没有办法通过组合框使用循环来实现这一点? 任何帮助将不胜感激。

Private Sub ComboBox11_Change()

Dim index As Integer
index = ComboBox11.ListIndex
ComboBox21.Clear

Select Case index
    Case Is = 0
        With ComboBox21
            .RowSource = Range("SubCat1").Address(external:=True)
        End With

    Case Is = 1
        With ComboBox21
            .RowSource = Range("SubCat6").Address(external:=True)
        End With

    Case Is = 2
        With ComboBox21
            .RowSource = Range("SubCat7").Address(external:=True)
        End With

    Case Is = 3
        With ComboBox21
            .RowSource = Range("SubCat8").Address(external:=True)
        End With

    Case Is = 4
        With ComboBox21
            .RowSource = Range("SubCat9").Address(external:=True)
        End With

    'and several more case options

End Select

End Sub

【问题讨论】:

    标签: excel vba


    【解决方案1】:

    您可以使用 Class 模块和User_Init Sub 将用户表单中的每个 ComboBox 控件设置为此类。

    在我的代码中我使用Main_Form作为User_Form的名称,根据你的User_Form Name修改代码。

    添加一个调用模块,并在 Class 1 中添加以下代码:

    Public WithEvents ComboBoxEvents As MSForms.ComboBox
    
     ' anytime a Change event occurs to any ComboBox, the Sub is triggered
    Private Sub ComboBoxEvents_Change()
    
    Dim ComboBox_Index As String
    Dim index As Integer
    
        With ComboBoxEvents
            ' read the index of the ComboBox, as long as the names remain ComboBox1, ComboBox2, ComboBox3, etc...
            ComboBox_Index = Mid(.Name, 9)
    
            ' run this code if it's ComboBox 11 to 20
            If ComboBox_Index >= 11 And ComboBox_Index <= 20 Then
                index = .ListIndex
    
                Select Case index
                    Case Is = 0
                        With Main_Form.Controls("ComboBox" & ComboBox_Index + 10)
                            .RowSource = Range("SubCat1").Address(external:=True)
                        End With
    
                    Case Is = 1
                        With Main_Form.Controls("ComboBox" & ComboBox_Index + 10)
                            .RowSource = Range("SubCat6").Address(external:=True)
                        End With
    
                    Case Is = 2
                        With Main_Form.Controls("ComboBox" & ComboBox_Index + 10)
                            .RowSource = Range("SubCat7").Address(external:=True)
                        End With
    
                    Case Is = 3
                        With Main_Form.Controls("ComboBox" & ComboBox_Index + 10)
                            .RowSource = Range("SubCat8").Address(external:=True)
                        End With
    
                    Case Is = 4
                        With Main_Form.Controls("ComboBox" & ComboBox_Index + 10)
                            .RowSource = Range("SubCat9").Address(external:=True)
                        End With
    
                    'and several more case options
    
                End Select                
            End If
        End With
    
    End Sub
    

    您的 User_Form_Init 中包含以下代码(在我的代码中,User_Form 的名称是 Main-Form):

    Option Explicit
    
    Dim ComboBoxes() As New Class1
    
    Private Sub UserForm_Initialize()
    
        Dim ComboBoxCounter As Integer, Obj As Control
    
        For Each Obj In Me.Controls
            If TypeOf Obj Is MSForms.ComboBox Then
                ComboBoxCounter = ComboBoxCounter + 1
                ReDim Preserve ComboBoxes(1 To ComboBoxCounter)
                Set ComboBoxes(ComboBoxCounter).ComboBoxEvents = Obj
            End If
        Next Obj
    
        Set Obj = Nothing
    
    End Sub
    

    【讨论】:

    • 当您说代码进入您的 User_Form_Init 时,您的意思是 UserForm_Initialize 过程。我把代码放在那里,但是当我加载用户表单时,组合框中没有条目。
    • @willi 您需要将UserForm_Initialize 的原始代码添加到我上面的代码中,在Set Obj = Nothing 行之后,我清楚了吗?
    • 我将代码添加到 UserForm_ 初始化过程,但它不接受 Option Explicit 或 Dim 语句“ComboBoxCounter As Integer, Obj As Control”被放置在子名称上方。我错过了什么?我将离开办公室几天。
    • @willi 之前的代码你准备好了 Class 1 模块吗?
    • Shai,我已将用户窗体重命名为 Main_Form,插入了一个类模块并将您的代码复制到其中。然后我进入 Main_Form 初始化程序并将相关的代码复制到其中。然后我创建了一个子来加载和显示 Main_Form。但是当我点击复选框 21 到 30 时,它们是空的。我错过了什么吗?
    【解决方案2】:

    方式是使用类

    添加一个Class模块,并以“CmbBox”命名(你可以选择任何名称,但要保持一致)

    将以下代码添加到类代码窗格中:

    Option Explicit
    
    Public WithEvents Cmb As MSForms.ComboBox
    
    Private Sub Cmb_Change()
        Dim index As Long
    
        With Cmb
            index = .ListIndex
            With .Parent.Controls("ComboBox" & Mid(.Name, 9) + 10)
                .Clear
                Select Case index
                    Case 0
                        .RowSource = Range("SubCat1").Address(external:=True)
                    Case 1 To 4
                        .RowSource = Range("SubCat" & index + 5).Address(external:=True)
                End Select
            End With
        End With
    End Sub
    

    然后切换到您的用户窗体代码窗格并添加此代码:

    Dim Cmbs(1 To 10) As New CmbBox '<--| this must be at the very top of your userform code pane
    
    Sub Userform_Initialize()
        Dim i As Long
    
        With Me.Controls
            For i = 11 To 20
                Set Cmbs(i - 10).Cmb = .Item("ComboBox" & i)
            Next i
        End With
    End Sub
    

    就是这样

    【讨论】:

    • @willi:你试过这个解决方案吗?它很短 -> 可维护
    • @willi:你很高兴能向尝试帮助你的人提供反馈
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-26
    • 1970-01-01
    • 2017-04-07
    • 1970-01-01
    • 2018-09-27
    • 2020-11-13
    相关资源
    最近更新 更多