LOCATE data IN dynarray[<f[,v[,s]]>] [,start] [BY format] SETTING variable [THEN statements] [ELSE statements] LOCATE(data,dynarray[,f[,v];variable[;format]) [THEN statements] [ELSE statements]
|data||The element value to search for in dynarray. This value must be the complete value of the element. An expression that evaluates to a string or a numeric value. Values are case-sensitive.|
|IN dynarray||A valid dynamic array.|
|f||Optional — An integer that denotes the Field level of the dynamic array to search for the element data. Fields are counted from 1. The surrounding angle brackets are required.|
|v||Optional — An integer that denotes the Value level of the dynamic array to search for the element data. Values are counted from 1.|
|s||Optional — Supported by Some Emulations Only — An integer that denotes the Subvalue level of the dynamic array to search for the element data. Subvalues are counted from 1.|
|start||Optional — An integer specifying the starting location to begin searching the level specified in f, v, and s. This argument is not supported by all emulations.|
|BY format||Optional — specifies the collation sequence. Specify format as a quoted string with one of the following values: “AL” (ascending, left justified); “AR” (ascending, right justified); “DL” (descending, left justified); “DR” (descending, right justified).|
|SETTING variable||A local variable that LOCATE sets to an integer specifying either where data is located or where data can be added.|
The LOCATE statement is used to search for an element value in a dynamic array and return the search results by setting variable. Caché MVBasic supports both syntactical forms, as shown above.
In Caché MVBasic you can set the f, v variables to integers to specify which data item(s) of the dynamic array to search. If you search with just the dynarray array name, you are searching for an Field within the dynamic array. If you search with dynarray<f> then you are searching within Field f of dynarray for a Value. If you search with dynarray<f,v> you are searching for a Subvalue within the Value dynarray<f,v>. For example, setting f=2 searches the second dynamic array field for the data value. Caché MVBasic LOCATE does not support s (Subvalue level); this is only supported by the INFORMATION, PIOpen, and UniData emulations, which use a different search logic, as described below.
The data value must be an exact match with the full value of an element in dynarray. It cannot be a substring of an element value. Matching is case-sensitive. If data does not match an element value, variable is set to an integer 1 larger than the current last element. This specifies how many elements were searched and where the missing value can be appended to the existing values. LOCATE behavior when dynarray is the null string ("") is described below.
The f, v, and s arguments accept a single dynamic array reference (A<i>), a single substring reference (A[s,l]), or a substring reference nested inside a dynamic array reference (A<i>[s,l]).
The optional BY clause specifies the collation (ascending or descending) and the justification (left or right) used to locate a value. Left justification is commonly used for strings, and right justification is used for numbers. Positive and negative numbers are sorted in numeric sequence, regardless of the justification. However, a mixed numeric value (for example -24degrees) sorts in string collation sequence, rather than numeric sequence.
You can optionally specify a THEN clause, an ELSE clause, or both a THEN and an ELSE clause. If data is located in dynarray, the THEN clause is executed. If data is not located in dynarray, the ELSE clause is executed. The statements argument can be the NULL keyword, a single statement, or a block of statements terminated by the END keyword. A block of statements has specific line break requirements: each statement must be on its own line and cannot follow a THEN, ELSE, or END keyword on that line.
Null Value Arguments
LOCATE behavior when data and/or dynarray has an empty string value is as follows:
data="", dynarray=value: Sets variable to an integer 1 larger than the last element of dynarray. The ELSE clause is taken. If start is specified with a value greater than 1, variable=start.
data=value, dynarray="": Sets variable=1. The ELSE clause is taken. This is because searching for a nonempty string treats an empty dynamic array component as containing zero subcomponents, so zero components are searched and the LOCATE stops before searching the subcomponent at position 1. If start=0 or start=1, variable=1; if start is greater than 1, variable=start.
data="", dynarray="": Sets variable=1. The THEN clause is taken. This is because searching for the empty string in the subcomponent contained in an empty component of a dynamic array considers that component as containing one empty subcomponent at position 1 which matches the searched-for empty string. If start is specified with a value other than 1, the ELSE clause is taken. If start=0 or start=1, variable=1; if start is greater than 1, variable=start.
LOCATE and FIND
The LOCATE statement and the FIND statement both search for an exact element value in a dynamic array and return its location. Both support optional syntax THEN for successful search and ELSE for unsuccessful search. They differ in the following ways:
FIND is used to search an entire dynamic array; there is no way to limit its scope to a portion of the dynamic array. LOCATE can use the f, v, and s variables to limit the scope of the search.
When a search is successful, FIND returns an absolute location within the dynamic array; LOCATE returns a count relative to the specified starting location.
When a search is unsuccessful, FIND provides no location information; LOCATE provides information on where the missing value could be appended to the existing values.
To locate an element in a dynamic array by a substring value, use the FINDSTR statement. To return the value of an element by specifying its dynamic array location, use the EXTRACT function.
In INFORMATION, PIOpen, UDPICK, and UniData, f, v, and s arguments mean to search at that level, rather than to search within that level. The f, v, and s argument values are start positions, rather than array subscripts. The search begins at the lowest level specified and only that level is searched. For this reason, these emulations require the f argument, and only these emulations support the s argument. $OPTIONS INFO.LOCATE supports this emulation feature. If dynarray is the null string (""), the SETTING variable is the integer value of the lowest specified level (f, v, or s). These emulations do not support the start argument.
In UniData, if f is less than or equal to 0, it is treated as 1. If v, or s (or both) are less than or equal to 0, they are ignored. If data="" and dynarray="" the THEN clause is always taken, regardless of the value of start.
The following example uses the LOCATE statement to find the second value from the first field of a dynamic array:
cities="New York":@VM:"London":@VM: "Chicago":@VM:"Boston":@VM:"Los Angeles" LOCATE "London" IN cities<1> SETTING a THEN PRINT "found",a ! returns "found 2" found in field 1 at position 2 ELSE PRINT "not found",a LOCATE "London" IN cities<2> SETTING a THEN PRINT "found",a ELSE PRINT "not found",a ! returns "not found 1", append to field 2 at level 1 LOCATE "London" IN cities<1,3> SETTING a THEN PRINT "found",a; ELSE PRINT "not found",a ! returns 2 not found, append to field 2 at level 2
The following example uses the second syntactical form of LOCATE. It is otherwise identical to the previous example:
cities="New York":@VM:"London":@VM: "Chicago":@VM:"Boston":@VM:"Los Angeles" LOCATE("London",cities<1>;a) THEN PRINT "found",a ! returns "found 2" found in field 1 at position 2 ELSE PRINT "not found",a LOCATE("London",cities<2>;a) THEN PRINT "found",a ELSE PRINT "not found",a ! returns "not found 1", append to field 2 at position 1 LOCATE("London",cities<1,3>;a) THEN PRINT "found",a; ELSE PRINT "not found",a ! returns 2 not found, append to field 2 at level 2