LOCATE, LOCATE() |
|
|
The LOCATE statement searches a dynamic array for a given field, value or subvalue. The LOCATE() function provides similar capabilities and is particularly suited to use in dictionary I-type items.
Format
This statement has three different syntaxes / semantics for compatibility with other systems.
Default style LOCATE string IN dyn.array<field {,value {, subvalue}}> {BY order} {SETTING var} {THEN statement(s)} {ELSE statement(s)}
UniVerse style (enabled by use of $MODE UV.LOCATE) LOCATE string IN dyn.array{<field {,value }>} {, start} {BY order} SETTING var {THEN statement(s)} {ELSE statement(s)}
Pick style LOCATE(string, dyn.array{, field {, value {, start }}}; var {; order}) {THEN statement(s)} {ELSE statement(s)}
Function style (returns position as function value) LOCATE(string, dyn.array, field {,value {, subvalue }} {; order})
where
At least one of the THEN and ELSE clauses must be present.
The LOCATE statement searches for fields, values or subvalues within a dynamic array. The semantics of this operation depend on the style selected as described below.
Default Style
The default style of LOCATE is as found in products such as Prime Information, PI/open and with certain mode settings in UniVerse and Unidata.
If only field is specified, LOCATE searches for a field that matches string. If field and value are specified but subvalue is omitted, LOCATE searches for a value within the specified field that matches string. If field, value and subvalue are specified, LOCATE searches for a subvalue within the specified field and value that matches string.
Searching commences at the starting position defined in the IN clause. If a match is found, var is set to its field, value or subvalue position as appropriate to the level of the search. If no match is found, var is set to the position at which a new item should be inserted. For an unordered LOCATE this will be such that it would be appended.
Note that the syntax actually reads incorrectly. A LOCATE statement such as LOCATE DT IN DATES<1> SETTING POS THEN ... is not searching in DATES<1> at all. It is searching starting at DATES<1>.
UniVerse Style
Pick and Reality systems and the UniVerse database running in Ideal, Pick, Reality or IN2 flavour uses the IN clause to identify the item to be searched, not the starting position. The starting position is assumed to be the first item in the data but may specified explicitly in the command by including the start item.
This format of LOCATE can be selected by including a line $MODE UV.LOCATE in the program on a line preceding the LOCATE statement.
Pick Style
The original Pick database used a very different syntax which can be used in QM without any special mode settings. Note that despite the presence of brackets, this is a statement and should not be confused with the LOCATE() function described below.
In all three styles, the THEN clause is executed if the string is found in dyn.array. The ELSE clause is found if the string is not found.
In QMBasic, unlike other multivalue environments, the SETTING clause is optional. If omitted, the THEN or ELSE clause is executed as described above but no positional information is returned.
Note that this syntax, as found in Information style multivalue products, is actually illogical. The IN clause does not specify the data within which to search. Instead it specifies the start position for the search. The alternative syntax enabled by the UV.LOCATE compiler mode and described below is more logical. This syntax is found in Pick, Reality and some flavours of UniVerse.
The optional BY clause allows selection of an ordering rule specified as a series of case insensitive letters. These are:
Left aligned ordering is faster than right aligned and should be used for textual data. Right aligned ordering is useful for numeric data such as internal format dates where the left aligned ordering would lead to sequencing problems (for example, 17 May 1995 is day 9999, 18 May 1995 is day 10000. Use of a left aligned ordering would place these dates out of calendar order).
The LOCATE() function works like the Information style described above but returns the position at which the item was found as its result value, zero if it was not found. Although the order argument can be used to specify the expected ordering and has the impact described above for numeric data, this function does not provide a way to identify where an item should be inserted if it is not found. The LOCATE() function is particularly suited to use in dictionary I-type items.
The result of a LOCATE statement or LOCATE() function with a specific ordering when applied to a dynamic array which does not conform to that ordering is undefined and likely to lead to misbehaviour of the program at run time.
Examples
Default style: LOCATE PART.NO IN PARTS<1> BY "AL" SETTING I ELSE INS PART.NO BEFORE PARTS<I> END
This program fragment locates PART.NO in a sorted list PARTS and, if it is not already present, inserts it.
UniVerse style: LOCATE PART.NO IN PARTS BY "AL" SETTING I ELSE INS PART.NO BEFORE PARTS<I> END
This is the same as the first example but reworked to use UniVerse style.
Function style: I = LOCATE(PART.NO, PARTS, 1; "AL")
This statement performs the same search as the previous example but can only be used to find the position of an existing item, not to determine where a new item should be inserted to maintain the correct sort order.
See also: DEL, DELETE(), EXTRACT(), FIND, FINDSTR, INS, INSERT(), LISTINDEX(), REPLACE() |