AndAlso/OrElse in VBA
I'm trying to get a lazy evaluation with 'And' in my Excel macro by doing the following:
If Not myObject Is Nothing *And* myObject.test() Then
'do something'
Else
'do something else'
End If
I know lazy evaluation exists in VB.NET as AndAlso
and OrElse
but cannot find anything similar in VBA. If lazy evaluation does not exist in VBA, what's the best way to structure the code so that it will evaluate the way I expect?
Solution 1:
The only short circuiting (of a sort) is within Case
expression evaluation, so the following ungainly statement does what I think you're asking;
Select Case True
Case (myObject Is Nothing), Not myObject.test()
MsgBox "no instance or test == false"
Case Else
MsgBox "got instance & test == true"
End Select
End Sub
Solution 2:
This is an old question, but this issue is still alive and well. One workaround I've used:
Dim success As Boolean ' False by default.
If myObj Is Nothing Then ' Object is nothing, success = False already, do nothing.
ElseIf Not myObj.test() Then ' Test failed, success = False already, do nothing.
Else: success = True ' Object is not nothing and test passed.
End If
If success Then
' Do stuff...
Else
' Do other stuff...
End If
This basically inverts the logic in the original question, but you get the same result. I think it's a cleaner solution than the others here that only use If
statements. The solution using a Select
statement is clever, but if you want an alternative using only If
statements, I think this is the one to use.
Solution 3:
Or you could create a function that takes your object as a parameter and returns boolean for either case. That's what I usually to.
i.e.
if Proceed(objMyAwesomeObject) then
'do some really neat stuff here
else
'do something else, eh
end if
...
end sub
private function Proceed(objMyAwesomeObject as Object)
if not objMyAweseomeObject is nothing then
Proceed = true
elseif objMyAwesomeObject.SomeProperty = SomeValue then
Proceed = true
else
Proceed = false
endif
end function
Solution 4:
Improving on this answer to a different question about the same basic problem, here is what I chose to do:
dim conditionsValid as boolean
conditionsValid = myObject Is Nothing
if conditionsValid then conditionsValid = myObject.test()
if conditionsValid then conditionsValid = myObject.anotherTest()
if conditionsValid then
'do something'
else
'do something else'
end if
I think this code is clearer than the other answers that have been suggested, and you (usually) don't need a different variable for each validation, which is the improvement over the original answer to the other question. By the way, each new condition you need adds just one more line of code.