=====================================================================
Nested Functions
=====================================================================
PRODUCT: R:BASE VERSION: 4.5
=====================================================================
AREA: FUNCTIONS CATALOG: GENERAL INFORMATION
=====================================================================
New to 4.5 is nested TEXT functions. Previously, non-TEXT functions
could be nested to any depth but if any part of the function included
a TEXT datatype value, you could not do any nesting. Using the nested
TEXT function capability of 4.5 groups of commands can be replaced by
a single command.
Use nested TEXT functions to customize the display of menu text.
For example,
CHOOSE vchoice FROM #VALUES FOR +
( RJS(CTXT(empid),6) & emplname ) FROM employee
The employee id value, empid, must be converted to text via the CTXT
function. But prior to 4.5, it could not also be justified for display
purposes. The employee id then needs to be parsed out of the menu
choice. The leading spaces are not desired in the result and can , in
4.5, be removed at the same time as the employee id value is
extracted. For example,
SET VAR vempid = (LJS(SGET(.vchoice,6,1),6))
Or convert the employee id value to INTEGER with one command,
SET VAR vempid_int = (INT(SGET(.vchoice,6,1)))
There is often a need to split a column into two or more parts based
on a space or other delimiter. Prior to 4.5 this required writing a
DECLARE CURSOR program. For each row you would find the space with
one command, then use additional SET VAR commands to parse the full
name value into its pieces, then get the next row and do it all over
again. With 4.5, this can be done in a single UPDATE command. Here's
the command that splits a full_name column into first_name and
last_name.
UPDATE test SET first_name = +
(IFEQ( (SLOC(full_name,' ')), 0, ' ', +
( SGET(full_name, (LMAX(SLOC(full_name,' '), 1) - 1), 1) ) )), +
last_name = ( SGET(full_name,20, (SLOC(full_name,' ') + 1) ) )
The command includes some additional expressions to account for the
situation where there is only one name. In that case the SLOC doesn't
find a blank and returns a 0. Since the first_name portion is found by
subtracting 1 from the location of the blank, if there is only one
name, the expression is illegal and cannot be evaluated. The command
errors out if we don't include the additional expressions.
Here's a breakdown of how the command works:
UPDATE test SET
Identifies the table name to be updated. Following the keyword SET is
the list of columns and expressions to be updated.
first_name = (IFEQ( (SLOC(full_name,' ')), 0, ' ', ))
The SLOC function finds the location of the first blank in the
full_name column. The IFEQ function tests the value returned by SLOC.
If it's a 0 (i.e. a single word name), then a space is returned to the
first_name column, if not, the first name is extracted from the full
name.
= ( SGET(full_name, ( - 1) , 1 ) )
The SGET function extracts a specified number of characters from a
string. Here we are computing the number of characters to retrieve,
, based on the result of the SLOC function. We subtract 1
because we don't want the trailing space. The final 1 tells the SGET
to get the characters starting at position 1 in the full_name column.
= (LMAX(SLOC(full_name,' '), 1)
The LMAX function is used to make sure the SGET has a valid number of
characters to retrieve. The SGET needs a number >= 0 for its second
and thrid arguments. Even though the SGET function is not being
executed when there is only a single word name, R:BASE needs to be
able to parse all parts of the IFEQ function (the SGET is argument 4)
and see valid expressions. If there is only one name, the SLOC returns
a 0. Subtracting one from zero means the second argument in the SGET
is negative and the SGET can't evaluate, the expression is invalid.
The LMAX function returns to the SGET the number representing the
location of the first blank or a one. This makes sure that the SGET
will never have a negative agrument for the number of characters to
return.
last_name = ( SGET(full_name,20, (SLOC(full_name,' ') + 1) ) )
The expression for last_name uses the SGET to return 20 characters
starting at the position of the blank plus one. The SLOC function
finds the position of the first blank.