Link to home
Start Free TrialLog in
Avatar of AliciaVee
AliciaVee

asked on

"Invalid Universal ID" Error on LotusScript

Experts,

I am trying to use this script (I ordered a code database from www.codeexamples.com).  The first part is the actualy code. The 2nd part is my version, matching my fields etc.  I only have one field I want tallied, so I had to make changes on this script to make it fit my need (not sure I did that right?)

I'm getting this error:  "Invalid Universal ID" on close of the document.  So, I thought maybe since I didn't have a field capturing the ParentDocumentUNID -- that I should add one to the parent.  So, I added a field called DocID to the PARENT Document with the following formula:
@Text(@DocumentUniqueID)

And I now see the DocumentUniqueID in the document properties -- but it didn't help me with my error -- still getting the SAME error.

I've put this in the QueryClose of my Main Document, and I'm trying to get the totals from my response document.  What also confuses me is the metion/call of a view?  Then I thought -- maybe this code goes in the view -- but the parameters don't match, so it must be document.

Can anyone help me?

Original Code:
--------------------------------
CALCULATE THE TOTAL OF THE A NUM BER/CURRENCY FIELD FROM ALL THE RESPONSE DOCUMENTS AND POPULATE A FIELD IN THE PARENT DOCUMENT WITH THAT TOTAL

Sub Queryclose(Source As Notesuidocument, Continue As Variant)
'DECLARING ALL THE VARABLES
Dim count As Integer
Dim workspace As New NotesUIWorkspace
Dim newamount As Variant
Dim currentdoc As NotesDocument
Dim dbase As NotesDatabase
Dim Session As New NotesSession
Dim responsedoc As NotesDocument
Dim parentdoc As notesDocument
Dim collection As NotesDocumentCollection
Dim parentdocitem As NotesItem

Dim item As NotesItem
Dim temp As Double
Dim ret As Variant
Dim view As NotesView

Dim ta As Double
Dim ts As Double
Dim trf As Double
Dim inst As Double
Dim mi As Double
Dim parentID As Variant

'SETTING THE VARIABLES
Set currentdoc = source.Document
Source.AutoReload = False
Set dbase = session.CurrentDatabase
Set responsedoc = source.Document

%REM
GETTING THE PARENT DOCUMENT'S UNIQUE ID FROM THE RESPONSE DOCUMENT AND THEN OPENS
DOCUMENT. THE COLLECTION IS SET TO BE ALL THE RESPONSES OF THE PARENT DOCUMENT.
%END REM

parentID = responsedoc.ParentDocumentUNID
Set parentdoc = dbase.GetDocumentByUNID(ParentID)
Set collection = parentdoc.Responses

'LOOPING THROUGH ALL THE RESPONSE DOCUMENTS TO ADD THE ACTUAL SAVINGS. WHEN DOING THIS
'IT CHECKS FOR WHETHER THE RESPONSE DOCUMENT IS A TAX ABATEMENT, TAX SAVINGS,
'INFRASTRUCTURE, TRAINING FUNDS OR MISCELLANEOUS TYPES, SO THAT THE CORRECT ACTUAL
'SAVINGS IN THAT PARTICULAR SECTION OF THE PARENT DOCUMENT IS POPULATED.

For count = 1 To collection.count
Set responsedoc = collection.GetNthDocument(count)
If responsedoc.TaType(0) = "Ta" Then
ta = ta + responsedoc.TaAmount(0)
End If

If responsedoc.TsType(0) = "Ts" Then
ts = ts + responsedoc.TsAmount(0)
End If

If responsedoc.TrfType(0) = "Trf" Then
trf = trf + responsedoc.TrfAmount(0)
End If

If responsedoc.InstrType(0) = "Instr" Then
inst = inst +responsedoc.InstrAmount(0)
End If

If responsedoc.MiType(0) = "Misc" Then
mi = mi + responsedoc.MiAmount(0)
End If
Next count

parentdoc.TotalAmount = ta + ts + trf + inst + mi
parentdoc.TaActAccSavings = ta
parentdoc.TsActAccSavings = ts
parentdoc.TrfActAccSavings = trf
parentdoc.InstrActAccSavings = inst
parentdoc.MiActAccSavings = mi

'SAVING THE PARENT DOCUMENT AFTER MAKING THE CHANGES.
ret = parentdoc.Save (True, False)

'REFRESHING THE VIEW TO SEE THE CHANGES MADE.
Set View = dbase.GetView("Status")
Call view.Refresh
Call workspace.viewRefresh

End Sub
----------------------------------------------

My code I am using:
--------------------------------------------
Sub Queryclose(Source As Notesuidocument, Continue As Variant)
     
