在重新选择时清除级联的ComboBox

时间:2015-10-18 11:44:22

标签: excel vba excel-vba combobox userform

我正在使用多个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) 

我怀疑这是因为明确在技术上是一种变化,因此它无法根据空值将值列表转换为其他框。

1 个答案:

答案 0 :(得分:2)

这将清除所有后续的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

cascade