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.
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.
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.
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
If Not Source.IsNewDoc Then
‘Rember values before editing.
orgValues(“Status”) = Source.Document.Status(0)
If orgValues(“Status”) = “30” Then
‘Do something depending on previous status.
‘You could undo status change if validation fails
.Status = orgValues(“Status”)