expression evaluation optimization

  • Thread starter Thread starter Dick Watson
  • Start date Start date
D

Dick Watson

Here's what I want to code:

...
If myobj Is Nothing Or myobj.property Is Null Then
Do_Lots
Of_Stuff
When_We
Get_Here
End If
...

Of course, this doesn't work because even if the first clause (myobj Is
Nothing) is True, VBA wastes time evaluating the second clause
(myobj.property Is Null) which, also of course, fails with object variable
not set.

So, here's how I coded it instead:

...
If myobj Is Nothing Then
boolDoStuff = True
ElseIf myobj.property Is Null Then
boolDoStuff = True
Else
boolDoStuff = False
End If
If boolDoStuff Then
Do_Lots
Of_Stuff
When_We
Get_Here
End If
...

(If it weren't for all of the context I'd need to pass, the obvious other
way--besides some harmful GoTos or error trapping--would have been:)

...
If myobj Is Nothing Then
Call DoStuff
ElseIf myobj.property Is Null Then
Call DoStuff
End If
...

Sub DoStuff ()
Do_Lots
Of_Stuff
When_We
Get_Here
End Sub

My question: is there a better way to get the evaluation done lazily in the
first place?
 
Dick Watson said:
Here's what I want to code:

...
If myobj Is Nothing Or myobj.property Is Null Then
Do_Lots
Of_Stuff
When_We
Get_Here
End If
...

Of course, this doesn't work because even if the first clause (myobj
Is Nothing) is True, VBA wastes time evaluating the second clause
(myobj.property Is Null) which, also of course, fails with object
variable not set.

So, here's how I coded it instead:

...
If myobj Is Nothing Then
boolDoStuff = True
ElseIf myobj.property Is Null Then
boolDoStuff = True
Else
boolDoStuff = False
End If
If boolDoStuff Then
Do_Lots
Of_Stuff
When_We
Get_Here
End If
...

(If it weren't for all of the context I'd need to pass, the obvious
other way--besides some harmful GoTos or error trapping--would have
been:)

...
If myobj Is Nothing Then
Call DoStuff
ElseIf myobj.property Is Null Then
Call DoStuff
End If
...

Sub DoStuff ()
Do_Lots
Of_Stuff
When_We
Get_Here
End Sub

My question: is there a better way to get the evaluation done lazily
in the first place?

What about this?

If Not (myobj Is Nothing) Then
If Not IsNull(myobj.property) Then
Do_Lots
Of_Stuff
When_We
Get_Here
End If
End If

Note: I changed "myobj.property Is Null" to "IsNull(myobj.property)"
because I don't expect the "Is Null" syntax to work in VBA.
 
I use the function below...

Function IsNothing(varArg As Variant) As Boolean
'Checks whether argument is Null, Empty, empty string, or Nothing

On Error GoTo Err_IsNothing

IsNothing = False

Select Case VarType(varArg)
Case vbEmpty
IsNothing = True
Case vbNull
IsNothing = True
Case vbString
If Len(varArg) = 0 Then
IsNothing = True
End If
Case vbObject
If varArg Is Nothing Then
IsNothing = True
End If
End Select

Exit Function

Err_IsNothing:
IsNothing = True
End Function
 
Fixed and commented code to correctly/clearly state question is below...

Dick Watson said:
Here's what I want to code:
...
' the object may be unset or set to something with a null property
If myobj Is Nothing Or IsNull(myobj.property) Then
Do_Lots
Of_Stuff
When_We
Get_Here
End If
...
Of course, this doesn't work because even if the first clause (myobj Is
Nothing) is True, VBA wastes time evaluating the second clause
IsNull(myobj.property) which, also of course, fails with object variable
not set.

So, here's how I coded it instead:
...
' the object may be unset or set to something with a null property
If myobj Is Nothing Then ' a true case, evaluated first
boolDoStuff = True
ElseIf IsNull(myobj.property) Then ' OR but evaluated separately
boolDoStuff = True
Else
boolDoStuff = False
End If
If boolDoStuff Then
Do_Lots
Of_Stuff
When_We
Get_Here
End If
...
(If it weren't for all of the context I'd need to pass, the obvious other
way--besides some harmful GoTos or error trapping--would have been:)
...
' the object may be unset or set to something with a null property
If myobj Is Nothing Then
Call DoStuff
ElseIf IsNull(myobj.property) Then ' mest be evaluated separately
Call DoStuff
End If
...

Sub DoStuff ()
Do_Lots
Of_Stuff
When_We
Get_Here
End Sub
 
Dirk Goldgar said:
What about this?

If Not (myobj Is Nothing) Then
If Not IsNull(myobj.property) Then
Do_Lots
Of_Stuff
When_We
Get_Here
End If
End If

Note: I changed "myobj.property Is Null" to "IsNull(myobj.property)"
because I don't expect the "Is Null" syntax to work in VBA.

The problem with that is that it amounts to

If Not (myobj Is Nothing) And Not IsNull(myobj.property) Then

not

If myobj Is Nothing Or Not IsNull(myobj.property) Then

I need the **Or** to pass both cases

a) where myobj is nothing, and
b) the case where myobj is something but its .property IsNull().

You are right about myobj.property Is Null vs. IsNull(myobj.property). I
messed up when I wrote the message.
 
Dick Watson said:
The problem with that is that it amounts to

If Not (myobj Is Nothing) And Not IsNull(myobj.property) Then

not

If myobj Is Nothing Or Not IsNull(myobj.property) Then

I need the **Or** to pass both cases

a) where myobj is nothing, and
b) the case where myobj is something but its .property IsNull().

You are right about myobj.property Is Null vs.
IsNull(myobj.property). I messed up when I wrote the message.

Sorry, I misunderstood what you wanted. I think using Paul Overway's
function, or something very like it, is going to be your cleanest
solution.
 
I thought of something like that about a day ago. Don't remember why I moved
on. Maybe the phone rang?

Anyway, maybe that's a cleaner answer than my separate boolean and If/Else
If/Else/If logic.

Thanks!
 
' the object may be unset or set to something with a null property
If myobj Is Nothing Or IsNull(myobj.property) Then
Do_Lots
Of_Stuff
When_We
Get_Here
End If

If MyObj Is Nothing then
NeedsDoing = True

ElseIf IsNull(MyObj.Property) Then
NeedsDoing = True

Else
NeedsDoing = False

End If

If NeedsDoing Then Call LotsOfStuff()


Hope that helps


Tim F
 
Back
Top