How to detect changes in fields on a form

A question I have seen a few times in the developerWorks forums is how to detect what values (often names) have been added in a multi-value field.

This is not very difficult to do in Lotusscript, and there are a few different ways to do it. I prefer to use lists, but you can of course use arrays as well. The basic idea is to declare a global variable to hold the initial value of the field, populate it when the document is either opened or put into edit mode, and then checked when the document is saved.

Globals:
Dim oldValue List As String

PostModeChange:
Dim oldarray as Variant
'*** Create array, assume ; as item separator in field
oldarray = Split(uidoc.FieldGetText("myMultiValueField"),";")
'*** Build a list of values
ForAll o in oldarray 
    oldValue(o) = o 
End ForAll

QuerySave: 
Dim newarray as Variant
Dim newValue List As String
'*** Create array, assume ; as item separator in field
newarray = Split(uidoc.FieldGetText("myMultiValueField"),";")
'*** Compare with values in list
ForAll n in newarray
    '*** Check if value is not in global list, then it is new
    If IsElement(oldValue(n)) = False Then
        newValue(n) = n    ' Add new value to list
    End If
End ForAll
'*** Loop through all new values and print them
ForAll nv in newValue 
    Print nv + " is new." 
End Forall
 

The same technique can be used to detect what fields have changed since the document was opened. Just store the values of all fields (except any starting with $) in a list, then check the values in the fields against that list when saving the document.

 
Globals:
Dim oldValue List As String

QueryOpen:
'*** Build a list of values with field name as listtag
ForAll i in doc.Items 
    If Left$(i.Name,1)<>"$") Then
        oldValue(i.Name)=i.Text
    End If
End ForAll

QuerySave: 
Dim modified List As String
Dim tmpValue As String
'*** Compare current fields with values in list
ForAll o in oldValue 
    '*** Check if value is the same or not
    tmpValue = uidoc.FieldGetText(Listtag(o))   ' Get current field value
    If tmpValue <> o Then
        modified(ListTag(o))=tmpValue    ' Add new value to list of modified fields
    End If
End ForAll
'*** Loop through all modified fields and display new value
ForAll m in modified
    Print Listtag(m) + " was changed from " + oldValue(Listtag(m)) + " to " + m
End Forall
  

All very easy when you know how to do it. And again, it shows the power of lists.

This Post Has 3 Comments

  1. Jesper Kiaer

    So has a field changed if only the (sorting) order has changed?? 🙂

    If two multi-value fields are to be compared the lists should actually be sorted first I would suggest.

    /Jesper Kiaer
    Jezzper Consulting

    1. Karl-Henry Martinsson

      Well, depends on the application. In some, you may want to update the backend or another system if the order changes. I have applications like that.
      In other applications it doesn’t matter.

  2. Fredrik Malmborg

    I use something like it. Not to track any change, but to specific changes.

    A simple example that with a status field:

    Dim orgValues List As String

    FormPostOpen
    If Not Source.IsNewDoc Then
    ‘Rember values before editing.
    orgValues(“Status”) = Source.Document.Status(0)
    End If

    QuerySave:
    If orgValues(“Status”) = “30” Then
    ‘Do something depending on previous status.
    End If

    ‘You could undo status change if validation fails
    .Status = orgValues(“Status”)

Leave a Reply