Excel vba is value in array

In this Article

  • Searching in a One-Dimensional Array
    • Find values that match the Filter
    • Find values that DO NOT match the Filter
    • Case Sensitive Filters
    • Option Compare Text
  • Using a Loop to Search through an array
  • Searching in a Multi-Dimensional Array

This tutorial will demonstrate how to Search for (Find) a Value in an Array in VBA

There are a number of ways you can search for a string in an array – depending on whether the array is a one dimensional or multi-dimensional.

Searching in a One-Dimensional Array

To search for a value in a one-dimensional array, you can use the Filter Function.

Dim z As Variant
'filter the original array
  z = Filter(Array, String, True, vbCompareBinary)

The Syntax of the Filter option is a follows

Filter(Source Array, Match as String, [Include as Boolean], [Compare as vbCompareMethod])

The Source Array and the Match as String are required while the Include as Boolean and the Compare as vbCompareMethod are optional.  If these are not included they are set to True and vbCompareBinary respectively.

Find values that match the Filter

Sub FindBob()
   'Create Array
   Dim strName() As Variant
   strName() = Array("Bob Smith", "John Davies", "Fred Jones", "Steve Jenkins", "Bob Williams")
   
   'declare a variant to store the filter data in
   Dim strSubNames  As Variant

  'filter the original array
   strSubNames = Filter(strName, "Bob")

   'if you UBound value is greater than -1, then the value has been found
   If UBound(strSubNames ) > -1 Then MsgBox ("I found Bob")
End Sub

The second array will hold the values found by the filter.  If your UBound values are not -1, then the array has managed to find the  value that you were searching for.

You can also see how many times the text appears in the original array.

Sub CountNames()
   'Create array
   Dim strName() As Variant
   strName() = Array("Bob Smith", "John Davies", "Fred Jones", "Steve Jenkins", "Bob Williams")

  'declare an array to store the filter data in
   Dim strSubNames As Variant

   'filter the original array
   strSubNames = Filter(strName, "Bob")

   'if you add 1 to the UBound value, we will get the number of times the text appears
   Msgbox  UBound(strSubNames) + 1 & " names found." 
End Sub

Find values that DO NOT match the Filter

The [Include as Boolean] option allows you to find how many values in your array which DO NOT match your filter

Sub CountExtraNames() 
  'create array
  Dim strName() As Variant 
  strName() = Array("Bob Smith", "John Davies", "Fred Jones", "Steve Jenkins", "Bob Williams") 

  'declare an array to store the filter data in 
  Dim strSubNames As Variant 

  'filter the original array 
  strSubNames = Filter(strName, "Bob", False) 

  'if you add 1 to the UBound value, we will get the number of times the text appears 
  Msgbox  UBound(strSubNames) + 1 & " names found." 
End Sub

we have therefore amended this line:

strSubNames = Filter(strName, "Bob")

with this line:

strSubNames = Filter(strName, "Bob", False)

Using this line in the code, would return all the names that do NOT match “Bob”.

vba find array msgbox

Case Sensitive Filters

You will find that the filter is case sensitive by default.  This is true for all VBA functions.  If you want to search for text that is not case sensitive, you need to amend your code slightly.

z = Filter(strName, "bob",, vbTextCompare)

Adding vbTextCompare to your filter line will enable your code to find “bob” or “Bob”.  If this is omitted, VBA by default uses vbBinaryCompare which will only look for data that is an EXACT match.  Notice in the example above, we have left out the [Include as Boolean] argument so True is assumed.

Option Compare Text

Alternatively, you can add the text Option Compare Text to the top of your module – this will make all the functions that you write in that particular module case insensitive.

vba find array option compare text

VBA Coding Made Easy

Stop searching for VBA code online. Learn more about AutoMacro — A VBA Code Builder that allows beginners to code procedures from scratch with minimal coding knowledge and with many time-saving features for all users!

automacro

Learn More

Using a Loop to Search through an array

Using a loop is a little bit more complicated than using the Filter function.  We can create a function that will loop through all the values in the array.

Sub LoopThroughArray()
  'create array
  Dim strName() As Variant 
  strName() = Array("Bob Smith", "John Davies", "Fred Jones", "Steve Jenkins", "Bob Williams") 

Dim strFind as string 
strFind = "Bob"

Dim i As Long
'loop through the array
   For i = LBound(strName, 1) To UBound(strName, 1)
       If InStr(strName(i), strFind) > 0 Then
          MsgBox "Bob has been found!"
          Exit For
       End If
    Next i
