===================================================================== 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.