48

是否有一个简单的(单行)在 VBA 的数组中搜索字符串?还是我需要遍历每个元素并将其与目标字符串进行比较?

编辑:它是一个一维数组。我只需要知道一个字符串是否在数组中的某个位置。

IE:

names(JOHN, BOB, JAMES, PHLLIP)

如何确定“JOHN”是否在数组中,它需要最小,因为它将重复大约 5000 次,我不希望该函数减慢整个过程。

4

11 回答 11

79

如果你想知道是否在数组中找到了字符串,试试这个函数:

Function IsInArray(stringToBeFound As String, arr As Variant) As Boolean
  IsInArray = (UBound(Filter(arr, stringToBeFound)) > -1)
End Function

正如SeanC 所指出的,这必须是一维数组。

例子:

Sub Test()
  Dim arr As Variant
  arr = Split("abc,def,ghi,jkl", ",")
  Debug.Print IsInArray("ghi", arr)
End Sub

(以下代码根据HansUp的评论更新)

如果你想要数组中匹配元素的索引,试试这个:

Function IsInArray(stringToBeFound As String, arr As Variant) As Long
  Dim i As Long
  ' default return value if value not found in array
  IsInArray = -1

  For i = LBound(arr) To UBound(arr)
    If StrComp(stringToBeFound, arr(i), vbTextCompare) = 0 Then
      IsInArray = i
      Exit For
    End If
  Next i
End Function

这也假设一个一维数组。请记住 LBound 和 UBound 是从零开始的,因此索引 2 表示第三个元素,而不是第二个。

例子:

Sub Test()
  Dim arr As Variant
  arr = Split("abc,def,ghi,jkl", ",")
  Debug.Print (IsInArray("ghi", arr) > -1)
End Sub

如果您有一个特定的示例,请用它更新您的问题,否则示例代码可能不适用于您的情况。

于 2012-06-08T16:31:36.577 回答
31

另一种选择是使用字典而不是数组:

Dim oNames As Object
Set oNames = CreateObject("Scripting.Dictionary")
'You could if need be create this automatically from an existing Array
'The 1 is just a dummy value, we just want the names as keys
oNames.Add "JOHN", 1
oNames.Add "BOB", 1
oNames.Add "JAMES", 1
oNames.Add "PHILIP", 1

因为这会给你一个单行

oNames.Exists("JOHN")

字典提供的优势是精确匹配而不是部分匹配Filter。假设您有一个数组中的原始名称列表,但正在寻找“JO”或“PHIL”,除了我们开始的四个人之外,他们实际上是两个新人。在这种情况下,Filter(oNAMES, "JO")将匹配可能不需要的“JOHN”。用字典,它不会。

于 2014-04-15T12:00:21.183 回答
14

另一个强制精确匹配(即没有部分匹配)的选项是:

Function IsInArray(stringToBeFound As String, arr As Variant) As Boolean
  IsInArray = Not IsError(Application.Match(stringToBeFound, arr, 0))
End Function

您可以在http://msdn.microsoft.com/en-us/library/office/ff835873(v=office.15).aspx阅读有关 Match 方法及其参数的更多信息

于 2014-06-02T01:46:51.477 回答
7

有一个函数将返回找到的所有字符串的数组

Filter(sourcearray, match[, include[, compare]])
sourcearray 必须是一维
的 该函数将返回数组中包含match字符串的所有字符串

于 2012-06-08T15:48:52.383 回答
5

这是另一个答案。它工作快速、可靠(参见 atomicules 的回答)并具有紧凑的调用代码:

' Returns true if item is in the array; false otherwise.
Function IsInArray(ar, item$) As Boolean
    Dim delimiter$, list$

    ' Chr(7) is the ASCII 'Bell' Character.
    ' It was chosen for being unlikely to be found in a normal array.
    delimiter = Chr(7)

    ' Create a list string containing all the items in the array separated by the delimiter.
    list = delimiter & Join(ar, delimiter) & delimiter

    IsInArray = InStr(list, delimiter & item & delimiter) > 0
End Function

示例用法:

Sub test()
    Debug.Print "Is 'A' in the list?", IsInArray(Split("A,B", ","), "A")