End Sub

In order to find a part of the text string ie “Bob” instead of “Bob Smith” or “Bob Williams”, we needed to use the Instr Function in the If Statement.  This looked in the string returned by the loop from the Array to see if “Bob” was in the string, and as it was in the string, it would return a message box and then Exit the Loop.

Searching in a Multi-Dimensional Array

We also use the loop to search through a multi-dimensional array.  Once again, we need to create a function than enables us to loop through all the values in the array, but this time, we also need to loop through each dimension of the array.

Function LoopThroughArray()
   Dim varArray() As Variant
   Dim strFind As String
   strFind = "Doctor"
'declare the size of the array
   ReDim varArray(1, 2)
'initialise the array
   varArray(0, 0) = "Mel Smith"
   varArray(0, 1) = "Fred Buckle"
   varArray(0, 2) = "Jane Eyre"
   varArray(1, 0) = "Accountant"
   varArray(1, 1) = "Secretary"
   varArray(1, 2) = "Doctor"
'declare variables for the loop
   Dim i As Long, j As Long
'loop for the first dimension
   For i = LBound(varArray, 1) To UBound(varArray, 1)
'loop for the second dimension
      For j = LBound(varArray, 2) To UBound(varArray, 2)
'if we find the value, then msgbox to say that we have the value and exit the function
         If varArray(i, j) = strFind Then
            MsgBox "Doctor has been found!"
            Exit Function
         End If
      Next j
   Next i
End Function

  • #2

Filter works on partial matches, so «a» is in the final array in the form of «a-b». Your second to last example works correctly for me

  • #3

Filter works on partial matches, so «a» is in the final array in the form of «a-b». Your second to last example works correctly for me

If Filter works on partial matches then that is where I am going wrong. Can you (or anyone else) suggest an alternate method of checking whether an item is in an array?

Edit: yes you are write about my second last example. That actually does work correctly. I got that example the wrong way around. But I think people should be able to get my drift.

Last edited: Sep 2, 2013

  • #4

Perhaps more resilient, but not fool proof:

Code:

Function IsInArray(stringToBeFound As String, arr As Variant) As Boolean
    IsInArray = InStr(1, vbCr & Join(arr, vbCr) & vbCr, vbCr & stringToBeFound & vbCr)
End Function

Though it’s worth mentioning, that looping through arrays in memory is pretty fast, so shouldn’t be ruled out. These approaches also will only work on arrays with a single dimension — they fail in the case of a 2d array which are very common in Excel

  • #5

Hi Harry

Filter does not perform an exact match.

Another option:

Code:

  IsInArray = Not IsError(Application.Match(stringToBeFound, arr, 0))

snb_

Well-known Member


  • #6

Code:

Sub M_snb()
    sn = Array("aa1", "aa2", "bb3")
    
    c00 = "aa1"
    c01 = "b"
    c02 = "Exact match: "
    
    MsgBox c02 & Format(InStr("~" & Join(sn, "~|~") & "~", "~" & c00 & "~"), "yes/no")
    MsgBox c02 & Format(InStr("~" & Join(sn, "~|~") & "~", "~" & c01 & "~"), "yes/no")

    MsgBox c02 & Format(UBound(Filter(Split("~" & Join(sn, "~|~") & "~", "|"), "~" & c00 & "~")) > -1, "yes/no")
    MsgBox c02 & Format(UBound(Filter(Split("~" & Join(sn, "~|~") & "~", "|"), "~" & c01 & "~")) > -1, "yes/no")

    MsgBox c02 & Format(Not IsError(Application.Match(c00, sn, 0)), "yes/no")
    MsgBox c02 & Format(Not IsError(Application.Match(c01, sn, 0)), "yes/no")
End Sub

  • #7

Hi Harry

Filter does not perform an exact match.

Another option:

Code:

  IsInArray = Not IsError(Application.Match(stringToBeFound, arr, 0))

Thank you that was exactly what I was looking for.

This problem has a small piece of the jigsaw puzzle that I posted in this thread:
http://www.mrexcel.com/forum/excel-…-value-exists-new-collection.html#post3561227

Which was itself a small piece in a larger jigsaw puzzle.

My original question was how could I check if an item was in a New Collection, which I never figured out. So I thought I would try passing my New Collection to an array and find someway to check that.

Thanks to Kyle123 and snb_ as well for their input too. Much appreciated. I am teaching myself VBA from books and I no one at my work knows anything about it, thus the learning process involves a lot of persistence and trial and error. So I am really grateful for the pointers I get from this forum.

