Hay un fácil (one-liner) para buscar una cadena dentro de una matriz en VBA? O tengo un bucle a través de cada elemento y se compara con la cadena de destino?

EDITAR:
Es una matriz unidimensional. Sólo necesito saber SI una cadena que está en algún lugar en la matriz.

Es decir:

names(JOHN, BOB, JAMES, PHLLIP)

¿Cómo puedo saber si «JUAN» está en la matriz, debe ser mínimo, ya que se repite alrededor de 5000 veces y no quiero que la función de frenar el proceso general hacia abajo.

  • Cuántas dimensiones?
  • ¿Solo quiero saber si la cadena es uno de los elementos de la matriz? O quiere que el índice del elemento coincidente?

9 Comentarios

  1. 64

    Si quieres saber si la cadena se encuentra en la matriz, pruebe esta función:

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

    Como Sean Cheshire señala, este debe ser un 1-D de la matriz.

    Ejemplo:

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

    (A continuación el código actualizado basado en el comentario de HansUp)

    Si quieres el índice del elemento coincidente en la matriz, intente esto:

    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

    Esto también supone un 1-D de la matriz. Tenga en cuenta LBound y UBound está basado en cero para un índice de 2 significa que el tercer elemento, no el segundo.

    Ejemplo:

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

    Si usted tiene un ejemplo específico en mente, por favor, actualice su pregunta, en caso contrario ejemplo de código podría no aplicarse a su situación.

    • La segunda versión de IsInArray devuelve 0 si stringToBeFound no se encuentra en arr.
    • Lo sé, pero ¿qué sugiere usted?
    • Yo podría asignar un valor, tales como -1, que no podría ser devuelto por UBound() de un no-matriz vacía. Dim lngReturn As Long; lngReturn = -1 Si stringToBeFound se encuentra: lngReturn = i Finalmente, IsInArray = lngReturn
    • Tienes razón, pero yo simplemente podría eliminar toda la sección de código como el OP no lo quiere de todos modos 🙂
    • Tenga en cuenta que recibirá un error si el array está vacío. Véase también stackoverflow.com/questions/206324/…
    • +1 buen post JP. El filtro es muy rara vez se utiliza.
    • La comprobación de matrices vacías deben ser encapsulado en una función diferente.

  2. 23

    Otra opción sería usar un diccionario en lugar de una matriz:

    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

    Como este sería entonces obtener una línea de

    oNames.Exists("JOHN")

    La ventaja de un diccionario ofrece es la coincidencia exacta sobre la parcial coincidencia de Filter. Dicen que si tienes el original de la lista de nombres en una Matriz, pero estaban buscando «JO» o «PHIL» que en realidad eran dos personas nuevas, además de los cuatro que hemos empezado. En este caso, Filter(oNAMES, "JO") coincidirá con «JOHN», que puede no ser deseado. Con un diccionario, no.

    • perfecto para mi propósito!
  3. 7

    hay una función que devolverá un matriz de todas las cadenas que se encuentran.

    Filter(sourcearray, match[, include[, compare]])

    El sourcearray tiene que ser 1 dimensiones

    La función devolverá todas las cadenas en la matriz que tiene el match cadena en ellos

  4. 5

    más simple de la Función whichs trabaja en Apple OS demasiado:

    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
    • Creo que tienes que hacer Dim element antes de que el bucle For (al menos, si usted tiene la Opción Explícita, que se debe.
    • gracias, he añadido
  5. 4

    Aquí otra respuesta. Funciona rápido, fiable (ver atomicules’ respuesta) y ha compacto código de llamada:

    ' 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

    El ejemplo de uso:

    Sub test()
        Debug.Print "Is 'A' in the list?", IsInArray(Split("A,B", ","), "A")
    End Sub
  6. 1

    Si es una lista de constantes, a continuación, puede utilizar Select Case de la siguiente manera:

    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
  7. 1

    Un Case instrucción puede satisfacer algunas de las aplicaciones más simplemente:

    select case var
    case "a string", "another string", sVar
      'do something
    case else
      'do something else
    end select
  8. 0

    Puede utilizar el siguiente sin la función de contenedor, pero proporciona una API bastante mejor:

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

    La Filter función tiene la siguiente firma:

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

Dejar respuesta

Please enter your comment!
Please enter your name here