38

I've got some code below, that is supposed to be checking if a value is in an Array or not.

Sub test()
    vars1 = Array("Examples")
    vars2 = Array("Example")
    If IsInArray(Range("A1").Value, vars1) Then
        x = 1
    End If

    If IsInArray(Range("A1").Value, vars2) Then
        x = 1
    End If
End Sub

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

If the cell A1 contains the word Examples for some reason both of the IsInArray detects it as existing for both Arrays when it should only find it existing in the vars1 array

What do I need to change to make my IsInArray function to make it an exact match?

1
  • Do you mean that the function IsInArray detects them when the cell A1 contains "Example"? Commented Jul 8, 2016 at 13:39

8 Answers 8

64

You can brute force it like this:

Public Function IsInArray(stringToBeFound As String, arr As Variant) As Boolean
    Dim i
    For i = LBound(arr) To UBound(arr)
        If arr(i) = stringToBeFound Then
            IsInArray = True
            Exit Function
        End If
    Next i
    IsInArray = False

End Function

Use like

IsInArray("example", Array("example", "someother text", "more things", "and another"))
Sign up to request clarification or add additional context in comments.

8 Comments

Is there any benefits/negatives to using your method over changing the IsInArray function in my original code to use IsInArray = Not IsError(Application.Match(stringToBeFound, arr, 0)) instead?
How big is your array? Is this more readable than the other methods? It might just be preference because iterating over an array is pretty quick, and (though I can't say for sure) the Match function is surely doing basically this.
I'm running 10~ arrays through IsInArray, in total all of them added up comes to 501 array items at the moment. It will eventually become bigger/more of them.
Those are small numbers. I'm not sure you'd see much of a difference either way. A third option is the Dictionary object. It has an Exists method and is easier to work with than arrays (no ReDim Preserve when adding items)
@Ryflex @Slai it's maybe a bit late, but I wanted to clarify that using the Match() function is actually a lot slower than just iterating (looping) through the array. I did a test with an array of size 2000. The worst case scenario for looping through the array would be looking for the last item (at index 2000). After 5000 calls to both the Match() function and looping, the total time for Match() was 3.746094 but only 1.667969 for looping through the array. Check the answer to this question for the code I used in my testing
|
17

This Question was asked here: VBA Arrays - Check strict (not approximative) match

Sub test()
    vars1 = Array("Examples")
    vars2 = Array("Example")
    If IsInArray(Range("A1").value, vars1) Then
        x = 1
    End If

    If IsInArray(Range("A1").value, vars2) Then
        x = 1
    End If
End Sub

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

3 Comments

No need to loop through an array when it is done in excel, since excel have powerful match() function to do the comparison.
@Sixthsense this doesn't loop through an array
see the comment here regarding the performance issue with Match instead of looping: stackoverflow.com/questions/38267950/…
7

Use Match() function in excel VBA to check whether the value exists in an array.

Sub test()
    Dim x As Long

    vars1 = Array("Abc", "Xyz", "Examples")
    vars2 = Array("Def", "IJK", "MNO")

    If IsNumeric(Application.Match(Range("A1").Value, vars1, 0)) Then
        x = 1
    ElseIf IsNumeric(Application.Match(Range("A1").Value, vars2, 0)) Then
        x = 1
    End If

    MsgBox x
End Sub

2 Comments

I changed the IsInArray function to use IsInArray = Not IsError(Application.Match(stringToBeFound, arr, 0)) which resolves the problem
Not IsError() and IsNumeric() both results same answer when used with Match() function :)
7

I searched for this very question and when I saw the answers I ended up creating something different (because I favor less code over most other things most of the time) that should work in the vast majority of cases. Basically turn the array into a string with array elements separated by some delimiter character, and then wrap the search value in the delimiter character and pass through instr.

Function is_in_array(value As String, test_array) As Boolean
    If Not (IsArray(test_array)) Then Exit Function
    If InStr(1, "'" & Join(test_array, "'") & "'", "'" & value & "'") > 0 _
        Then is_in_array = True
End Function

And you'd execute the function like this:

test = is_in_array(1, array(1, 2, 3))

1 Comment

Horrifying. Please, no one should EVER convert an array of data into a string, to do a test like this! This is the opposite of good programming technique.
4

The below function returns '0' if there is no match and a 'positive integer' in case of matching:

Function IsInArray(stringToBeFound As String, arr As Variant) As Integer 
    IsInArray = InStr(Join(arr, ""), stringToBeFound) 
End Function

Note: the function first concatenates the entire array content to a string using 'Join' (not sure if the join method uses looping internally or not) and then checks for a match within this string using InStr.

4 Comments