As it happens I am quite glad that I now have two methods at my disposal, and for the larger problem that I am working finding partial matches will also be very useful, and I will ultimately incorporate both approaches in my code. Cheers.

snb_

Well-known Member


  • #8

Code:

Sub M_snb()
    On Error Resume Next
    With New Collection
      .Add "aaa", "bbb"
      x3 = .Item("bb1")
      If Err.Number <> 0 Then MsgBox "item doesn't exist"
    End With
End Sub

  • #9

You’re welcome. Thanks for the feedback.

  • #10

As long as your ‘arr’ variable will always be a one-dimensional array, you could write your function this way…

Code:

Function IsInArray(stringToBeFound As String, arr As Variant) As Boolean
  IsInArray = InStr(Chr(1) & Join(arr, Chr(1)) & Chr(1), Chr(1) & stringToBeFound & Chr(1)) > 0
End Function

To check if a value exists in an array, we can loop through its elements. However there is another solution! You can use the INDEX () function, native to Excel and in the case of two-dimensional arrays use a combination of the INDEX/MATCH function. However, if the value is not found, Application.Match returns an error. You will need to take into account any possible errors, as well as the number of dimensions of the array variable. This small function will help you out.

Using the Match function

Function EstDans(mot As String, Tabl) As Boolean
Dim Dimension As Byte, j As Integer
On Error Resume Next
If IsError(UBound(Tabl, 2)) Then Dimension = 1 Else Dimension = 2
On Error GoTo 0
Select Case Dimension
    Case 1
        On Error Resume Next
        EstDans = Application.Match(mot, Tabl, 0)
        On Error GoTo 0
    Case 2
        For j = 1 To UBound(Tabl, 2)
            On Error Resume Next
            EstDans = Application.Match(mot, Application.Index(Tabl, , j), 0)
            On Error GoTo 0
            If EstDans = True Then Exit For
        Next
End Select
End Function

Invoking the function

Sub test()
Dim Tb(), i As Integer
'tb 2 dimensions :
Tb = Range("A2:C16").Value
Debug.Print EstDans(MaValeur, Tb)
Erase Tb
'tb 1 dimension :
ReDim Preserve Tb(15)
For i = 0 To 14
    Tb(i) = Cells(i + 2, 1)
Next
Debug.Print EstDans(MaValeur, Tb)
End Sub

Using a loop

The structure of this function is similar to the one using Match.

Function BoucleSurTabl(mot As String, Tb)
Dim Dimension As Byte, i As Long, j As Long
On Error Resume Next
If IsError(UBound(Tb, 2)) Then Dimension = 1 Else Dimension = 2
On Error GoTo 0
Select Case Dimension
    Case 1
        For j = LBound(Tb) To UBound(Tb)
            If Tb(j) = mot Then BoucleSurTabl = True: Exit Function
        Next
    Case 2
        For i = LBound(Tb, 1) To UBound(Tb, 1)
            For j = LBound(Tb, 2) To UBound(Tb, 2)
                If Tb(i, j) = mot Then BoucleSurTabl = True: Exit Function
            Next j
        Next i
End Select
End Function

Observations

Against all odds, you will get a better result with the loop function on large arrays than using Application.Match. Testing a 2-dimensional array with a the following Range («A1: Y20002»).

  • Using the Match function: 8.300781 seconds.
  • Using the loop: 0.4375 seconds.

Testing a one-dimensional array:

  • Using the Match function: instant
  • Using the loop: 0.015625 seconds

Download link

  • You can download the sample workbook here.

More Excel questions? Check out our forum!

To check if a value exists in an array, copy this function into a module:

Function in_array(my_array, my_value)
    
    'https://www.excel-pratique.com/en/vba_tricks/search-in-array-function
	
    in_array = False
    
    For i = LBound(my_array) To UBound(my_array)
        If my_array(i) = my_value Then 'If value found
            in_array = True
            Exit For
        End If
    Next
    
End Function

The in_array function will return True or False depending on the result.

Here’s a simple example that will look for the presence of the value of the «test_value» variable in the «test_array» array and display True or False in a MsgBox:

Sub test()
    
    test_array = Array(23, 67, 38, 17, 854, 9, 92)

    test_value = 17
    
    MsgBox in_array(test_array, test_value)

End Sub

Понравилась статья? Поделить с друзьями:
  • Excel vba number format number
  • Excel vba is not numeric
  • Excel vba is keyword
  • Excel vba now time
  • Excel vba is decimal