I created a seemingly simple code which checks the values in 2 cells (Q78 and Q87). And based on the values executes actions.
If Range("Q78") = "1" And Range("Q87") = "1" Or "2" Then
Go do this
ElseIf Range("Q78") = "2" And Range("Q87") = "1" Or "2" Then
Go do that
End If
The problem I have is that even if the value in the cell Q78="2" and Q87="2" it just runs the first part of the code(If Range("Q78") = "1" And Range("Q87") = "1" Or "2" Then)
.
However if I change the Q87 value to "1" it works the way it should.
What am I doing wrong?
To expand on @FunThomas 's comment with an explanation of why to add the brackets...
Using parentheses (brackets) in that way forces VBA to evaluate the expression in the order you intended. Many languages (VBA included) will evaluate the and
before the or
but will evaluate the content between brackets first regardless.
Taking
If Range("Q78") = "1" And Range("Q87") = "1" Or Range("Q87") = "2" Then
With your values that is equivalent to saying
If "2" = "1" And "2" = "1" Or "2" = "2" Then
Start with the And - that bit evaluates to False
so the snippet becomes
If False Or "2" = "2" Then
Which becomes
If False Or True Then
Do This
So you will always Do This
.
Force VBA to evaluate the Or
first by adding the brackets
If Range("Q78") = "1" And (Range("Q87") = "1" Or Range("Q87") = "2") Then
The bit in the brackets is evaluated first (not that it matters as long as that Or
is done on the intended values) and the whole thing evaluates to
If False And True Then 'i.e. If False Then
And it will route to Do That
EDIT: Challenge accepted! @FunThomas mentioned I hadn't explained why
If Range("Q78") = "2" And Range("Q87") = "1" Or "2" Then
doesn't work as you expected it to.
The key bit here is Or "2"
.
First thing to note is that VBA will convert strings to numbers if it can. So in this case that is the same as Or 2
.
The 2nd point, is that boolean values have numeric equivalents
False = 0
True = any non-zero value - usually -1 or 1, but any value will do
So 2
by itself = True
Back to your snippet, what it is actually saying is
If Range("Q78") = "2" And Range("Q87") = "1" Or True Then
Follow the steps above from that point.