VBA:在每个循环中忽略条件

问题陈述

对于这些国家的一些国家和国家,我有一些相关的combobox。 我正在使用VBA在第一个combobox中填充唯一值,然后在第二个combobox中dynamic填充唯一值。 代码似乎在最初的传递中忽略了条件。

例如,代码适用于第一个国家:

在这里输入图像说明

但下列国家错误地保留了第一个国家的价值:

在这里输入图像说明

数据

这是数据集,名称为“国家”和“国家”。 这些名称与每个标题下方的范围dynamic对应:

在这里输入图像说明

名称引用使用以下格式的公式:

=OFFSET(Sheet1!$A$2,0,0,COUNTA(Sheet1!$A:$A),1) 

combobox是分别具有名称“国家”和“州”的ActiveX对象。

代码片段:

 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 

新南威尔士州的价值将被存储在所有以下添加国家的combobox中。

使用MsgBox在循环内部进行debugging:

  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 

似乎表明,在select澳大利亚以外的国家时,有条件的第一部分没有像预期的那样运作:

在这里输入图像说明

您可以使用与国家/地区相同的方法。 为什么不使用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 

尽pipe我不想看到NSW被排除在任何列表之外,但是可以通过在尝试执行Match之前testing您的arrvariables是否为空来解决您的问题:

 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,因此对UBound的testing将防止Match崩溃。