[back to
Generating sequential numbers in replicated applications
]
The AutoNumberGet function
Public Function AutoNumberGet (strANView As String, strANKey As String, strANField As String, strANServer As String, bFailProof As Variant) As Long
'Retrieves and reserves a sequential number for the code that calls it.
'Requirements:
'- You must have a lookup view containing at least one "AutoNumbering" control doc. (A doc with a text field containing
' a number to be incremented as each AutoNumber is generated.)
'- The calling code must save the returned number into the document that is being numbered.
'- If your numbering scheme rolls over every year, you must check/handle this before calling AutoNumberGet.
'Parameters:
'- strANView: the view containing the Autonumbering control doc
'- strANKey: the key that will find it
'- strANField: the field containing the number
'- strANServer: the central server that can assign numbers (or "" if any server will do)
'- bFailProof: enable/disable the Fail Proof feature (if disabled, save conflicts will generate an error)
'Returns:
' The number currently listed as "Next Number" in the AutoNumbering control doc.
' OR a negative error code number:
' - C_AN_WRONG_SERVER if the current server cannot assign numbers (Not a problem, but it might mean that your agent is running on the wrong server.)
' - C_AN_NO_COUNTER if the counter doc doesn't exist (The calling code could create the Autonumbering control doc and call AutoNumberGet again.)
' - C_AN_NO_ACCESS if the current user doesn't have access to update the counter
' - C_AN_UNKNOWN_ERROR if an unexpected error occurs (e.g. if Notes raises an error, or the "docANCounter.save" command fails).
'Side Effects:
'- if successful, the value in the AutoNumbering control doc is incremented.
'Possible Enhancements:
'- Reduce the number of necessary parameters by passing in docANCounter instead of strANView and strANKey.
' Instead of reloading docANCounter from the view during each FailProof iteration, get its UniversalID and reload it
' using GetDocumentByUNID. This way the counter could be kept in a profile doc if desired.
Dim s As New NotesSession, db As NotesDatabase, vwAN As NotesView, docANCounter As NotesDocument
Dim varANValue As Variant, lngANValue As Long, itemNewAN As NotesItem
Dim bSuccess As Variant, bKeepLooping As Variant
Dim iReturn As Long
iReturn = C_AN_UNKNOWN_ERROR 'Always assume the worst
On Error Goto tagError 'Disable this line if you prefer to handle unexpected errors in the calling code instead of receiving C_AN_UNKNOWN_ERROR.
On Error 4000 Goto tagError4000
Set db = s.CurrentDatabase
Set vwAN = db.GetView(strANView)
bSuccess = False
bKeepLooping = True
If (strANServer <> "") And (db.server <> strANServer) Then
'Check server is enabled, and this server cannot assign numbers
iReturn = C_AN_WRONG_SERVER
bKeepLooping = False
End If
'If Fail Proof is enabled, keep looping until an number is successfully reserved. Never give up!
Do While bKeepLooping And (Not bSuccess)
bKeepLooping = bFailProof
'Get the Autonumbering control doc
Set docANCounter = vwAN.GetDocumentByKey (strANKey, True)
If docANCounter Is Nothing Then 'Does the Autonumbering control doc exist?
bKeepLooping = False
iReturn = C_AN_NO_COUNTER 'Error: Counter doc doesn't exist
Else
varANValue = docANCounter.GetItemValue( strANField )
lngANValue = Clng( varANValue(0) )
If lngANValue <= 0 Then
bKeepLooping = False
iReturn = C_AN_UNKNOWN_ERROR
Else
Set itemNewAN = docANCounter.ReplaceItemValue ( strANField, Cstr(lngANValue+1) ) 'increment the number by one
If docANCounter.save(False,False) Then 'attempt to save the counter doc
iReturn = lngANValue
bSuccess = True
Else
'A replication/save conflict occurred. Fail. Or if bFailProof is enabled, start over.
End If
End If
End If 'Does the Autonumbering control doc exist?
Loop
tagExit:
AutoNumberGet = iReturn
Exit Function
tagError:
Print "Error #" + Cstr(Err) + ": " + Error$
Resume tagExit
tagError4000:
bKeepLooping = False
iReturn = C_AN_NO_ACCESS 'Error: Unable to save counter doc
Resume tagExit
End Function 'AutoNumberGet