Multi-value fields are one of the core features of Lotus Notes and Domino. Creating these fields on a form is simple within Domino Designer. Once a field is defined as multi-value, it is easy for users to add a value to the field -- just type a comma or semicolon, and then enter the new value. But performing the same operation within Lotuscript is tricky, especially if the field is not text type. This tip shows you how to do just that.
If the field in question is text, adding to it from Lotuscript is straightforward, using a method that is designed specifically for this task. Consider this code:
Const PERSONS_FIELD = "Persons" Dim ThisDoc As NotesDocument Dim Field As NotesItem 'Add this user to the list of previous users. If ThisDoc.HasItem(PERSONS_FIELD) Then Set Field = ThisDoc.GetFirstItem(PERSONS_FIELD) Call Field.AppendToTextList (User) Else Call ThisDoc.ReplaceItemValue(PERSONS_FIELD, User) End If
The LotusScript code snippet assumes that you have already initialized the NotesDocument object named ThisDoc. The code then checks to see if the designated field exists. If it does, it calls the method NotesItem.AppendToTextList, to add a new name to the end of the field. If the field does not exist, the code creates it with an initial value, using NotesDocument.ReplaceItemValue.
The LotusScript code for text fields is so simple that it is not worth writing a technical tip about. But suppose you want to do the same thing for a time-date or number field? This should be easy, with methods called NotesItem.AppendToTimeField and AppendToNumberField. Unfortunately, these methods do not exist.
Here is the same code snippet, but modified to handle time-date fields:
Const TIMES_FIELD = "CallTimes" Dim NewTimeList () As Variant Dim NewTime As Variant Dim OldTimeList As Variant Dim i As Integer 'Does field exist? If ThisDoc.HasItem(TIMES_FIELD) Then 'Yes, it exists, get it. Set Field = ThisDoc.GetFirstItem(TIMES_FIELD) 'Is the field time type? If Field.Type = DATETIMES Then 'Yes, it is time, get contents of field. OldTimeList = Field.Values 'Build an array of all existing values. i = 0 Forall s In OldTimeList Redim Preserve NewTimeList(i) NewTimeList(i) = s i = i+1 End Forall 'Add new value to end of array. Redim Preserve NewTimeList(i) NewTimeList (i) = NewTime 'Rewrite field with appended value Call ThisDoc.ReplaceItemValue(TIMES_FIELD, NewTimeList) 'Field is not time type, fix by setting it to this time Else Call ThisDoc.ReplaceItemValue(TIMES_FIELD, NewTime) End If 'Field does not exist, set it to this time Else Call ThisDoc.ReplaceItemValue(TIMES_FIELD, NewTime) End If
Adding to a time-date multi-value field must account for several situations. First, the field may not exist, just as with text fields. Next, the field may exist, but contain something other than a time-date value. This is actually quite common, since Lotus Notes has an annoying habit of initializing time-date and number fields to the null string before you enter a real value.
If you try to append a new value to a time-date field that contains a null string, you will have a lot of problems, since the existing value is not a valid time-date. And we need code for the normal case, an existing field with legal values in it.
The LotusScript code sample above assumes that the time variable NewTime is initialized with a valid time, perhaps with the statement NewTime=Now.
The central part of the code is the Forall loop, which reads each value in the existing field and adds it to an array. Because we don't know the number of values in the field, we must Redim the array for each new value, being careful to use the Preserve option (so values already in the array are not lost). After we have built an array with the current field contents, we then add the new value to the end of the array. (With another Redim, of course.)
Finally, we use NotesDocument.ReplaceItemValue to rewrite the whole field with the updated contents. This method will set the datatype of the field correctly, based on the type of array being used.
The end of the snippet shows two Else clauses that handle the other cases: field does not exist, and field exists with wrong datatype. In both cases, the field is replaced with the single new time-date value.
Handling multi-value number fields is identical to time-date fields, except that the two variables named New* are changed to Long datatype. The field that holds the existing values (Old*List) can remain a Variant, since a Variant can hold a list of numbers retrieved from a field.
About the author: Chuck Connell is president of CHC-3 Consulting, which helps organizations with all aspects of Lotus Notes and Domino.
I have done this with a bit more efficiency. Do you remember the doc.getitemvalue method? It is a more efficient way of retrieving the array than using a forall loop.
I have a very slight variation to this tip. I use Ubound to check for the upperbound value. Now, you only have to use Redim once. I would also likely use ReplaceItemValue instead of the abbreviated syntax.
newDate = Now() ' may be any Variant of type Date/Time If Isdate(doc.Multi(0)) Then ' Multi contains a date value already u% = Ubound(doc.Multi) Redim A(u% + 1) As Variant ' copy values to dynamic array For i% = 0 To u% A(i%) = doc.Multi(i%) Next A(u% + 1) = newDate ' append new value doc.Multi = A ' set value of item to new array Else ' Multi is empty (string) doc.Multi = newDate End If
You can replace the following code:
i = 0 Forall s In OldTimeList Redim Preserve NewTimeList(i) NewTimeList(i) = s i = i+1 End Forall 'Add new value to end of array. Redim Preserve NewTimeList(i) NewTimeList (i) = NewTime
With this code:
NewTimeList = Arrayappend(OldTimeList , NewTime )
Unless I'm mistaken, I believe Chuck forgot to set the value of "newtime" before adding it to the array. As a result, this will probably fail.
Do you have comments on this tip? Let us know.
Related information from SearchDomino.com:
- Expert Advice: Using a multi-value field in DECS
- Looking for a value in a multi-valued text field
- LotusScript Learning Guide
- FAQ: LotusScript
Please let others know how useful this tip is via the rating scale below. Do you have a useful Lotus Notes, Domino, Workplace or WebSphere tip or code snippet to share? Submit it to our tip contest and you could win a prize.