问题陈述
我为这些国家/地区的某些国家和州提供了几个相关的组合框。我使用VBA在第一个组合框中填充唯一值,然后在第二个组合框中动态填充唯一值。代码似乎忽略了初始传递中的条件。
例如,代码适用于第一个国家/地区:
但是以下国家/地区错误地保留了第一个州值:
数据
这是数据集,名称"国家"和"州"。这些名称动态对应于每个标题下方的范围:
名称引用使用以下格式的公式:
=OFFSET(Sheet1!$A$2,0,0,COUNTA(Sheet1!$A:$A),1)
组合框是ActiveX对象,其名称为#34; countries"和"州"分别
代码
代码段:
Private Sub Worksheet_Activate()
'Populate combo box with unique countries.
Dim arr() As String
Dim tmp As String
Dim rng As Range
Dim ws As Worksheet
Set ws = Worksheets("Sheet1")
Me.countries.Clear
For Each rng In ws.Range("Country")
If (rng <> "") And (InStr(tmp, rng) = 0) Then
tmp = tmp & rng & "|"
End If
Next rng
If Len(tmp) > 0 Then tmp = Left(tmp, Len(tmp) - 1)
arr = Split(tmp, "|")
Me.countries.List = arr
End Sub
Private Sub countries_lostfocus()
'Populate dependent combo box with unique states
'according to selection in countries combo box.
Dim rng As Range
Dim ws As Worksheet
Dim str As String
Set ws = Worksheets("Sheet1")
str = countries.Value
Me.states.Clear
On Error Resume Next
For Each rng In ws.Range("State")
If ((rng.Offset(, -1).Value) = str) And (IsNotInArray(rng.Value, Me.states.List)) Then
Me.states.AddItem rng.Value
End If
Next rng
End Sub
Function IsNotInArray(stringToBeFound As String, arr As Variant) As Boolean
IsNotInArray = IsError(Application.Match(stringToBeFound, arr, 0))
End Function
杂
新州州的州值将存储在所有后续国家/地区的组合框中。
使用MsgBox在循环内调试:
For Each rng In ws.Range("State")
If ((rng.Offset(, -1).Value) = str) And (IsNotInArray(rng.Value, Me.states.List)) Then
MsgBox ("Country: " & str & "; check: " & rng.Offset(, -1).Value)
Me.states.AddItem rng.Value
End If
Next rng
似乎表明,在选择澳大利亚以外的国家时,条件的第一部分无法按预期运作:
答案 0 :(得分:2)
尽管我不希望新南威尔士州被排除在任何列表之外,但您可以通过在尝试执行arr
之前测试Match
变量是否为空来解决您的问题:
Function IsNotInArray(stringToBeFound As String, arr As Variant) As Boolean
If UBound(Arr) = -1 Then
IsNotInArray = True
Else
IsNotInArray = IsError(Application.Match(stringToBeFound, arr, 0))
End If
End Function
如果将arr
作为ComboBox的清除列表传递给该函数,则其LBound
为0且UBound
为-1,因此对{的测试{1}}会阻止UBound
崩溃。
答案 1 :(得分:1)
您可以使用与Country相同的方法。为什么不使用countries_Change
事件?
Option Explicit
Private Sub countries_Change()
Dim sCountry As String
Dim sList As String
Dim rng As Range
sCountry = Me.countries.Value
Me.states.Clear
With ThisWorkbook.Names("State")
For Each rng In .RefersToRange
If Not IsEmpty(rng) Then
If rng.Offset(0, -1).Value = sCountry Then
If InStr(1, sList, rng.Value, vbTextCompare) = 0 Then
If Len(sList) > 0 Then sList = sList & "|"
sList = sList & rng.Value
End If
End If
End If
Next
End With
Me.states.List = Split(sList, "|")
End Sub
Private Sub Worksheet_Activate()
Dim sList As String
Dim rng As Range
With ThisWorkbook.Names("Country")
For Each rng In .RefersToRange
If Not IsEmpty(rng) Then
If InStr(1, sList, rng.Value, vbTextCompare) = 0 Then
If Len(sList) > 0 Then sList = sList & "|"
sList = sList & rng.Value
End If
End If
Next
End With
Me.countries.List = Split(sList, "|")
countries_Change ' <-- This is better User experience
End Sub