Подтвердить что ты не робот

Как искать строку в массиве

Есть ли простой (однострочный) для поиска строки в массиве в VBA? Или мне нужно прокрутить каждый элемент и сравнить его с целевой строкой?

EDIT: Это одномерный массив. Мне нужно знать только, если строка находится где-то в массиве.

IE:

names(JOHN, BOB, JAMES, PHLLIP)

Как узнать, находится ли "JOHN" в массиве, он должен быть минимальным, поскольку он будет повторяться около 5000 раз, и я не хочу, чтобы функция замедляла общий процесс.

4b9b3361

Ответ 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])