Subject: RE: Not perfect solution- but working !
Tim -
I debated as to whether or not I should post this code. I’m sometimes a little too quick to adopt a “throw-more-code-at-it” approach. In any case, I wrote these functions to help deal with some of the behavioural nuances of using the native document locking feature introduced in ND6 (although I haven’t come across the specific problem mentioned here).
dgg
Public Function isDocumentLocked(pdoc As NotesDocument) As Boolean
'// +++ GLOBAL VARIABLES +++
'// Constants:
'// LIB_NAME = name of this library
'//
'// Class instances:
'// none
'//
'// Primitives:
'// none
'//
'// 11/10/2003 - Dallas Gimpel
'//
'// DESCRIPTION:
'// Given a handle to a backend document, examines the document’s Lockholders property to
'// determine whether or not the document is locked.
'//
'// INPUT:
'// pdoc - NotesDocument, handle to the document to be examined
'//
'// OUTPUT:
'// function returns a boolean - true if the document passed in is locked (as indicated
'// by the lockholders), otherwise false.
On Error Goto errorHandler
Const CODE_ELEMENT$ = "isDocumentLocked function"
Dim varLockHolders As Variant
isDocumentLocked = False
If Not(pdoc Is Nothing) Then
varLockHolders = pdoc.LockHolders
If Len(varLockHolders(0)) > 0 Then
isDocumentLocked = True
End If
End If
functionExit:
Exit Function
errorHandler:
Call processUIError(CODE_ELEMENT & " / " & LIB_NAME)
Resume functionExit
End Function
Public Function applyLock(pdoc As NotesDocument, pstrUName As String) As Boolean
'// +++ GLOBAL VARIABLES +++
'// Constants:
'// LIB_NAME = name of this library
'//
'// Class instances:
'// none
'//
'// Primitives:
'// none
'//
'// 05/03/2004 - Dallas Gimpel
'//
'// DESCRIPTION:
'// This function is just a helper for the Lock method of the NotesDocument class. It is
'// just a more consistent way of locking a document without causing unnecessary errors
‘// to be raised. Unlike Lotus’ implementation, this function just returns true if the
'// document was successfully locked and suppresses (known) possible errors.
'//
'// INPUT:
'// pstrUName - String, the user name to be used when locking a given document
'//
'// OUTPUT:
'// Function returns a boolean (true if successfull, otherwise false).
On Error Goto errorHandler
Const CODE_ELEMENT = "applyLock function"
Const ERR_DOC_MODIFIED = 4579 '// error text: Unable to lock - Note has been modified since opening
Const ERR_DOC_IS_LOCKED = 4595 '// error text: Note is already locked by someone else
applyLock = False
If Len(pstrUName$) > 0 Then
If pdoc.Lock(pstrUName$, False) Then
applyLock = True
End If
Elseif pdoc.Lock() Then '// if empty string is passed, use defaults
applyLock = True
End If
functionExit:
Exit Function
errorHandler:
Select Case Err
Case ERR_DOC_MODIFIED
Print Error$
Case ERR_DOC_IS_LOCKED
Print Error$
Case Else
Call processUIError(CODE_ELEMENT & " / " & LIB_NAME)
End Select
Resume functionExit
End Function
Public Function removeLock(pdoc As NotesDocument, pstrUName As String) As Boolean
'// +++ GLOBAL VARIABLES +++
'// Constants:
'// LIB_NAME = name of this library
'//
'// Class instances:
'// none
'//
'// Primitives:
'// none
'//
'// 05/03/2004 - Dallas Gimpel
'//
'// DESCRIPTION:
'// This function is just a helper for the Unlock method of the NotesDocument class. It
'// is just a more consistent way of unlocking a document without causing unnecessary
'// errors to be raised when a given user is not among the lock holders of the document.
'// This helps in suppressing unnecessary errors.
'//
'// INPUT:
'// pstrUName - String, the user name to be evaluated before unlocking a given document
'//
'// OUTPUT:
'// pdoc - NotesDocument, the document to be unlocked
'// Function returns a boolean (true unless an error is encountered).
On Error Goto errorHandler
Const CODE_ELEMENT = "removeLock function"
removeLock = False
If Isnumeric(Arraygetindex(pdoc.LockHolders, pstrUName$, 5)) Then
Call pdoc.UnLock()
End If
removeLock = True
functionExit:
Exit Function
errorHandler:
Call processUIError(CODE_ELEMENT & " / " & LIB_NAME)
Resume functionExit
End Function
Public Function lockDocumentCollection(pdclxnTarget As NotesDocumentCollection) As Boolean
'// +++ GLOBAL VARIABLES +++
'// Constants:
'// LIB_NAME = name of this library
'//
'// Class instances:
'// none
'//
'// Primitives:
'// none
'//
'// 05/04/2004 - Dallas Gimpel
'//
'// DESCRIPTION:
'// This function iterates through a given NotesDocumentCollection and attempts to lock
'// each member document. If at any point, the attempt to lock a document fails, the
'// function unlocks any documents that were locked.
'//
'// NOTE:
'// This function is particularly useful when preparing to use the RemoveAll or StampAll
'// methods of NotesDocumentCollection.
'//
'// INPUT:
'// none
'//
'// OUTPUT:
'// pdclxnTarget - NotesDocumentCollection, the document collection to be locked
'// Function returns a boolean (true ONLY if all documents are successfully locked, otherwise false).
On Error Goto errorHandler
Const CODE_ELEMENT$ = "lockDocumentCollection function"
Dim nsess As NotesSession
Dim doc As NotesDocument
Dim x As Long
Dim lngClxnCount As Long
Dim lngLockCount As Long
Dim strUName As String
lockDocumentCollection = False
Set nsess = New NotesSession
lngClxnCount& = pdclxnTarget.Count
lngLockCount& = 0
strUName$ = nsess.UserName
'// Attempt to lock all documents in the collection.
If lngClxnCount& > 0 Then
Set doc = pdclxnTarget.GetFirstDocument()
For x = 1 To lngClxnCount&
If applyLock(doc, strUName$) Then
lngLockCount& = lngLockCount& + 1
Else
Exit For
End If
Set doc = pdclxnTarget.GetNextDocument(doc)
Next x
End If
lockDocumentCollection = (lngClxnCount& = lngLockCount&)
functionExit:
'// Enforce an “all-or-none” rule - if ALL documents were not locked successfully, we
'// unlock any that were.
If Not(lockDocumentCollection) Then
If Not(pdclxnTarget Is Nothing) Then
If lngLockCount& > 0 Then
Set doc = pdclxnTarget.GetFirstDocument()
For x = 1 To lngLockCount&
Call removeLock(doc, strUName$)
Set doc = pdclxnTarget.GetNextDocument(doc)
Next x
End If
End If
End If
Exit Function
errorHandler:
Call processUIError(CODE_ELEMENT & " / " & LIB_NAME)
Resume functionExit
End Function
Public Function unlockDocumentCollection(pdclxnTarget As NotesDocumentCollection) As Boolean
'// +++ GLOBAL VARIABLES +++
'// Constants:
'// LIB_NAME = name of this library
'//
'// Class instances:
'// none
'//
'// Primitives:
'// none
'//
'// 05/04/2004 - Dallas Gimpel
'//
'// DESCRIPTION:
'// This function iterates through a given NotesDocumentCollection and attempts to unlock
'// each member document by way of the “removeLock” function. Since all known erorrs are
'// trapped in the removeLock function, we call the function without checking its return
'// value. This way processing continues even if a single document can’t be unlocked.
'//
'// INPUT:
'// none
'//
'// OUTPUT:
'// pdclxnTarget - NotesDocumentCollection, the document collection to be unlocked
'// Function returns a boolean (true unless an error is encountered here).
On Error Goto errorHandler
Const CODE_ELEMENT$ = "unlockDocumentCollection function"
Dim nsess As NotesSession
Dim doc As NotesDocument
Dim x As Long
Dim lngClxnCount As Long
Dim strUName As String
unlockDocumentCollection = False
Set nsess = New NotesSession
lngClxnCount& = pdclxnTarget.Count
strUName$ = nsess.UserName
'// Attempt to lock all documents in the collection.
Set doc = pdclxnTarget.GetFirstDocument()
If lngClxnCount& > 0 Then
For x = 1 To lngClxnCount&
Call removeLock(doc, strUName$)
Set doc = pdclxnTarget.GetNextDocument(doc)
Next x
End If
unlockDocumentCollection = True
functionExit:
Exit Function
errorHandler:
Call processUIError(CODE_ELEMENT & " / " & LIB_NAME)
Resume functionExit
End Function