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.

,

6 comments:

Mikkel Heisterberg said...

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

Charles Robinson said...

$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?

David said...

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.

Charles Robinson said...

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.

Dreicha said...

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

Jens Polster said...

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.