29

How can one achieve:

if X in (1,2,3) then

instead of:

if x=1 or x=2 or x=3 then

In other words, how can one best imitate the IN operator in VBA for excel?

Community
  • 1
  • 1
Allan Bowe
  • 12,306
  • 19
  • 75
  • 124

8 Answers8

19

I don't think there is a very elegant solution.

However, you could try:

If Not IsError(Application.Match(x, Array("Me", "You", "Dog", "Boo"), False)) Then

or you could write your own function:

Function ISIN(x, StringSetElementsAsArray)
    ISIN = InStr(1, Join(StringSetElementsAsArray, Chr(0)), _
    x, vbTextCompare) > 0
End Function

Sub testIt()
    Dim x As String
    x = "Dog"
    MsgBox ISIN(x, Array("Me", "You", "Dog", "Boo"))
End Sub
Kredns
  • 36,461
  • 52
  • 152
  • 203
  • 1
    Couldn't you just avoid the function and use something like: `InStr(1,"MeYouDogBoo",x)`? – redOctober13 May 09 '17 at 14:18
  • 1
    @redOctober13 this could work if you separate the list items with a delimiter that cannot be found in x. Otherwise, YouDo would trigger the InStr. – mrdaddychops Jan 17 '18 at 19:06
  • 1
    Be careful with this simple version of the **IsIn()** function. It will return True if the search word is contained in any words in the passed array. Searching for 'do' will return true because it's found in 'Dog'. The better way is to make sure chr(0) is before and after the search word, and before and after the joined search string. An example can be found here – Ben Apr 19 '18 at 20:52
  • @Ben can you check that link, it appears to be broken. Also I wrote this response almost 10 years ago and you are correct that this could be improved. – Kredns Apr 30 '18 at 17:32
  • @Kredns The address is correct but the link is passing the trailing '>' which was unintended. Try this one: [http://www.freevbcode.com/ShowCode.asp?ID=1675](http://www.freevbcode.com/ShowCode.asp?ID=1675) – Ben May 17 '18 at 16:24
  • When tested, this method took **1.828 seconds** while **[this answer](https://stackoverflow.com/a/52042455/8112776)** took only **0.406 seconds**. (Details in other answer.) – ashleedawg Aug 27 '18 at 15:28
15

You could also try the CASE statement instead of IF

Select Case X

 Case 1 To 3   
  ' Code to do something
 Case 4, 5, 6
  ' Code to do something
 Case 7
  ' Code to do something
 Case Else  
  ' More code or do nothing

End Select
Robert Mearns
  • 11,796
  • 3
  • 38
  • 42
  • 1
    How is this shorter than `if x=1 or x=2 or x=3 then` like the OP asked? – ashleedawg Aug 27 '18 at 14:20
  • 1
    I think this is still a good answer, and my preferred option. You only need one case statement as values can be stacked: `Select Case x Case 1,2,3 ' Your code... End Select` – LiceRewis Apr 03 '19 at 02:13
9

Fastest Method:

Here's a method much faster and more compact than any of the other answers, and works with numeric or text values:

Function IsIn(valCheck, valList As String) As Boolean  
    IsIn = Not InStr("," & valList & ",", "," & valCheck & ",") = 0
End Function

Examples:

Use IsIn with a numeric value:

Sub demo_Number()
    Const x = 2
    If IsIn(x, "1,2,3") Then
        Debug.Print "Value " & x & " was Found!"
    Else
        Debug.Print "Value " & x & " was not Found."
    End If
End Sub

Use IsIn with a string value:

Sub demo_Text()
    Const x = "Dog"
    If IsIn(x, "Me,You,Dog,Boo") Then
        Debug.Print "Value " & x & " was Found!"
    Else
        Debug.Print "Value " & x & " was not Found."
    End If
End Sub

Speed Comparison:

To compare speed I ran the test from the accepted answer 100,000 times:

  • 0.406 sec (FASTEST) This Function (using InStr):
  • 1.828 sec (450% slower) Accepted Answer with the "ISIN" function
  • 1.799 sec (440% slower) Answer with the "IsInArray" from freeVBcode
  • 0.838 sec (206% slower) Answer with modified "IsInArray" function

I didn't include the much longer answer that uses SELECT..CASE since the OP's goal was presumably to simplify and shorten the task compared to "if x=1 or x=2 or x=3 then".

ashleedawg
  • 20,365
  • 9
  • 72
  • 105
2

did you try

eval("3 in(1,2,3,4,5)")
THEn
  • 1,920
  • 3
  • 28
  • 35
1

There's none that I'm aware of.

I usually use a home-brewed InArray() function like the one at http://www.freevbcode.com/ShowCode.asp?ID=1675

You could also make a version that iterates through the array instead of concatenating, if that is more appropriate to your data type.

anschauung
  • 3,697
  • 3
  • 24
  • 34
  • When tested, this method took **1.799 seconds** while **[this answer](https://stackoverflow.com/a/52042455/8112776)** took only **0.406 seconds**. – ashleedawg Aug 27 '18 at 15:27
0

It doesn't work without writing your own function. Be aware that the accepted solution by @Kredns may not work as expected for all types of objects since they are coerced to strings (which also may raise Type Mismatch errors).

This solution should (hopefully) handle all types of data (at least in Excel 365, not sure about earlier versions):

Function IsIn(x As Variant, list As Variant) As Boolean
    ' Checks whether list (Array) contains the element x
    IsIn = False
    For Each element In list
        If x = element Then IsIn = True
    Next element
End Function
ascripter
  • 5,665
  • 12
  • 45
  • 68
0
dim x, y
x = 2
y = Array(1, 2, 3)

For i = 0 To 2
If x = y(i) Then
'your code comes here
Exit For
End If
Next i
Hakan
  • 1
  • While this code block may answer the OP's question, this answer would be much more useful if you explain how this code is different from the code in the question, what you've changed, why you've changed it and why that solves the problem without introducing others. – Nol4635 Jun 30 '22 at 23:47
-1

I wrote it now...

Public Function IsInArray(FindValue As Variant, ParamArray arrEmailAttachment()) As Boolean

Dim element As Variant

For Each element In arrEmailAttachment
    If element = FindValue Then
        IsInArray = True
        Exit Function
    End If
Next element

IsInArray = False

End Function
shlomo
  • 1
  • 2
  • While this code may answer the question, providing additional context regarding why and/or how this code answers the question improves its long-term value. – ashleedawg Aug 27 '18 at 14:30
  • When tested, this method took 0.838 seconds while **[this answer](https://stackoverflow.com/a/52042455/8112776)** took only **0.406 seconds**. – ashleedawg Aug 27 '18 at 15:25