%REM Copyright Joe Litton. http://joelitton.net You are free to use this code, provided you do not claim it as your own work. Use this code at your own risk; there are no guarantees whatsoever. It is your responsibility to fully test this code before using in production. This code, when added to a form, will help you maintain an audit trail of changes made to any field. Instructions: 1. Add a Computed When Composed field on the form. Call the field 'HistoryLog', and set it's value to be 'HistoryLog' (without the quotes). This field gets populated programmatically. 2. Add the code below to the (Globals) (Options), (Globals) (Declarations), and to the form's PostOpen and QuerySave events. 3. Be sure to edit the list of fields to skip; the list is in the PostOpen event. %END REM ' (Globals) (Options) Option Public Option Explicit '(Globals) (Declarations) Dim ws As NotesUIWorkspace Dim session As NotesSession Dim db As NotesDatabase Dim uidoc As NotesUIDocument Dim doc As NotesDocument Dim saveFields List As String ' List that will store existing values of all fields (all doc items) Dim dontCheckFields List As String ' List of fields that we don't bother to check for changes Sub Postopen(Source As Notesuidocument) Set ws = New NotesUIWorkspace Set session = New NotesSession Set db = session.CurrentDatabase Set uidoc = ws.CurrentDocument Set doc = uidoc.Document ' Cycle through all items (fields) in the doc and store the value to an element in the saveFields list. ' Note that we only store the zero element. You could also store the item.Text or other value, depending ' on your needs. Forall i In doc.items saveFields( Ucase(i.Name) ) = i.values(0) End Forall ' Populate list of fields that we don't bother to check when logging changes to audit trail dontCheckFields( "FIRSTFIELDTOSKIP" ) = "" dontCheckFields( "SECONDFIELDTOSKIP" ) = "" dontCheckFields( "ANOTHERFIELDTOSKIP" ) = "" End Sub Sub Querysave(Source As Notesuidocument, Continue As Variant) ' Store a history log of <almost> all changes to the doc's fields. Store the history log in ' reverse chronological order. Dim itmTemp As NotesItem Dim strNow As String Dim strUser As String Dim strNewValue As String Dim strTemp As String Dim strArray() As String Dim historyArray() As String Dim intIndex As Integer Dim intArraySize As Integer Dim j As Integer Dim strUName As String ' Set up variables used in each line of the history log. strNow = Cstr(Now) strNow = Format( strNow, "mm/dd/yyyy hh:mm AM/PM" ) strUser = session.CommonUserName ' Save any existing content of the history log. Save it in true chronological order. intArraySize = -1 If doc.HistoryLog(0) <> "" Then Set itmTemp = doc.GetFirstItem("HistoryLog") Forall v In itmTemp.Values intArraySize = intArraySize + 1 End Forall Redim strArray( intArraySize ) As String intIndex = 0 For j = intArraySize To 0 Step -1 strArray( intIndex ) = itmTemp.Values( j ) intIndex = intIndex + 1 Next End If intIndex = intArraySize ' Create an audit line for any field that has changed. For now, store the audit line in a temp array. Forall i In doc.Items strUName = Ucase(i.Name) If Iselement( dontCheckFields( strUName )) Then ' Skip this field; we don't keep an audit trail on it. Else If saveFields( strUName ) <> i.Values(0) Then strTemp = strNow & " " & strUser & " changed field <" & i.Name _ & "> from <" & saveFields( strUName ) & "> to <" & i.Values(0) & ">" intIndex = intIndex + 1 Redim Preserve strArray( intIndex ) As String strArray( intIndex ) = strTemp saveFields( strUName ) = i.Values(0) End If End If End Forall ' Now recreate the HistoryLog field, storing audit trail lines so that most recent changes appear first. If intIndex > -1 Then ' There's at least one history line intArraySize = intIndex Redim historyArray( intArraySize ) As String intIndex = 0 For j = intArraySize To 0 Step -1 historyArray( intIndex ) = strArray( j ) intIndex = intIndex + 1 Next doc.HistoryLog = historyArray End If End Sub
This LotusScript was converted to HTML using the ls2html routine,
provided by Julian Robichaux at nsftools.com.