A list is a string of one or more entries, where each entry is separated from the next by means of a delimiter (<GOLD> semicolon). Once a list of entries has been built it is then possible to reference individual entries by supplying an index number or a name. In other languages this construct is known as an ARRAY.
A list comes in two forms: INDEXED or ASSOCIATIVE.
An INDEXED list contains entries such as "Apple;Banana;Carrot". Entries in an INDEXED list can be referenced by using their index (sequence) number within the list. In the above example "Apple" = 1, "Banana" = 2 and "Carrot" = 3.
An ASSOCIATIVE list contains entries such as "A=Apple;B=Banana;C=Carrot". Entries in an ASSOCIATIVE list can be referenced by using the 'name' part of each 'name=value' pair. This is also known as a valrep (value/representation) list and is used in such widgets as dropdown lists and radio groups. The 'value' part is what is used internally, and the 'representation' part is how that value is represented to the user.
A list can be a field name or a variable name, or $valrep(field)
in order to manipulate the properties of a widget.
$valrep(field) = "string" ; operates on all occurrences within current form $fieldvalrep(field) = "string" ; operates on current occurrence only
A list can be created with a simple assignment statement, as in:
$$list = "A=Apple;B=Banana;C=Carrot"
The contents may be defined on the message file, as in:
$$list = $text(v_star_signs)
A list can be emptied by assigning an empty string, as in:
$$list = ""
Any list can be treated as either an indexed list or an associative list. Consider this list:
"A=Monday;B=Tuesday;C=Wednesday;D=Thursday;E=Friday;F=Saturday;G=Sunday"
It can be treated as an associative list by retrieving the representation whose value is "B".
It can be treated as an indexed list by retrieving the entire 2nd item ("B=Tuesday").
Consider this list:
"Monday;Tuesday;Wednesday;Thursday;Friday;Saturday;Sunday"
It can be treated as an indexed list by retrieving the 2nd item ("Tuesday").
It can be treated as an associative list by retrieving the representation whose value is "Tuesday". As there is no equals sign in this ValRep, the representation is the same as the value.
Within as associative list item, if an equal sign is preceded by a percent sign (%), it is not recognised as a ValRep separator. This allows you to use the equal sign in the value or representation of a list item, as in: "1=A%=B;2=A%=C"
.
putitem list, N, source
N must be an integer greater than zero, with '-1' used to signify 'append'. If the number supplied is currently greater than the number of items in the list, empty items will be created until the Nth item is reached.
putitem $$list, -1, "Monday" - appends putitem $$list, -1, "Tuesday" - appends putitem $$list, -1, "Thursday" - appends putitem $$list, 3, "Wednesday" - replaces item 3
If List contains an associative list, the entire ValRep of the associative item is replaced by Source.
putitem/id{/case} list, index{, source}
putitem/id $$list, "A", "Apple" - appends putitem/id $$list, "B", "Banana" - appends putitem/id $$list, "C", "Camel" - appends putitem/id $$list, "C", "Carrot" - replaces item whose id = 'C'
By default the matching of Index with item values is not case-sensitive. If multiple entries exist, then the first one found in the list is deleted. If a specific match is required the /case
switch must be used.
putlistitems $$list, field
(occurrence 1) day.calendar = "Monday" (occurrence 2) day.calendar = "Tuesday" (occurrence 3) day.calendar = "Wednesday" setocc "calendar",1 putlistitems $$list, day.calendar ; $$list = "Monday;Tuesday;Wednesday"
putlistitems/id {/field} {/component} {/global} $$list
one.entity = "ONE" $one$ = "$ONE$" $$one = "$$ONE" $two$ = "$TWO$" $$three = "$$THREE" $$list = "one;$two$;$$three" putlistitems/id/field $$list ; "one=ONE;$two$=$TWO$;$$three="$$THREE" putlistitems/id/component $$list ; "one=$ONE$;$two$=$TWO$;$$three="$$THREE" putlistitems/id/global $$list ; "one=$$ONE;$two$=$TWO$;$$three="$$THREE"
If the Value part of a list item does not contain a dollar sign ($), the source is assumed to be a field unless one of the source switches /component
or /global
is present.
If the list is indexed it is converted to associative by adding in values from the current occurrence.
Note: /component
is a synonym for /local
, but it refers to the component variables, not local variables.
(a) putlistitems/id $$list, {SourceValue}, SourceRepresentation
(occurrence 1) num.calendar = "d1", day.calendar = "Monday" (occurrence 2) num.calendar = "d2", day.calendar = "Tuesday" (occurrence 3) num.calendar = "d3", day.calendar = "Wednesday" setocc "calendar",1 putlistitems/id $$list, num.calendar, day.calendar ; $$list= "d1=Monday;d2=Tuesday;d3=Wednesday"
Note: Both SourceValue
and SourceRepresentation
are optional (but at least one must be specified), allowing either one or two fields to be copied.
(b) putlistitems/occ{/modonly} $$list, "entity"
This will result is a list of all field names and their associated values from the current occurrence of "entity". If the /modonly
switch is used only the value from those fields where $fieldmod = 1
are inserted. Field ids which are unmodified are removed from the list.
You can use putlistitems/occ
and getlistitems/occ
to copy field values from one occurrence to another, or from one entity to another.
(c) putlistitems/id $$list
This will convert an indexed list of field names into an associative list of fieldnames and values, using the current occurrence as its source. If this is preceded by $keyfields('entity',1)
this will effectively construct a list containing the primary key of the current occurrence.
For example, and entity called PERSON has a primary key called PERSON_ID. At run time the current occurrence of PERSON has a primary key value of 'AJM'. This information can be inserted into a list with the following commands:
$$pkey = $keyfields(PERSON, 1) ; $$pkey contains 'person_id' putlistitems/id $$pkey ; $$pkey contains 'person_id=AJM'
This procedure works even if the primary key is made up of more than one field.
getitem target, list, N
N must be an integer greater than zero, with '-1' used to signify the last entry. If the number supplied is currently greater than the number of items in the list nothing can be copied.
$$list = "Apple;Banana;Carrot" getitem $1, $$list, 2 ; $1 = "Banana" getitem $1, $$list, -1 ; $1 = "Carrot"
getitem/id{/case} target, list, index
$$list = "A=Apple;B=Banana;C=Carrot" getitem/id $1, $$list, "B" ; $1 = "Banana" getitem/id $1, $$list, "C" ; $1 = "Carrot"
By default the matching of Index with item values is not case-sensitive. If multiple entries exist, then the first one found in the list is retrieved. If a specific match is required the /case switch must be used.
getitem target, list, N $$list = "A=Apple;B=Banana;C=Carrot" getitem $1, $$list, 2 ; $1 = "B=Banana"
getlistitems $$list, field
$$list = "Monday;Tuesday;Wednesday" setocc "calendar",1 getlistitems $$list, day.calendar (occurrence 1) day.calendar = "Monday" (occurrence 2) day.calendar = "Tuesday" (occurrence 3) day.calendar = "Wednesday"
getlistitems/id {/field} {/component} {/global} $$list
$$list = "one=ONE;$two$=$TWO$;$$three=$$THREE" getlistitems/id/field $$list ; one.entity = ONE ; $two$ = $TWO$ ; $$three = $$THREE getlistitems/id/component $$list ; $one$ = ONE ; $two$ = $TWO$ ; $$three = $$THREE getlistitems/id/global $$list ; $$one = ONE ; $two$ = $TWO$ ; $$three = $$THREE
If the Value part of a list item does not contain a dollar sign ($), the target is assumed to be a field unless one of the target switches /component
or /global
is present.
Note: /component
is a synonym for /local
, but it refers to the component variables, not local variables.
(a) getlistitems/id $$list, {TargetValue}, TargetRepresentation
$$list = "d1=Monday;d2=Tuesday;d3=Wednesday" setocc "calendar",1 getlistitems/id $$list, num.calendar, day.calendar (occurrence 1) num = "d1", day = "Monday" (occurrence 1) num = "d2", day = "Tuesday" (occurrence 3) num = "d3", day = "Wednesday"
Note: Both TargetValue
and TargetRepresentation
are optional (but at least one must be specified), allowing either one or two fields to be populated.
(b) getlistitems/occ $$list, "entity"
This fills in all specified fields in the current occurrence. You can use putlistitems/occ
and getlistitems/occ
to copy field values from one occurrence to another, or from one entity to another.
(c) getlistitems/occ/init $$list, "entity"
This does not set field or occurrence modification switches.
delitem list, N
N must be an integer greater than zero, with '-1' used to signify the last entry. If the number supplied is currently greater than the number of items in the list nothing can be deleted.
$$list = "Apple;Banana;Carrot" delitem $$list, 1 ; $$list = "Banana;Carrot" delitem $$list, -1 ; $$list = "Banana"
delitem/id{/case} list, index
$$list = "A=Apple;B=Banana;C=Carrot" delitem/id $$list, "A" ; $$list = "B=Banana;C=Carrot" delitem/id $$list, "C" ; $$list = "B=Banana"
By default the matching of Index with item values is not case-sensitive. If multiple entries exist, then the first one found in the list is deleted. If a specific match is required the /case
switch must be used.
delitem list, N $$list = "A=Apple;B=Banana;C=Carrot" delitem $$list,2 ; deletes "B=Banana"
sort/list field {,"D(escending) U(nique)"}
If the 'Unique' option is specified then duplicate entries will be removed.
$$list = "Mon;Tue;Wed;Thu;Fri" sort/list $$list $$list = "Fri;Mon;Thu;Tue;Wed" $$list = "Mon;Tue;Wed;Thu;Fri" sort/list $$list,(d) $$list = "Wed;Tue;Thu;Mon;Fri"
sort/list field {,"D(escending) U(nique)"}
If the list is associative items are sorted by the Representation (after the '='), not the Value (before the '=').
$$list = "1=Mon;2=Tue;3=Wed;4=Thu;5=Fri" sort/list $$list $$list = "5=Fri;1=Mon;4=Thu;2=Tue;3=Wed" $$list = "1=Mon;2=Tue;3=Wed;4=Thu;5=Fri" sort/list $$list,(d) $$list = "3=Wed;2=Tue;4=Thu;1=Mon;5=Fri"
There may be an occasion when you are traversing the contents of an associative list and you do not know the current item's ID, therefore you cannot use getitem/id
. In this situation the ID and VALUE portions of a list item can be extracted individually by using the functions IDPART and VALUEPART as follows:
$$list = "B=Tuesday" $1 = idpart($$list) ; $1 now contains "B" $2 = valuepart($$list) ; $2 now contains "Tuesday"
item(id, associative_list)
This is a quick way to return the value that belongs to a given id from an associative list. This function acts in the same way as the getitem/id statement, but may also be used as part of an expression.
The following example shows how to find and directly pass an associative list item to an operation:
if (item("MEDIUM", myList) = "Book" ) call selectBook(item("ISBN_NR", myList) ) endif
NOTE: If the item contains leading numeric characters then you should convert the expression into a string when using it as a parameter otherwise only the leading digits will be extracted. For example: "%%ITEM(id, list)%%%"
It is possible to construct a list that contains other lists. For example, you can construct a list containing all the values from an occurrence with the following command:
putlistitems/occ $$list1, "entity"
$$list1 will now contain "field1=value1;field2=value2;...;fieldn=valuen"
.
But supposing you wanted a list which contained the data from more than one occurrence. How could this be done? Consider the following command:
putitem/id $$list2, "occ/%%$curocc", $$list1
$$list2 will now contain "occ/1=field1=value1!;field2=value2!;...!;fieldn=valuen"
If you put this command into a loop you could construct a list containing the data from all available occurrences. You could use code similar to the following:
setocc "entity",1 ; start at first occurrence repeat putlistitems/occ $$list1,"entity" ; put occurrence data into $$list1 putitem/id $$list2, "occ/%%$curocc", $$list1 ; insert into $$list2 with a unique id setocc "entity",$curocc(entity)+1 ; look for next occurrence until ($status < 1) ; until no more occurrences
Uniface accomplishes this task of embedding one list inside another by inserting a '!' character in front of each existing delimiter inside the list which is being embedded. This process of adding a '!' character to the delimiter will continue even if the list being embedded already contains an embedded list. Thus it is possible to construct a list which contains any number of lists within lists, and you will see several '!' characters in front of each <GOLD>semi-colon delimiter.
Note that in order to access the contents of an embedded list you must reverse the process, i.e. extract the contents of an embedded list into a non-embedded list until all the '!' characters have been stripped from the delimiters. This is where the VALUEPART command comes in handy.
getitem $$list3, $$list2, 1 ; extract the first 'occ/n=list' pair $$list4 = valuepart($$list3) ; extract 'list' into $$list4
At the end of these commands $$list4 will contain the data for a single occurrence which can then be put back by using getlistitems/occ
.
To transfer all data into occurrences in the current form you could use code similar to the following:
while ($$list2 != "") ; while $$list2 is not empty getitem $$list3, $$list2, 1 ; extract the first 'occ=list' pair into $$list3 delitem $$list2,1 ; delete this pair $$list4 = valuepart($$list3) ; extract 'list' into $$list4 creocc "entity",-1 ; create empty occurrence getlistitems/occ $$list4,"entity" ; fill occurrence with data endwhile
Tony Marston
24th October 2002
mailto:tony@tonymarston.net
mailto:TonyMarston@hotmail.com
http://www.tonymarston.net
3rd Nov 2002 | Added section 2.8 ITEM (my thanks to Ulrich?Merkel for pointing this function out to me). |