【问题标题】:Clear cascading ComboBox on reselection重新选择时清除级联组合框
【发布时间】:2019-10-19 21:45:24
【问题描述】:

我正在创建一个使用多个 ComboBox 的 excel 用户表单。第一个 ComboBox 列出了表格第 1 列中的值,下面的 ComboBox' 列出了以下列中的值。从 ComboBox 2 开始,也只根据前面的框列出值。所有 ComboBox' 仅显示唯一值。

这是我正在使用的当前代码:

Option Explicit
Private Sub ComboBox1_Change()
    Call cValues(ComboBox1.Value, ComboBox2, 2)
End Sub
Private Sub ComboBox2_Change()
    Call cValues(ComboBox2.Value, ComboBox3, 3)
End Sub
Private Sub ComboBox3_Change()
    Call cValues(ComboBox3.Value, ComboBox4, 4)
End Sub
Private Sub ComboBox4_Change()
    Call cValues(ComboBox4.Value, ComboBox5, 5)
End Sub
Private Sub ComboBox5_Change()
    Call cValues(ComboBox5.Value, ComboBox6, 6)
End Sub

Private Sub UserForm_Initialize()
    Dim Rng         As Range
    Dim Dn          As Range
    Dim Dic         As Object
    With Sheets("Listuni")
        Set Rng = .Range(.Range("A2"), .Range("A" & Rows.Count).End(xlUp))
    End With
    Set Dic = CreateObject("scripting.dictionary")
    Dic.CompareMode = vbTextCompare

    For Each Dn In Rng: Dic(Dn.Value) = Empty: Next
    Me.ComboBox1.List = Application.Transpose(Dic.keys)
End Sub

Sub cValues(txt As String, Obj As Object, col As Integer)
    Dim Dn              As Range
    Dim Rng             As Range
    Dim Dic             As Object
    With Sheets("Listuni")
        Set Rng = .Range(.Cells(2, col), .Cells(Rows.Count, col).End(xlUp))
    End With
    Set Dic = CreateObject("Scripting.Dictionary")
    Dic.CompareMode = 1

    For Each Dn In Rng
        If Dn.Offset(, -1).Value = txt Then
            If Not Dic.exists(Dn.Value) Then
                Dic(Dn.Value) = Empty
            End If
        End If
    Next Dn
    Obj.List = Application.Transpose(Dic.keys)
End Sub

当用户重新选择前面的 ComboBox 时,会出现我遇到的问题。不会清除后续框,而是保留所有现有选择。

每次重新选择前面的 ComboBox 时,我都在寻找一种方法来清除/默认后续 ComboBox 的值。例如,如果我在 ComboBox 1 和 2 中进行了选择,然后在 ComboBox 1 中更改了我的选择,我希望 ComboBox 2 清除而不是显示我之前的选择。请注意,用户表单在启动时的默认位置在任何 ComboBox 中都没有显示任何值。

我曾尝试使用 .clear 方法进行更改,但这总是挂在:

Obj.List = Application.Transpose(Dic.keys) 

我怀疑这是因为清除在技术上是一种更改,因此它不能根据空值将值列表转置到其他框。

【问题讨论】:

    标签: vba excel combobox userform


    【解决方案1】:

    这会清除所有后续的 ComboBox - 如果 Combo1 更改,则清除 Combo2、3、4、5 和 6

    Option Explicit
    
    Private ws  As Worksheet
    Private d   As Object
    
    Private Sub UserForm_Initialize()
        Dim cel As Range, txt As String, rng As Range
    
        Set ws = Worksheets("Listuni")
        Set d = CreateObject("Scripting.Dictionary"): d.CompareMode = vbTextCompare
    
        Set rng = ws.Range(ws.Cells(2, 1), ws.Cells(ws.Rows.Count, 1).End(xlUp))
    
        For Each cel In rng: d(cel.Value) = Empty: Next
        ComboBox1.List = Application.Transpose(d.keys)
    End Sub
    
    Private Function setList(ByVal txt As String, ByRef cmb As ComboBox) As Object
        Dim xID As Long, rng As Range, cel As Range, x As Control
    
        xID = Right(cmb.Name, 1)
        For Each x In Me.Controls
            If TypeName(x) = "ComboBox" Then If Val(Right(x.Name, 1)) > xID - 1 Then x.Clear
        Next
    
        Set rng = ws.Range(ws.Cells(2, xID), ws.Cells(ws.Rows.Count, xID).End(xlUp))
    
        d.RemoveAll
        For Each cel In rng
            If cel.Offset(, -1) = txt Then
                If Not d.exists(cel.Value) Then
                    d(cel.Value) = Empty
                End If
            End If
        Next
        If d.Count > 0 Then cmb.List = Application.Transpose(d.keys) Else cmb.Clear
    End Function
    
    Private Sub ComboBox1_Change()
        setList ComboBox1.Value, ComboBox2
    End Sub
    Private Sub ComboBox2_Change()
        setList ComboBox2.Value, ComboBox3
    End Sub
    Private Sub ComboBox3_Change()
        setList ComboBox3.Value, ComboBox4
    End Sub
    Private Sub ComboBox4_Change()
        setList ComboBox4.Value, ComboBox5
    End Sub
    Private Sub ComboBox5_Change()
        setList ComboBox5.Value, ComboBox6
    End Sub
    

    【讨论】:

    • 嗨,谢谢。试了一下,ComboBox 1 按预期列出了值。做出选择后,我遇到了运行时错误“类型不匹配”。表格中的所有数据都是文本数据。
    • Debug 将我带到 Private Function setList 代码中的第一个“Next”
    • 刚刚检查过,代码没有显示错误,但是出现了另一个问题。如果我要从 ComboBox1 中选择一个值,那么 ComboBox 2 只列出 b 列中的第一个对应值。在我的例子中,从第 1 列到第 2 列有许多不同的关联值。例如,如果我在第一个 ComboBox 中选择 USA,我希望在 ComboBox 2 中查看与美国相对应的所有不同状态,因为它们列在 B 列中的电子表格。如果我将 ComboBox 1 中的选择更改为 UK,则 ComboBox 2 应列出英国境内 ComboBox 2 中的所有城市,依此类推。
    • 感谢您的帮助!是的,我按预期在另一个 ComboBox' 中发布了转置和列出的值的初始代码。刚刚在重选清除时被赶上
    • 这正在工作,但还有一个例外(对不起!)。 ComboBox 2 及以后的版本现在列出了所有包含许多重复项的值。有没有办法只显示 ComboBox 1 中的唯一值?
    猜你喜欢
    • 2012-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-31
    • 2017-10-24
    • 1970-01-01
    • 2021-12-05
    相关资源
    最近更新 更多