'DECLARING ALL THE VARABLES
     Dim count As Integer
     Dim workspace As New NotesUIWorkspace
     Dim newamount As Variant
     Dim currentdoc As NotesDocument
     Dim dbase As NotesDatabase
     Dim Session As New NotesSession
     Dim responsedoc As NotesDocument
     Dim parentdoc As notesDocument
     Dim collection As NotesDocumentCollection
     Dim parentdocitem As NotesItem
     
     Dim item As NotesItem
     Dim temp As Double
     Dim ret As Variant
     Dim view As NotesView
     
     Dim ta As Double
     Dim ts As Double
     Dim trf As Double
     Dim inst As Double
     Dim mi As Double
     Dim parentID As Variant
     
'SETTING THE VARIABLES
     Set currentdoc = source.Document
     Source.AutoReload = False
     Set dbase = session.CurrentDatabase
     Set responsedoc = source.Document
     
%REM
GETTING THE PARENT DOCUMENT'S UNIQUE ID FROM THE RESPONSE DOCUMENT AND THEN OPENS
DOCUMENT. THE COLLECTION IS SET TO BE ALL THE RESPONSES OF THE PARENT DOCUMENT.
%END REM
     
     parentID = responsedoc.ParentDocumentUNID
     Set parentdoc = dbase.GetDocumentByUNID(ParentID)
     Set collection = parentdoc.Responses
     
'LOOPING THROUGH ALL THE RESPONSE DOCUMENTS TO ADD THE ACTUAL SAVINGS. WHEN DOING THIS
'IT CHECKS FOR WHETHER THE RESPONSE DOCUMENT IS A TAX ABATEMENT, TAX SAVINGS,
'INFRASTRUCTURE, TRAINING FUNDS OR MISCELLANEOUS TYPES, SO THAT THE CORRECT ACTUAL
'SAVINGS IN THAT PARTICULAR SECTION OF THE PARENT DOCUMENT IS POPULATED.
     
     For count = 1 To collection.count
          Set responsedoc = collection.GetNthDocument(count)
          TU = TU + responsedoc.RequestQuantity(0)
         
     Next count
     
     parentdoc.TotalLitUsed = TU
     
'SAVING THE PARENT DOCUMENT AFTER MAKING THE CHANGES.
     ret = parentdoc.Save (True, False)
     
'REFRESHING THE VIEW TO SEE THE CHANGES MADE.
     Set View = dbase.GetView("BrochuresInventory")
     Call view.Refresh
     Call workspace.viewRefresh
     
End Sub
Avatar of Sjef Bosman
Sjef Bosman
Flag of France image

Did you try the debugger? It's most likely a call to GetDocumentByUNID that fails, because the ParentID isn't a correct universalID.
Avatar of AliciaVee
AliciaVee

ASKER

sjef,

I'm not real good using the debugger :(

Assuming it is the call to GetDocumentByUNID -- what do I need to do to make this code work?
Alicia, you say you are not good with teh debugger.  Well, maybe you shoudl consider trying to get better.  It isn't hard.  The easiest way to do this is to just turn the debugger on, and when the script starts running, click CONTINUE (or press F5).  When the script fails, the line it failed on will be highlighted, so you will know what line has the problem.

If it is the GetDocumentByUNID call, you can then click on the variables tab, highlight ParentID -- because the call is to .getDocumentByUNID(ParentID) -- and see what value is there.  It should be exactly 32 characters long, and only contains numbers, and letters a-f (or A-F).

If it does match that description, then that means you have a valid UNID format, but there happens to be no document with taht UNID in the database.  So, either you picked up a bad value (which we can try to debug further), or, it picked up a good document value, but the document has not been saved yet -- so even though there is a document "in memory" with that UNID, it can't be retrieved until it is saved.
This script belongs in the child documents.  When any child document is saved, it will update the parent document with the some of it's children.  If you are placing the script in the parent document, you would make the following chage:

REMOVE:
parentID = responsedoc.ParentDocumentUNID
Set parentdoc = dbase.GetDocumentByUNID(ParentID)

ADD:
Set parentdoc = currentdoc


This could be done much cleaner/simpler, but the above should at least get you working.
qwaletee,

Wow!  Now that was cool.  When I said I'm not good with the debugger, I was using my expereince in Access (VBA) -- I always had trouble figuring out what to do...

So, I go into Notes and can you belive it took me a while to FIND the debugger and how to turn it on...ha ha.

Anyway, I checked it (which is how you turn it on -- right?) then I go into the document, and it bought me back to the code, on the following line:

Dim workspace As New NotesUIWorkspace

I then click contine (right?)

and go back to the document.  I was getting the error when I closed the document, so when I did that, I got the error in the database, after I clicked OK...it bought me back to the debugger to the following line:

