Thursday, November 09, 2006

SNTT - Calling an agent using RunOnServer when saving a new document

Enough of the politics, let's have even more RunOnServer fun! Let's say that when a user saves and closes a document you want to update the newly saved document with information from an agent. RunOnServer takes a NoteID so it looks like a no brainer. In reality it proved to be more a little more difficult.

The first hurdle: I started out using the QuerySave event and the NoteID was always 0. I dug into the Notes.Net developerWorks Notes forum and learned that the NoteID doesn't exist until the document is saved to the hard drive. Okay, I'll use the PostSave event. Since it's called "PostSave" I expected the document to be saved to disk. Well, either it isn't or the PostSave event occurs before the NoteID is populated. The solution: force the document to save from PostSave. I'm not sure why this forced save is necessary, but it works. Calling doc.Save from QuerySave gave a save conflict warning, but calling it from PostSave doesn't.
Sub Postsave(Source As Notesuidocument)
Dim session As New NotesSession
Dim db As NotesDatabase
Dim agent As NotesAgent
Dim doc As NotesDocument

Call Source.Document.Save(True, False)
Set doc = Source.Document
Set db = session.CurrentDatabase
Set agent = db.GetAgent("Process Service Fees")

If agent.RunOnServer(doc.NoteID) <> 0 Then
Msgbox "There was an error and the service fee notice was not sent.", 48, "Service Fees"
End If
End Sub
This LotusScript was converted to HTML using the ls2html routine,
provided by Julian Robichaux at nsftools.com.

,

8 comments:

  1. Nice solution but wont that mean that the document is actually saved twice? Does the $UpdatedBy field contain two values?

    ReplyDelete
  2. $UpdatedBy only has one entry, but $Revisions has two with the same timestamp. Pardon my ignorance, but is it a problem that the document is saved twice?

    ReplyDelete
  3. Wouldn't it be better to put the code into the QueryClose event, with a flag to run it in the PostSave event. At QueryClose the NOTEID has been set and can be used even on new documents.

    ReplyDelete
  4. David, PostSave happens before QueryClose. Flipping the logic around, you could create a flag in PostSave that you reference in QueryClose and do the lookup there instead. That would prevent the second save and cluttering the $Revisions field, and should also get around the save conflict. I'll test that, thanks for the suggestion.

    ReplyDelete
  5. QueryClose doesn't work too.

    Solution is:

    Sub Postsave(Source As Notesuidocument)

    Dim agent As NotesAgent
    Dim doc As NotesDocument
    Set doc=source.Document.ParentDatabase.GetDocumentByUNID(source.Document.UniversalID)
    Set agent = source.Document.ParentDatabase.GetAgent("(update_statuss)")
    Call agent.RunOnServer(doc.NoteID)

    End Sub

    ReplyDelete
  6. In QueryClose the Source.Document object does not yet know its NoteID, but if you retrieve the backend document via
    set doc=source.Document.ParentDatabase.GetDocumentByUNID(source.Document.UniversalID)
    (as Dreicha suggested) then doc.NoteID will be correct.

    ReplyDelete
  7. I was trying with your code but still NoteID 0, nothing was generated. Can someone please help me.??

    ReplyDelete
  8. I was trying with your code but still NoteID 0, nothing was generated. Can someone please help me.??

    ReplyDelete