This Blog has moved to

False Positives Adventures in Technology, SciFi and Culture from Toronto

Wednesday, March 31, 2004

Getting around Lotus Notes Domino (Web) Error 4354: Cannot remove NotesDocument when it is the Document Context

Deleting Domino Doc's

In the process of doing some work I came across this problem, and after searching / googling the usual suspects did not find a resolution, until I remembered how I done this in the past. I'm going to document my solution as a aid to other and for the next time I have a brain freeze.

This works for Lotus Notes Domino R5.x.

When does this error occur : When doing Domino Web work, the easy, standard, way of executing a agent from a Web Form is to create a formula hotspot or button with the formula : @Command([ToolsRunMacro]; "myAgent") Which will execute the "myAgent" Agent, and the other half of this is have LotusScript code along the lines of :

Sub Initialize

Dim session As New NotesSession
Dim sessiondb As NotesDatabase
Set sessiondb = session.CurrentDatabase

Dim sessionDoc As notesDocument
Set sessionDoc = session.DocumentContext
........' the rest of the code

Now after doing what ever other stuff you what / need to do, you what to delete the Document from which you called the agent so you :

Call sessionDoc.remove(True)

Which would do ordinarily do exactly that, but this time blows up and doesn't remove the document. ACK!

After trying a few things and then RTFM'ing, I discover that at the end of the help page for DocumentContext property it says :

You cannot use the encrypt and remove methods on the Document object returned by DocumentContext...

So, I'm SOL, right? Not so fast....

I've got 2 ways around this:

1) rather that do a remove in the first agent, mark it with a status indicating it needs to be deleted...

Set sessionDoc.Status = "DeleteMe"
Call sessionDoc.Save ( True, False )

The Documents can either be manually deleted (from a Lotus client and special view, by the appropriate user) or you can create a scheduled agent to do a search for document marked for deletion and zap them. Like this....

Dim tmpDoc as NotesDocument
Dim Doc As NotesDocument
Dim Dc As NotesDocumentCollection
Dim searchFormula As String
searchFormula = |SELECT Status="DeleteMe"|
Set DC = db.Search( searchFormula, Nothing, 0 )
Set Doc = DC.GetFirstDocument
Do While Not(Doc Is Nothing )
Set tmpDoc = Doc
Set Doc = DC.GetNextDocument( Doc )
Call tmpDoc.remove(True)

Two additional things 2 keep in mind. Make sure any user views or lookups wouldn't find the document marked with the sessionDoc.Status = "DeleteMe". Run the actual delete agent as often as needed or a server resources allow.

I don't like the above solution because I need to worry about the showing up where it shouldn't or going though any views might show the document. For a existing application, there is a risk that a deleted document will be visible. The other reason I don't like it is because It requires an higher level user to remember to open a view to manually delete (and I'm busy enough as it is) or the server resources to run yet another scheduled agent (and the servers are the only thing busier than me).

2) The workaround is to invoke the agent another way, to modify the agent to make it to work by NOt using the @Command([ToolsRunMacro]; "myAgent") Command and the DocumentContext property.

Rather, Launch the agent via it url (either building a HREF or using @URLOpen("pathtoMyAgent/MyAgent?OpenAgent&ID=123"), pass on the url line a ID to the document, then within Agent, parse the url to get the Id and do a look to get the NotesDocument which is then removable.

I'll post some code to parse the url line paramters shortly. A quick google failed to find anything useful. Hopeful this will save the life of some newbie.

Update : here that promised code: Very simple LotusScript function to parse value on url line. enjoy.

Please Note that this Blog (False Positives) has moved to