Как искать строку в массиве
Есть ли простой (однострочный) для поиска строки в массиве в VBA? Или мне нужно прокрутить каждый элемент и сравнить его с целевой строкой?
EDIT:
Это одномерный массив. Мне нужно знать только, если строка находится где-то в массиве.
IE:
names(JOHN, BOB, JAMES, PHLLIP)
Как узнать, находится ли "JOHN" в массиве, он должен быть минимальным, поскольку он будет повторяться около 5000 раз, и я не хочу, чтобы функция замедляла общий процесс.
Ответы
Ответ 1
Если вы хотите узнать, найдена ли строка в массиве вообще, попробуйте эту функцию:
Function IsInArray(stringToBeFound As String, arr As Variant) As Boolean
IsInArray = (UBound(Filter(arr, stringToBeFound)) > -1)
End Function
Как Шон Чешир указывает, что это должен быть 1-мерный массив.
Пример:
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
Это также предполагает 1-мерный массив. Имейте в виду, что LBound и UBound основаны на нуле, поэтому индекс 2 означает третий элемент, а не второй.
Пример:
Sub Test()
Dim arr As Variant
arr = Split("abc,def,ghi,jkl", ",")
Debug.Print (IsInArray("ghi", arr) > -1)
End Sub
Если у вас есть конкретный пример, пожалуйста, обновите свой вопрос, иначе код примера может не соответствовать вашей ситуации.
Ответ 2
Другим вариантом будет использование словаря вместо массива:
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", который может быть нежелательным. Со словарем он не будет.
Ответ 3
Другой вариант, который обеспечивает точное сопоставление (то есть без частичного совпадения), будет:
Function IsInArray(stringToBeFound As String, arr As Variant) As Boolean
IsInArray = Not IsError(Application.Match(stringToBeFound, arr, 0))
End Function
Вы можете больше узнать о методе Match и его аргументах в
http://msdn.microsoft.com/en-us/library/office/ff835873(v=office.15).aspx
Ответ 4
есть функция, которая будет возвращать массив всех найденных строк.
Filter(sourcearray, match[, include[, compare]])
Исходный массив должен быть одномерным
Функция вернет все строки в массиве, в которых есть строка match
Ответ 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
Ответ 6
Вот еще один ответ. Он работает быстро, надежно (см. Ответ атомников) и имеет компактный код вызова:
' 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
Ответ 7
Если это список констант, вы можете использовать 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
Ответ 8
Оператор A Case
может несколько упростить некоторые приложения:
select case var
case "a string", "another string", sVar
'do something
case else
'do something else
end select
Ответ 9
Вы можете использовать следующее без функции-оболочки, но она предоставляет более приятный 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])