would only works if arr items and stringToBeFound do not contain the , character/delimiter!
I tried it with ',' as well, but it still works! replaced 'Examples' with 'Exampl,es' in botb the arr and in stringToBeFound. Am i missing something? BTW, there was a typo in my code: now changed IsInArray = InStr(Join(arr, "), stringToBeFound) to IsInArray = InStr(Join(arr, ""), stringToBeFound)
I meant "would only work ... reliably" ... IsInArray( "ab", ("ab,c","d")) would return True, but it should return False because none of the two array items ab,c nor d equals ab. Same for IsInArray( "ab,c", ("ab","c"))
Horrifying. Please, no one should EVER convert an array of data into a string, to do a test like this! This is the opposite of good programming technique.
3

I would like to provide another variant that should be both performant and powerful, because

...

'-1 if not found
'https://stackoverflow.com/a/56327647/1915920
Public Function IsInArray( _
  item As Variant, _
  arr As Variant, _
  Optional nthOccurrence As Long = 1 _
  ) As Long

    IsInArray = -1

    Dim i As Long:  For i = LBound(arr, 1) To UBound(arr, 1)
        If arr(i) = item Then
            If nthOccurrence > 1 Then
                nthOccurrence = nthOccurrence - 1
                GoTo continue
            End If
            IsInArray = i
            Exit Function
        End If
continue:
    Next i

End Function

use it like this:

Sub testInt()
  Debug.Print IsInArray(2, Array(1, 2, 3))  '=> 1
End Sub

Sub testString1()
  Debug.Print IsInArray("b", Array("a", "b", "c", "a"))  '=> 1
End Sub

Sub testString2()
  Debug.Print IsInArray("b", Array("a", "b", "c", "b"), 2)  '=> 3
End Sub

Sub testBool1()
  Debug.Print IsInArray(False, Array(True, False, True))  '=> 1
End Sub

Sub testBool2()
  Debug.Print IsInArray(True, Array(True, False, True), 2)  '=> 2
End Sub

Comments

1

While this is essentially just @Brad's answer again, I thought it might be worth including a slightly modified function which will return the index of the item you're searching for if it exists in the array. If the item is not in the array, it returns -1 instead.

The output of this can be checked just like the "in string" function, If InStr(...) > 0 Then, so I made a little test function below it as an example.

Option Explicit

Public Function IsInArrayIndex(stringToFind As String, arr As Variant) As Long

    IsInArrayIndex = -1

    Dim i As Long
    For i = LBound(arr, 1) To UBound(arr, 1)
        If arr(i) = stringToFind Then
            IsInArrayIndex = i
            Exit Function
        End If
    Next i

End Function

Sub test()

    Dim fruitArray As Variant
    fruitArray = Array("orange", "apple", "banana", "berry")

    Dim result As Long
    result = IsInArrayIndex("apple", fruitArray)

    If result >= 0 Then
        Debug.Print chr(34) & fruitArray(result) & chr(34) & " exists in array at index " & result
    Else
        Debug.Print "does not exist in array"
    End If

End Sub

Then I went a little overboard and fleshed out one for two dimensional arrays because when you generate an array based on a range it's generally in this form.

It returns a single dimension variant array with just two values, the two indices of the array used as an input (assuming the value is found). If the value is not found, it returns an array of (-1, -1).

Option Explicit

Public Function IsInArray2DIndex(stringToFind As String, arr As Variant) As Variant

    IsInArray2DIndex= Array(-1, -1)

    Dim i As Long
    Dim j As Long

    For i = LBound(arr, 1) To UBound(arr, 1)
        For j = LBound(arr, 2) To UBound(arr, 2)
            If arr(i, j) = stringToFind Then
                IsInArray2DIndex= Array(i, j)
                Exit Function
            End If
        Next j
    Next i

End Function

Here's a picture of the data that I set up for the test, followed by the test:

test 2

Sub test2()

    Dim fruitArray2D As Variant
    fruitArray2D = sheets("Sheet1").Range("A1:B2").value

    Dim result As Variant
    result = IsInArray2DIndex("apple", fruitArray2D)

    If result(0) >= 0 And result(1) >= 0 Then
        Debug.Print chr(34) & fruitArray2D(result(0), result(1)) & chr(34) & " exists in array at row: " & result(0) & ", col: " & result(1)
    Else
        Debug.Print "does not exist in array"
    End If

End Sub

Comments

-1

You want to check whether Examples exists in Range("A1").Value If it fails then to check Example right? I think mycode will work perfect. Please check.

Sub test()
Dim string1 As String, string2 As String
string1 = "Examples"
string2 = "Example"
If InStr(1, Range("A1").Value, string1) > 0 Then
    x = 1
ElseIf InStr(1, Range("A1").Value, string2) > 0 Then
    x = 2
End If

End Sub

1 Comment

Yes, Examples exists in A1 and I can't use strings like you are using, I have an array for my code, otherwise I would have ordinaryly used InStr

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.