匹配字符串数组中的值

Dav*_*ens 17 arrays excel vba excel-vba data-structures

问题:寻找一种更有效的方法来查找1d数组中是否存在精确匹配值 - 本质上是一个布尔值true/false.

我忽略了一些明显的东西吗 或者我只是使用错误的数据结构,当我可能应该使用集合对象或字典时使用数组?在后者中,我可以分别检查.Contains.Exists方法

在Excel中,我可以检查向量数组中的值,如:

If Not IsError(Application.Match(strSearch, varToSearch, False)) Then
' Do stuff
End If
Run Code Online (Sandbox Code Playgroud)

这将返回一个精确的匹配索引,显然受到Match函数的限制,该函数仅在此上下文中找到第一个匹配值.这是一种常用的方法,也是我长期使用的方法.

这对Excel来说足够令人满意 - 但其他应用程序呢?

在其他应用程序中,我基本上可以做同样的事情,但需要启用Excel对象库的引用,然后:

   If Not IsError(Excel.Application.match(...))
Run Code Online (Sandbox Code Playgroud)

但这看起来很愚蠢,并且由于权限/信任中心/等原因而难以管理分布式文件.

我试过使用Filter()函数:

 If Not Ubound(Filter(varToSearch, strSearch)) = -1 Then
    'do stuff
 End If
Run Code Online (Sandbox Code Playgroud)

但是这种方法的问题是Filter返回部分匹配的数组,而不是完全匹配的数组.(我不知道为什么返回子串/部分匹配会有用.)

另一种选择是逐字迭代数组中的每个值(我认为这也是非常常用的) - 这似乎比调用Excel的Match函数更加麻烦.

For each v in vArray
   If v = strSearch Then
    ' do stuff
   End If
Next
Run Code Online (Sandbox Code Playgroud)

Tim*_*ams 30

如果我们要讨论性能,那么运行一些测试就没有任何代价.根据我的经验,Application.Match()比调用使用循环的函数慢十倍.

Sub Tester()

    Dim i As Long, b, t
    Dim arr(1 To 100) As String

    For i = 1 To 100
        arr(i) = "Value_" & i
    Next i

    t = Timer
    For i = 1 To 100000
        b = Contains(arr, "Value_50")
    Next i
    Debug.Print "Contains", Timer - t

    t = Timer
    For i = 1 To 100000
        b = Application.Match(arr, "Value_50", False)
    Next i
    Debug.Print "Match", Timer - t

End Sub


Function Contains(arr, v) As Boolean
Dim rv As Boolean, lb As Long, ub As Long, i As Long
    lb = LBound(arr)
    ub = UBound(arr)
    For i = lb To ub
        If arr(i) = v Then
            rv = True
            Exit For
        End If
    Next i
    Contains = rv
End Function
Run Code Online (Sandbox Code Playgroud)

输出:

Contains       0.8710938 
Match          4.210938 
Run Code Online (Sandbox Code Playgroud)

  • 如果数组已作为 VBA 数组存在,则数组方法比使用 .MATCH 更快,因为每次调用 .MATCH 都会导致将数组传输到 .MATCH 可以处理的对象的大量开销。如果数据是 Excel 范围,则使用 .MATCH 会快得多(避免数据转换开销) (2认同)