... VBA keeps testing an "Or" statement after it finds a true? ...

darlingm

Registered User.
Local time
Yesterday, 16:50
Joined
Feb 24, 2008
Messages
14
Why in the world am I getting a message box saying "You should never see this message." followed by a message box saying "You should see this message."

Am I missing something, or does this prove VBA in an "or" statement, keeps testing after it's found a true, rather than stopping where it should?

If so, WTF? Isn't it pretty standard by now that (current) languages stop processing Or statements once they know it's true, at least to save execution time? Is there a reason why Access VBA acts differently? This was fun, wasted a decent amount of time today figuring this one out. :mad:

I'm testing this just by typing in the following code, clicking into the subroutine TheTest() and clicking "Run Sub/UserForm".

Code:
Function ReturnTrue() As Boolean
   ReturnTrue = True
End Function

Function ThisShouldNotRun() AS Boolean
   MsgBox ("You should never see this message.")
   ThisShouldNotRun = True
End Function

Sub TheTest()
   If (ReturnTrue()) Or (ThisShouldNotRun()) Then
      MsgBox ("You should see this message.")
   End If
End Sub

I can, of course, get around this by re-writing TheTest() to be:

Code:
Sub TheTest()
    If ReturnTrue() Then
        MsgBox ("You should see this message.")
    ElseIf TestOr() Then
        MsgBox ("You should never see this message, either.")
    End If
End Sub
 
I'll be the first to say shame on me, assuming the language/compiler made an optimization, and coding to that, but wow, I'm suprised. I've always been able to count on that.
 
i'm pretty sure that if and iif statements evaluate every expression, so you have to be aware of that to avoid divide by zero errors and stuff, as you have seen

if vba was a great language, we would have a nice friendly pointer type, and be able to pass procedure addresses to other procedures, and loads of stuff like that, and not have to write i= i+1

just checked with

If True Or 3 / 0 = 1 Then
MsgBox ("OK")
Else
MsgBox ("Error")
End If

it crashes!!!
 
Simple Software Solutions

Gemma

An IIf statement evaluates both expressions THEN decides whether to use the true or false element of the code, so if there is a propblem with one element you would expect to get an error. Whereas an If statement will only evaluate the Else statement if the If statement is not met.

When using an ElseIf this is simply a multiple If statement checking for several conditions about one entity. It will consider each ElseIf in turn until it finds an answer. That is why you should always employ an Else condition as a get out clause. This also applies to Select Case .... Case Else... End Select.

Consider evaluating the day of the week for a date in a Select Case Statement

Select case day(Date())

Case vbMonday
Case vbTuesday
....
Case vbSunday
Case Else

End Select

In theory the case else condition should never be reached, but as in everyday life something always come along and bites your bum. So to be prepared for it, its always good practice to add a little extra code to prevent the app from falling over.

Going back to the If versus IIf practice; always use the If Else above the IIf wherever possible, not only does it speed up your program but is easier to read, espeically if you are building nested IIf's.

CodeMaster::cool:http://www.icraftlimited.co.uk
 
i know that

darlingm was surpised that the expression

if a or b then
etc

evaluated b, if a was true anyway, and i had a look at it.


anyway you want to write

if a or b then
do_x


rather than

if a then
do_x
elseif b then
do_x
end if
 

Users who are viewing this thread

Back
Top Bottom