API
@-Formulas
JavaScript
LotusScript
Reg Exp
Web Design
Notes Client
XPages
 
Document Locking and ws.EditDocument
I haven't used document locking very much, but one customer insisted on it. Then, after implementing document locking, I ended up with a bunch of replication/save conflicts. Some of the conflicts even had a created date AFTER the last modified date and NOBODY listed in the Modified By, like in figure 1. I did not touch up that image at all. So, what was the problem?

It turns out that it was the way I was creating my document that was the problem. To show the situation in action, you have to enable document locking on a test database somewhere. There's all kinds of documentation about document locking - I won't get into that here. But the basics are that you need an administrative server and you need to enable document locking in the database properties.

Once you have document locking enabled, create a test form with some editable fields on it. Next, create an agent that "composes" the test form. I put "composes" in quotes because this is the key to the whole problem. The agent should be run manually from the actions menu with no target. Here's some sample code:

Sub Initialize
   Dim ws As New NotesUIWorkspace
   Dim session As New NotesSession
   Dim db As NotesDatabase
   Dim doc As NotesDocument
   
   Set db = session.CurrentDatabase
   Set doc = db.CreateDocument
   Call doc.ReplaceItemValue("Form", "My Form")
   Call ws.EditDocument(True, doc)
End Sub

NOTE: This is an over-simplified version of the code. If this was truly all I was doing, @Command([Compose]; "My Form") would be a much better way to go. My actual code has additional checking, additional prompts, and sets other hidden fields on the document before opening it up for edit. The above code is all you need to demonstrate the situation, though.

The agent creates a new back end document, sets the form (change "My Form" to the name of your test form) and then opens the document for editing. Run the agent and you'll see your test form opened for you.

Put some values in your test document and then press CTRL+S or go to File | Save. Don't close the document. Change some values or put some more data and save the document again. At this point you'll be prompted about creating a conflict. If you say "Yes" to create the conflict, the properties of the conflict document will be similar to those shown in figure 1 - the created date will be after the last modified date and there will be no $UpdatedBy field (which is why the "Modified By" value is blank).

So what's the problem? Not knowing the actual C code behind document locking, I can only make guesses. But it has to do with document locking - if you disable document locking on your database, the above steps don't cause a conflict. In order to get this situation to not cause a conflict, you have to lock the document manually in your code. But you can't lock a brand new document - you'll get an error. Here's how I had to change my code:

Sub Initialize
   Dim ws As New NotesUIWorkspace
   Dim session As New NotesSession
   Dim db As NotesDatabase
   Dim doc As NotesDocument
   
   Set db = session.CurrentDatabase
   Set doc = db.CreateDocument
   Call doc.ReplaceItemValue("Form", "My Form")
   If db.IsDocumentLockingEnabled Then
      Call doc.Save(True, False, True)
      Call doc.Lock
   End If
   Call ws.EditDocument(True, doc)
End Sub

The difference now is that I check for document locking being enabled on the database. If it is, then I save the document that was just created, put a lock on it, and then open it up for edit mode.

The ws.EditDocument command will now print a message in the status bar: "You already have the document locked". That command is trying to lock the document, but the LotusScript code had already locked it.

Please note that this code is specific to brand new documents. But, just to be safe, my application now checks for document locking and then puts a lock on the document whenever it's being opened up in edit mode through script. Getting the extra message saying the document is already locked is not an issue - I can be sure the document is locked and that cuts down on the conflicts.

One final item to point out. If you take the second block of code above and comment out the doc.Lock statement, you will get a replication/save conflict immediately when saving the document. This is because the ws.EditDocument statement opens a new instance of the document (so there's technically two instances). There's a parameter to tell the Notes client to open the existing instance. So that last line of code could read:
   Call ws.EditDocument(True, doc, , , , False)

This will both lock the document and open it up for edit and you won't get a conflict. However, if you try to open up the existing instance without saving the document first, Notes will open up the default form in the database (the line that sets the form is ignored). So my code looks like the second block above - if document locking is enabled, then lock the document and use the "old fashioned" edit document method.