End Sub
于 2015-04-15T03:54:00.533 回答
5

更简单的功能也适用于 Apple OS:

Function isInArray(ByVal stringToBeFound As String, ByVal arr As Variant) As Boolean
Dim element
For Each element In arr
    If element = stringToBeFound Then
        isInArray = True
        Exit Function
    End If
Next element
End Function
于 2014-06-17T07:57:34.473 回答
2

这是我的代码,灵感来自@atomicules

Public Function IsName(name As String) As Boolean
  Dim names As Object
  Set names = CreateObject("System.Collections.ArrayList")

  names.Add "JOHN"
  names.Add "BOB"
  names.Add "JAMES"
  names.Add "PHLLIP"
  
  IsName = names.Contains(name)
    
End Function

这是用法:

If IsName("JOHN") Then ...
于 2021-08-04T13:08:05.340 回答
1

如果它是一个常量列表,那么您可以使用 Select Case,如下所示:

Dim Item$: Item = "A"

Select Case Item
  Case "A", "B", "C"
    ' If 'Item' is in the list then do something.
  Case Else
    ' Otherwise do something else.
End Select
于 2015-04-15T04:19:25.557 回答
1

完成对 Jimmy Pena 接受的答案的评论

正如SeanC 所指出的,这必须是一维数组。

以下示例调用演示了该IsInArray()函数不能仅对1-dim数组调用,也用于“平面”2-dim数组:

Sub TestIsInArray()
    Const SearchItem As String = "ghi"
    Debug.Print "SearchItem = '" & SearchItem & "'"
    '----
    'a) Test 1-dim array
    Dim Arr As Variant
    Arr = Split("abc,def,ghi,jkl", ",")
    Debug.Print "a) 1-dim array " & vbNewLine & "   " & Join(Arr, "|") & " ~~> " & IsInArray(SearchItem, Arr)
    '----
    
        '//quick tool to create a 2-dim 1-based array
        Dim v As Variant, vals As Variant                                       
        v = Array(Array("abc", "def", "dummy", "jkl", 5), _
                  Array("mno", "pqr", "stu", "ghi", "vwx"))
        v = Application.Index(v, 0, 0)  ' create 2-dim array (2 rows, 5 cols)
    
    'b) Test "flat" 2-dim arrays
    Debug.Print "b) ""flat"" 2-dim arrays "
    Dim i As Long
    For i = LBound(v) To UBound(v)
        'slice "flat" 2-dim arrays of one row each
        vals = Application.Index(v, i, 0)
        'check for findings
        Debug.Print Format(i, "   0"), Join(vals, "|") & " ~~> " & IsInArray(SearchItem, vals)
    Next i
End Sub
Function IsInArray(stringToBeFound As String, Arr As Variant) As Boolean
'Site: https://stackoverflow.com/questions/10951687/how-to-search-for-string-in-an-array/10952705
'Note: needs a "flat" array, not necessarily a 1-dimensioned array
  IsInArray = (UBound(Filter(Arr, stringToBeFound)) > -1)
End Function

VB 编辑器的即时窗口中的结果

SearchItem = 'ghi'
a) 1-dim array 
   abc|def|ghi|jkl ~~> True
b) "flat" 2-dim arrays 
   1          abc|def|dummy|jkl|5         False
   2          mno|pqr|stu|ghi|vwx         True
于 2021-02-22T10:12:48.730 回答
0

您可以在没有 wrapper 函数的情况下使用以下内容,但它提供了更好的 API:

Function IsInArray(ByVal findString as String, ByVal arrayToSearch as Variant) as Boolean
  IsInArray = UBound(Filter(arrayToSearch,findString)) >= 0
End Function

Filter函数具有以下签名:

Filter(sourceArray, stringToMatch, [Include As Boolean = True], [Compare as VbCompareMethod = vbBinaryCompare])

于 2019-10-04T17:52:29.883 回答
0

声明可能更Case简单地适合某些应用程序:

select case var
case "a string", "another string", sVar
  'do something
case else
  'do something else
end select
于 2017-06-10T22:39:42.177 回答