使用VBA中的Application.Match检查项目是否存在于集合中

我有一个我为Excel编写的macros的代码有问题。

它具体涉及方法Application.Match或者Application.WorksheetFunction.Match

我有一个string数组,我将所有公司的名称存储在列表中

 Dim CompanyID() As String ReDim CompanyID(NumCO) For i = 1 To NumCO CompanyID(i) = Worksheets("Sheet1").Cells(i, 1).Value Next i 

然后我创build一个collections只包含所有不同的公司

 Dim DifCO As New Collection, a On Error Resume Next For Each a In CompanyID DifCO.Add a, a Next 

后来在我的代码中,我再次通过这些公司,将它们与某些属性相关联,为此我需要在Collection DifCO保存公司的索引。 但是,我一直无法得到它与Application.Match

我的程序似乎没有做任何事情,并certificate它我已经试图在MsgBox打印索引,但MsgBox不会出现,它甚至不会发送错误消息。

 For i to NumCO MsgBox (Application.WorksheetFunction.Match(CompanyID(i), DifCO, 0)) Next i 

我已经尝试了不同的事情,使用Application.Match和将集合的元素移动到另一个string的数组,但结果是相同的。

我知道代码循环正确,因为我已经在逐步debugging选项中观察到它。 但是我已经想出了什么可能是问题的想法,所以我在这里问这个社区。

正如Mat在OP上的注释中所表示的那样,它看起来像是使用了On Error Resume Next而没有On Error GoTo 0 ,所以处理程序正在吞咽错误,并且没有看到它,并且不显示MsgBox。

在debugging的时候,有一个选项可以Break on All Errors ,尽pipe在非常复杂的应用程序中它是一个非常痛苦的事情,因为像这样的事情会立即为你标记问题。 在工具>选项>常规下的VBE中:

在这里输入图像说明

通常,您希望避免Resume Next除非是非常小而有目的的错误陷阱。 让它像这样打开,势必会在你的代码中导致进一步的错误,这些错误很难排除(正如你注意到的那样)。

对于你的解决scheme,你可以使用一个ArrayList

 Dim list as Object Set list = CreateObject("System.Collections.ArrayList") For Each a In CompanyID If Not list.Contains(a) Then list.Add(a) Next 

然后,通过使用ToArray方法将ArrayList转储到variables数组,然后使用Application.Matchtesting该数组:

 Dim arr, foundAt arr = list.ToArray() For i = 1 To NumCO foundAt = Application.Match(CompanyID(i), arr, 0) If Not IsError(foundAt) Then MsgBox foundAt End If Next i 

否则,从集合或数组获取索引的通常方法就是对项目进行粗暴的迭代,最好是分离一个ad-hoc函数来完成这些工作,而不是使用额外的循环混淆主要过程:

 Sub collExample() Dim c As New Collection c.Add "9" c.Add "14" c.Add "3" c.Add "15" c.Add "4" c.Add "3" Debug.Print colItmExists(c, "5") '~~> False Debug.Print colItmExists(c, "10") '~~> True Debug.Print colItmFirstIndex(c, "3") '~~> 3 Debug.Print colItmFirstIndex(c, "17") '~~> -1 End Sub Function colItmExists(col As Collection, itm) As Boolean Dim i, ret As Boolean For i = 1 To col.Count If col(i) = itm Then ret = True Exit For End If Next colItmExists = ret End Function Function colItmFirstIndex(col As Collection, itm) As Long Dim ret As Long If Not colItmExists(col, itm) Then ret = -1 Else For i = 1 To col.Count If col(i) = itm Then ret = i Exit For End If Next End If colItmFirstIndex = ret End Function