LOCATE, LOCATE()

Top  Previous  Next

 

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

 

stringevaluates to the item to be located.

 

dyn.arrayis the dynamic array in which searching is to occur.

 

fieldis the field at which searching is to commence.

 

valueis the value at which searching is to commence. If omitted or zero, searching occurs at the field level.

 

subvalueis the subvalue at which searching is to commence. If omitted or zero, searching occurs at the value level.

 

orderevaluates to the ordering string as described below. If omitted, no ordering is assumed.

 

varis the variable to receive the position value.

 

statement(s)are statements to be executed depending on the outcome of the LOCATE action.

 

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. The order must evaluate to a two character string, which is

 

ALAscending, left justified. Items are considered to be sequenced in ascending collating sequence order.

 

ARAscending, right justified. Items are considered to be sequenced in ascending collating sequence order. Where the item being examined is not of the same length as the string being located, the shorter of the two is right aligned within the length of the longer prior to comparison. Integer numeric data that can be represented as a 64 bit value is treated as a special case and is sorted into correct numeric sequence. In the Pick style syntax, fractional values are also allowed in numeric sorting.

 

DLDescending, left justified. Similar to AL except that the list is held in descending collating sequence.

 

DRDescending, right justified. Similar to AR except that the list is held in descending collating sequence.

 

The ordering string must be in upper case. 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.

 

Use of the $NOCASE.STRINGS compiler directive makes the comparison case insensitive. When used with a BY clause, the sorting is effectively as though both string and dyn.array are in uppercase.

 

 

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 stye:

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()