Set parentdoc = dbase.GetDocumentByUNID(ParentID)

The only option I had was to Stop debugger....

So, I reviewed the code and noticed I needed to remove a few fields being declared that I didn't need.  So I removed the following from the original code:

Dim ta As Double
Dim ts As Double
Dim trf As Double
Dim inst As Double
Dim mi As Double

I then changed ta to TU (which is what I changed in the script, but I didn't declare it)
I then added a field in my response doc called ParentID, because I think I need it (right)? based on the following code:

Set parentdoc = dbase.GetDocumentByUNID(ParentID)

I sent the new field ParentID in my response doc as computed, and the value as $Ref.  I then ran a RefreshDoc agent.  In the response doc, I can see the field properties, and do see the $REF field is the same as the new ParentID field I added.

But, in doing all of this, the same error appears when I close the document.  And, when I look at the VARIABLES section of the debugger, I see that PARENTID value is ""

What to do now?


This is my current code:
-------------------------------
Sub Queryclose(Source As Notesuidocument, Continue As Variant)
      
      'DECLARING ALL THE VARABLES
      Dim count As Integer
      Dim workspace As New NotesUIWorkspace
      Dim newamount As Variant
      Dim currentdoc As NotesDocument
      Dim dbase As NotesDatabase
      Dim Session As New NotesSession
      Dim responsedoc As NotesDocument
      Dim parentdoc As notesDocument
      Dim collection As NotesDocumentCollection
      Dim parentdocitem As NotesItem
      
      Dim item As NotesItem
      Dim temp As Double
      Dim ret As Variant
      Dim view As NotesView
      
      Dim TU As Double
      Dim parentID As Variant
      
'SETTING THE VARIABLES
      Set currentdoc = source.Document
      Source.AutoReload = False
      Set dbase = session.CurrentDatabase
      Set responsedoc = source.Document
      
%REM
GETTING THE PARENT DOCUMENT'S UNIQUE ID FROM THE RESPONSE DOCUMENT AND THEN OPENS
DOCUMENT. THE COLLECTION IS SET TO BE ALL THE RESPONSES OF THE PARENT DOCUMENT.
%END REM
      
      parentID = responsedoc.ParentDocumentUNID
      Set parentdoc = dbase.GetDocumentByUNID(ParentID)
      Set collection = parentdoc.Responses
      
'LOOPING THROUGH ALL THE RESPONSE DOCUMENTS TO ADD THE ACTUAL SAVINGS. WHEN DOING THIS
'IT CHECKS FOR WHETHER THE RESPONSE DOCUMENT IS A TAX ABATEMENT, TAX SAVINGS,
'INFRASTRUCTURE, TRAINING FUNDS OR MISCELLANEOUS TYPES, SO THAT THE CORRECT ACTUAL
'SAVINGS IN THAT PARTICULAR SECTION OF THE PARENT DOCUMENT IS POPULATED.
      
      For count = 1 To collection.count
            Set responsedoc = collection.GetNthDocument(count)
            TU = TU + responsedoc.RequestQuantity(0)
            
      Next count
      
      parentdoc.TotalLitUsed = TU
      
'SAVING THE PARENT DOCUMENT AFTER MAKING THE CHANGES.
      ret = parentdoc.Save (True, False)
      
'REFRESHING THE VIEW TO SEE THE CHANGES MADE.
      Set View = dbase.GetView("BrochuresInventory")
      Call view.Refresh
      Call workspace.viewRefresh
      
      
End Sub
Oh -- one more thing, in the VARIABLES section, I see RESPONSEDOC and in the middle column is had the following:
[False, Date, Time]
with the date being today and time being when I closed the form.  So, does false mean it didn't find the response docs?
mssturgeon,

Okay. now I'm confused -- but maybe you are right and I went and put this code in the wrong document?  Ugh!  Now I went and changed fields, added, fields to try and match up with what was in the code.

Let me take a step back.  Let me explain what I want to work.  I have a Parent document.  This holds information for a specific literature.  This has a field called Inventory -- number.  I have a response doc that is used to requets malings of this literature.  This is a client database, and is only used internally.  The response doc has a field = RequestQuantity.

So, I already have a bunch of response documents with amounts that were requested of parent documents.  I thought a nightly agent would be able to do a scan of all response amounts and update a field in  my parent document called: TotalUsed. I would then have another field that is computed that shows Inventory - TotalUsed = TotalOnHand.  All of these fields would be in the Parent document.

So, now I made changes and have the following 'added' fields in both documents:

Parent Document:
DocInventory - this holds the current inventory
TotalUsed - will hold the value that I want entered in via script
ParentID - is hidden, and computed, with the following code: @Text(@DocumentUniqueID)

Response Document:
DocID - computed with the following code: @Text(@DocumentUniqueID)
ParentDocumentUNID - computed with the following code $REF (I know I probably don't need this -- right?)

So, now what can I do to get this working?  I was really looking for a script, but if this works, I'll be so happy!
Here's the script to run from the parent document to sum its children (responses):

--- BEGIN
Dim children as NotesDocumentCollection
Dim child as NotesDocument
Dim TU as Integer

Set currentDoc = Source.Document
Set children = currentDoc.Responses
Set child = children.GetFirstDocument
TU = 0
Do (until child is nothing)
   TU = TU + child.GetItemValue("RequestQuantity")(0)
   Set child = children.GetNextDocument(child)
Loop

Call currentDoc.ReplaceItemValue("TotalUsed", TU)
Call currentDoc.Save(true, false)
--- END

Note: You may want TU ro be a Long datatype rather than an Integer if this number will be large.

This script can be run either in QueryClose or QuerySave.
oops ... small error:

Do (until child is nothing)

should be ...

Do Until (child is nothing)



Of course, the parenthesis are just for looks ... not needed but I use them out of habit.
mssturgeon,

This is just too cool!  Yep, it works beautifully.  I can't believe how little code you provided, compared with what I started with.  Thanks so very much!

qwaletee,
Thanks for showing me around the debugger -- I will use it from now on, even though I'm not sure how to trouble shoot the code, I will start to try and read more aobut LS and how to handle errors.

AliciaVee
mssturgeon,

Oh...one more question. Will this code still work okay regardless of what type of document access the user opening the document has?  In other words, most users will only have read access to the main document.  If a person with Read access opens the document, upon close -- will they receive an error if the code is trying to write to the document?

And lastly -- in thinking this through, on what you mentioned that this code should have been on the child -- I can see why  that is the case (now).  If I have a document that is not opened by the user, and a user requests literature mailed and never opens the document, how will the value change (be updated) once a user (or several users) submit requests on that particular Parent document?  Yikes -- this could be a problem huh?  How can I reverse and put the code in the child -- sorry -- unless I have nothing to worry about?  Are you following me?

AliciaVee
ASKER CERTIFIED SOLUTION
Avatar of mssturgeon
mssturgeon

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
mssturgeon,

Darn....I got the following error:

"Variant does not contain an object"

And the debugger has stopped on this line:

Set parentDoc = session.CurrentDatabase.GetDocumentByUNID(currentDoc.ParentDocumentUNID)

Do you think the error has anything to do with the fact that I created a field named ParentDocumentUNID ??  Should I removed that field?
You probably just need to
Dim session = New NotesSession

If you've done the above already, then yes ... remove that field ... it could be causing the problem.

You could also try splitting the line:
Set currentDB = session.CurrentDatabase
Set unid = currentDoc.ParentDocumentUNID
Set parentDoc = currentDB.GetDocumentByUNID(unid)

... it would give us more information about which piece is causing the error.

Cheers,
- Shane
Shane,

Works great!  Yay!

My final code is below.  I think you meant
Dim Session As New NotesSession (not =)

And, I didn't change those 3 lines, because I wasn't sure how to split it.  The code is working, so should I be concerned, and if so, how would you suggest breaking it up?

My Current 'working' code is as follows -- stored in the RESPONSE doc
----------------------------------------------------------------------------------------

Sub Querysave(Source As Notesuidocument, Continue As Variant)
      
      Dim session As New NotesSession
      Dim children As NotesDocumentCollection
      Dim child As NotesDocument
      Dim TU As Integer
      
      Set currentDoc = Source.Document
      
' the following line was not in its "parent" version
      Set parentDoc = session.CurrentDatabase.GetDocumentByUNID(currentDoc.ParentDocumentUNID)
      
' the following line was altered slightly from its "parent" version
      Set children = parentDoc.Responses
      
      Set child = children.GetFirstDocument
      TU = 0
      Do Until (child Is Nothing)
            TU = TU + child.GetItemValue("RequestQuantity")(0)
            Set child = children.GetNextDocument(child)
      Loop
      
' the following line were altered slightly from their "parent" version
      Call parentDoc.ReplaceItemValue("TotalUsed", TU)
      Call parentDoc.Save(True, False)      
End Sub
No need to split it up, I was only suggesting it to help with the debugging, if need be.

Keep in mind that whomever might edit the "child" documents would need editor access to the parent as well.

Cheers,

- Shane
Got it Shane -- thanks so much!

AliciaVee
Hi Alicia, sorry I left early. The problem is solved, you learned to use the debugger, so all in all it must have been a wonderful day. :)

And, welcome Shane! Can you update your EE-profile, with anything you like? Just to provide some background info?
Done.