In an application I'm working on now, from a given document - a Claim, I need to look up a value on a connected document, a Partner.  In this application there is a function to do just that, fetch a Partner document based on a value in Claim;  The code snippet looks like this:

       'is the partner tax exempt?  
       Dim ClientInsurer As NotesDocument
       Set ClientInsurer = GetPartnerDoc(claim.ID_ClientInsurer(0))
       If ClientInsurer Is Nothing then

And when this is run, ClientInsurer is invariably Nothing.  

GetPartnerDoc looks like this:

Function GetPartnerDoc(IPCode As String) As NotesDocument
       Dim pDB As NotesDatabase, insurers As NotesView
       Set pDB=GetPartnersDB
       Set Insurers=pDB.GetView("LookUpIPCode")
       Set GetPartnerDoc=Insurers.GetDocumentByKey(IPCode,True)
End Function

When I look at this with the debugger, I can see that the last line of getPartnerDoc populates getPartnerDoc with a NotesDocument data type, and it is indeed the partner document that I want - getPartnerDoc seems to work OK.   Yet that value, that I can see ready to go when it's executed the last line of GetPartnerDoc doesn't get back in to ClientInsurer in the invoking code.  How strange is that?

I've bypassed it by replacing the call to GetPartnerDoc with a direct lookup to the same view, and that works just fine.

Btw:  this is with Designer 8.5.1 FP1, Notes 851FP1 client and a Donino 851FP1 server.  However when the code runs on a 7.0.something server, it also generates the same erroneous result.  

Comments (9)
Mick Moignard March 11th, 2010 09:42:02 AM

 Comments
1) How strange is this?
Selcuk Ayguney 3/11/2010 12:56:04 PM

That's most probably because the garbage collector destroys your NotesDocument after returning from function because the parent object (NotesDatabase) is destroyed.

Initialize the database object before and pass it as a function argument instead:

Set pDB=GetPartnersDB

Set ClientInsurer = GetPartnerDoc(pDB, claim.ID_ClientInsurer(0))

and

Function GetPartnerDoc(pDB as NotesDatabase, IPCode As String) As NotesDocument

Hope this helps

Selcuk Ayguney

2) How strange is this?
Julian Robichaux 3/11/2010 1:10:11 PM

I've had exactly that same issue on code that runs on a server, yet it runs just fine in the client. In certain situations (as Selcuk describes), if you return a handle to a NotesDocument from a function/method but the database and/or view that the document is from is no longer in scope, the NotesDocument reference will also go out of scope too. If the NotesDatabase and NotesView that the doc came from stay in scope (globally or locally) you won't see the error.

It's a pain to debug too, because when you run the function locally it usually works. Just on the server where it's a problem most of the time.

3) How strange is this?
Giulio Campobassi 3/11/2010 1:20:59 PM

Julian has explained it best.

This is not a bug, but simply variable scope rules for Notes objects biting you in the a$$.

A couple of ways to solve this. Keep the db object global and only access it via the getPartnersDB function.

4) How strange is this?
Giulio Campobassi 3/11/2010 1:22:53 PM

hmmm.. I said that there were "a couple of ways" and only listed one.. the second way is not worth mentioning...LOL...

5) How strange is this?
Brent Henry 3/11/2010 1:31:59 PM

Notes is working as designed (really).

Here is the best explanation I've seen around scope, garbage collection, etc.

{ Link }

6) How strange is this?
Mick Moignard 3/11/2010 1:50:24 PM

Thanks everyone for all the feedback - I knew there was a simple answer that was eluding me - and @5 I've even read that article before, too. Should have realised sooner that was the answer.

Mick

7) How strange is this?
Peter Presnell 3/11/2010 2:41:36 PM

I have always found it a good idea to have a LS library that declares a few global variables such as DB and then initialize its value in the Initialize section. Include that LS library everywhere you invoke LS code thereby creating a global variable that is never going to be garbage collected.

8) How strange is this?
Devin Olson 3/15/2010 6:47:51 AM

It is a scope issue; and is compounded by your script debugger crossing scope boundaries -which it will sometimes do.

Make your partners db globally accessible, and the problem will go away.

9) How strange is this?
Julian Woodward 3/16/2010 9:08:04 AM

Another solution would be to make the database handle a static variable inside the GetPartnersDB function, and use an 'is nothing' test within that function to see if it's already been initialised. That also takes the inefficiency out of repeated calling the function. (Although to really eradicate the inefficiency you would want to do the same thing with the view handle in the GetPartnerDoc function)

 Add a Comment
Subject:
   
Name:
E-mail:
Web Site:
 
Comment:  (No HTML - Links will be converted if prefixed http://)
 
Remember Me?