Typically free format code does not require a graphic illustrating the nesting levels since it can be written in an indented manner. However, Example 5.3b, below, illustrates this indented nesting graphic for free format RPG.
Example 5.3: Graphic illustration of RPG nesting in free format.
....._+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ /FREE-FORM IF %Status = 0; | DOW %eof(CUSTMAST) = *OFF AND Count <= 20; | | WRITE SFL001; | | IF NOT %eof(SFL001); | | | Eval Count += 1; | | | READ CUSTMAST; | | ENDIF; | ENDDO; ENDIF; /END-FREE
The ACQ operation is used to grab or capture the program device (workstation/display station) specified in factor 1.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
workstn device ID | ACQ(E) | workstn file name | [error] |
See also REL
Factor 1 must contain a constant or a field that contains the name of the program device (workstation/ display station) that is acquired by the program. Factor 2 must contain the name of the workstation file that is used to acquire the program device. When resulting indicator 2 is set on by the ACQ operation, one of the following conditions exists:
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | N/A | |
73 – 74 | 2 | [error] | An error occurred during the operation. |
75 – 76 | 3 | N/A |
The device has already been acquired by another application (a user may have "signed on" to the system using that device).
The device file specified in factor 2 already acquired the device.
The device specified in factor 1 does not exist.
Once a device has been acquired, the program may read from the device or write to the device. To identify which device a program accesses, move the name of the device into the field specified for the program device ID. This field is specified on the DEVID keyword of the file specification. The maximum number of program devices a program can acquire is equal to the number of program devices specified for the MAXDEV keyword of the file specification.
In Example 5.4, line 10 contains the file specification for the workstation display file GLENTRY (G/L Entry). The MAXDEV keyword is used to indicate the maximum number of devices that may be acquired by the program for the GLENTRY workstation display file.
Example 5.4: Acquiring a workstation device.
.....FFileName++IFEASFRlen+LKeylnKFDevice+.Functions++++++++++++++++++++++++++++ 0010 FGLENTRY CF E WORKSTN MaxDev(*FILE) DEVID(wsid) .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0030 C 'DSP01' ACQ(E) GLENTRY 0040 C If %ERROR 0050 C EXSR *PSSR 0060 C ENDIF 0070 C MOVEL 'DSP01' WSID 0080 C EXFMT PROMPT
In Example 5.4 , the file's description is used to set the number of devices. This value may be overridden to a different number outside of the program through a system function.
Line 10 also contains the DEVID keyword. This keyword is used to identify which device the program reads on the next I/O operation.
Line 30 uses the constant 'DSP01' as the name of the device that is acquired by the program. GLENTRY is the workstation file that acquires DSP01.
Line 70 moves the constant 'DSP01' into the field WSID to force the EXFMT (write/read format) operation on line 80 to write to and then read from the DSP01 device.
Note | Line 80 uses a record format name 'prompt' in place of the workstation file name. |
The ADD operation is used to produce the sum of two numeric values. Add works with packed, signed, binary, or integer numeric data types. For DATE, TIME, and TIMESTAMP values, the ADDDUR operation must be used.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
[numeric value 1] | ADD(H) | numeric value 2 | sum | [+] | [-] | [0 or b] |
See also EVAL, EVALR, SUB, MULT, DIV, SQRT, ADDDUR, and SUBDUR
If factor 1 is specified, factor 1 and factor 2 are added to produce a sum that is returned to the result field. If factor 1 is omitted, factor 2 and the result field are added and the sum is placed into the result field. The H operation extender can be specified to cause the result to be half-adusted (rounded up).
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | [ + ] | The result field is greater than zero. |
73 – 74 | 2 | [ - ] | The result field is less than zero. |
75 – 76 | 3 | [ 0 ] | The result field is equal to zero. |
If you wrote the code shown in Example 5.5 in traditional mathematical expressions, it would appear as follows:
A + B = C C + 1 = C
Example 5.5: Adding variables and constants.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C A ADD B C 0020 C ADD 1 C 545658
In this example, fields A and B are added, and the result is placed into field C. Then field C is incremented by 1. If C is greater than 0, resulting indicator 1 is set on. If C is less than 0, resulting indicator 2 is set on. If C is equal to 0, resulting indicator 3 is set on.
The ADDDUR operation adds the duration specified in factor 2 to the date, time, or timestamp variable specified in factor 1. The new value is returned in the result field. The value specified in factor 1 is referred to as the base date or base time. If factor 1 is not specified, the duration is added to the variable specified in the result field.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
[date value] | ADDDUR(E) | duration : dur code | resulting date | [error] |
See also SUBDUR, EXTRCT, and TEST.
Factor 1 is optional and can contain a date, time, or timestamp value. If factor 1 is not specified, the date, time, or timestamp value specified in the result field is used.
Extender | Description |
---|---|
E | ERROR - Causes the %ERROR and %STATUS built-in functions to be set if an error occurs during the operation. |
Factor 2 is required and must contain a variable or literal that represents a duration that is added to the value. Because factor 2 can be a positive or negative value, ADDDUR can be used to add or subtract a duration. The duration must be identified with a valid duration code (i.e., *YEARS, *MONTHS, *DAYS, *HOURS, *MINUTES, *SECONDS, *MSECONDS). See Table 5.6 for a description of these duration codes.
If the result field contains an array name (e.g., an array of dates), the duration is added to each element in the array. Example 5.6 illustrates the use of the ADDDUR operation code to add 30 days to the field named DUEDATE. In Example 5.6, the field DUEDATE is of type DATE. It is initialized to the 17th of February, 1996. After the ADDDUR operation on line 4 is performed, the DUEDATE variable is set to the 19th of March, 1996.
Example 5.6: Using ADDDUR to add 30 days to a date variable.
.....DName+++++++++++EUDS.......Length+TDc.Functions++++++++++++++++++++++++++++ 0001 D DueDate S D INZ (D'1996-02-17') 0002 .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0003 * Add 30 days to the due date 0004 C AddDur 30:*Days DueDate
The ALLOC operation is used to dynamically allocate storage (memory) at runtime. The number of bytes and a pointer variable to which the memory location is returned are passed to the ALLOC operation.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
ALLOC (E) | Length in bytes | Pointer variable | [error] |
See also REALLOC and DEALLOC.
Factor 1 is required and must contain a numeric field or literal value. Factor 1 indicates the number of bytes of memory to allocate. The number of bytes that can be allocated must be greater than 0 and less than 16 megabytes (16,776,704). If the number of bytes is outside this limit, status error code 0425 is returned to the %STATUS built-in function.
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | N/A | |
73 – 74 | 2 | [error] | An error occurred during the operation. |
75–76 | 3 | N/A |
The result field is required and must contain a field of type pointer. The address of the memory allocated is returned to this variable. There should be a variable with the BASED keyword referencing this pointer variable. The based variable can be used to access the newly allocated memory.
In Example 5.7, 500 bytes of memory are allocated on line 3. The pointer variable pSTRING is used to store the address of those 500 bytes of memory. Line 1 declares the based-on variable STRING. This variable declaration contains the BASED keyword. This indicates that the STRING variable is based on the pSTRING pointer. Note that RPG does not require pointer variables to be explicitly declared. Specifying the pointer variable in the BASED keyword causes the variable to be declared by the RPG language.
Example 5.7: Allocating 500 bytes of memory.
.....DName+++++++++++EUDS.......Length+TDc.Functions++++++++++++++++++++++++++++ 0001 D String S 500A Based(pString) .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0002 * Allocate 500 bytes of memory 0003 C ALLOC(E) 500 pString
The ANDxx operation is used in conjunction with the IFxx, DOWxx, DOUxx, and WHENxx operations. ANDxx complements these other operations in that their conditioning is extended through the use of the ANDxx.
Conditioning indicators are not allowed for this operation. Resulting indicators are not valid for this operation.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
Compare value 1 | ANDxx | compare value 2 |
See also ORxx, DOUxx, DOWxx, and IFxx
Factor 1 is required and must contain a field, literal value, array element, or figurative constant. Factor 2 is required and must contain a field, literal value, array element, or figurative constant.
Factor 1 is compared to factor 2 using the ANDxx Boolean operators EQ, GE, GT, LE, LT, and NE (see Table 5.9). Factor 1 and factor 2 must be similar data types. In other words, both must be character or numeric. Example 5.8 shows an example of using ANDLE to extend the DOWEQ operation.
Example 5.8: Using ANDLE to extend the DOWxx operation.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C *IN58 DOWEQ *OFF 0020 C C ANDLE 10 0030 C ADD 1 C 3 0 0040 C READ CUSTMAST 58 0050 C ENDDO
In Example 5.8, indicator 58 is compared to the *OFF figurative constant. If indicator 58 is off, field C is compared to the constant 10. If it is less than or equal to 10, the ANDLE extension is satisfied, and the DO WHILE loop is performed.
The BEGSR operation marks the beginning of a subroutine. Factor 1 must contain a unique name for the subroutine. That unique name is used as the target of the EXSR (perform subroutine) and CASxx (compare factor 1 and factor 2, then perform subroutine) operations. Evoking a subroutine is faster than evoking a subprocedure or subprogram. Conditioning and control level-break indicators are not valid for this operation. Resulting indicators are not valid for this operation.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
Subroutine name | BEGSR |
See also ENDSR, EXSR, CASxx, *INZSR, and *PSSR
Factor 1 is required and must contain a unique subroutine name. If factor 1 contains *PSSR, the subroutine is the program status subroutine and is called before the RPG exception/error handling routine to handle runtime exceptions. If factor 1 contains *INZR, the subroutine is the initialization subroutine and is called immediately after the RPG cycle completes the *INIT routine—before first page output (i.e., 1P output) is performed. If factor 1 contains *TERMSR, the subroutine is the termination subroutine and is automatically called when the program ends.
The control-level indicator can contain the subroutine identifying letters SR. This identifier is optional and is used only on the first and last lines of a subroutine for identification purposes.
In Example 5.9, the subroutine COUNT is called from the "main line" calculations through the use of the EXSR operation. The subroutine COUNT is delimited with the BEGSR operation on line 20 and the ENDSR (End Subroutine) operation on line 70.
Example 5.9: Performing a subroutine.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C EXSR COUNT 0020 CSR COUNT BEGSR 0030 C READ FILE 75 0040 C IF NOT %EOF 0050 C ADD 1 C 0060 C ENDIF 0070 CSR ENDCNT ENDSR
The BITOFF operation causes the bits specified by factor 2 to be set to '0' in the result field. Bits that are not referenced in factor 2 are unchanged in the result field. This operation is normally used in conjunction with the BITON (Set Bits On) operation to build character values that are less than X'40'. Resulting indicators are not valid for this operation.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
BITOFF | 'bits to set off' | char variable |
See also BITON and TESTB
Factor 2 can contain a bit pattern. The bit pattern can be a named constant or a literal value containing bit numbers, a one-position character field, or a hexadecimal literal value. If a field name or hexadecimal literal value is specified for factor 2, then the bits that are on in factor 2 are set on in the result field. For fields and hexadecimal literal values, bits that are off in factor 2 are not changed in the result field. The result field must contain a one-position character field or array element. For more information on bit patterns, see the subheading TESTB (Test Bit Pattern).
In Example 5.10, bit 1 in the first 35 elements of the array NAME is set off. If the array NAME contains some text, this routine would convert that text to lowercase.
Example 5.10: Converting the contents of an array to lowercase letters.
.....DName+++++++++++EUDS.......Length+TDc.Functions++++++++++++++++++++++++++++ 0010 D NAME S 1 DIM( 35) .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0020 C DO 35 X 0030 C BITOFF '1' NAME(X) 0040 C ENDDO
The BITON operation causes the bits indicated in factor 2 to be set to '1' in the result field. Bits that are not referenced in factor 2 are unchanged in the result field.
This operation is normally used in conjunction with the BITOFF (Set Bits Off) operation to build character values that are less than X'40'. While it also can be used to convert lowercase letters to uppercase, the XLATE operation provides a more portable method of conversion. Resulting indicators are not valid for this operation.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
BITON | 'bits to set on' | char variable |
See also %BITAND, %BITOR, %BITXOR, %BITNOT, BITOFF and TESTB
Factor 2 can contain a bit pattern. The bit pattern can be a named constant or a literal value containing bit numbers, a one-position character field, or a hexadecimal literal value. If a field name or hexadecimal literal value is specified for factor 2, then the bits that are on in factor 2 are set on in the result field. For fields and hexadecimal literal values, bits that are off in factor 2 are not changed in the result field.
The result field must contain a one-position character field or array element. For more information on bit patterns, see the subheading TESTB (Test Bit Pattern).
In Example 5.11, bit 1 in the first 35 elements of the array ITEM is set on. If the array ITEM contains some text, this routine converts that text to uppercase.
Example 5.11: Converting the contents of an array to uppercase letters.
.....DName+++++++++++EUDS.......Length+TDc.Functions++++++++++++++++++++++++++++ 0010 D ITEM S 1 DIM(35) .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0020 C DO 35 X 0030 C BITON '1' ITEM(X) 0040 C ENDDO
If factor 2 contains a bit pattern literal value, it must conform to the following guidelines:
It must be left-justified in factor 2.
It must be enclosed in single quotation marks.
It must contain one or more unique numerals ranging from 0 to 7.
Bits 0, 1, 2, and 3 are the top half of the byte. Bits 4, 5, 6, and 7 are the bottom half of the byte. Bits that are not referenced in factor 2 go unchanged. The bit pattern for factor 2 is described as follows:
Bit numbers that can be set | 0123 4567 |
Value of bits that are set | 8421 8421 |
In Example 5.12, Line 10 sets off all the bits in field FLDA. Line 20 sets on all the bits in the field FLDB. Line 30 sets off bits 0, 1, 3, 4, 5, and 7 in the field ATTR. Line 40 sets on bits 2 and 6 in field ATTR. Line 50 set on bits 0, 1, 2, and 3 (the mask for X'F0'). Bits 4, 5, 6, and 7 are not changed.
Example 5.12: More examples of bit manipulation.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq * Set off all the bits in FLDA. 0010 C BITOFF '01234567' FLDA 1 * Set on all the bits in FLDB. 0020 C BITON '01234567' FLDB 1 * Change field ATTR to x'22' (two operations required). 0030 C BITOFF '013457' ATTR 1 0040 C BITON '26' ATTR 1 * Set on bits 0 to 3 in HEXVAL. 0050 C BITON X'F0' HEXVAL 1
In Example 5.12, Line 10 sets off all the bits in field FLDA. Line 20 sets on all the bits in the field FLDB. Line 30 sets off bits 0, 1, 3, 4, 5, and 7 in the field ATTR. Line 40 sets on bits 2 and 6 in field ATTR. Line 50 set on bits 0, 1, 2, and 3 (the mask for X'F0'). Bits 4, 5, 6, and 7 are not changed.
Use of the BITON and BITOFF operations has been substantially reduced since the introduction of hexadecimal literal values to the language. BITON and BITOFF traditionally have been used to create characters where the values are less than X'40' (a blank). With hexadecimal literal values, a simple MOVE or MOVEL accomplishes the same task and is much more readable.
The CABxx operation compares factor 1 to factor 2. If the relationship test is true, then a branch is performed to the label specified in the result field, and any resulting indicators are set on accordingly.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
Compare value 1 | CABxx | compare value 2 | [label] | [1>2] | [1<2] | [1=2] |
See also TAG, GOTO, ENDSR, and LEAVESR
The result field is optional and contains the label of a TAG or ENDSR statement that is the target of the branch. If the result field is omitted, at least one resulting indicator must be specified. Resulting indicators are optional unless no result field (label) is specified or when xx of the CABxx operation is blank. Under these situations, at least one resulting indicator is required.
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | [1>2] | Factor 1 is greater than factor 2. |
73 – 74 | 2 | [1<2] | Factor 1 is less than factor 2. |
75 – 76 | 3 | [1=2] | Factor 1 is equal to factor 2. |
Example 5.13 shows several examples of the use of compare and branch operations.
Example 5.13: Branching to certain labels based on the contents of various fields.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C Z-ADD 100 A 3 0 0020 C Z-ADD 200 B 3 0 0030 C A CABEQ B LAB1 0040 C A CABLT B LAB2 545658 0050 C A CAB B LAB3 545658 0060 C LAB1 TAG 0070 C LAB2 TAG 0080 C LAB3 TAG
The CALL operation temporarily interrupts the program, and then dynamically loads and runs another program.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
CALL(E) | program name | [parameter list] | [error] | [LR} |
See also CALLB, CALLP, PARM, and PLIST
Factor 2 must contain the name of the program to be run. Factor 2 can be either a quoted literal value, named constant, field, array element, data structure, or data-structure subfield name.
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | N/A | |
73 – 74 | 2 | [error] | An error occurred during the operation. |
75 – 76 | 3 | [ LR ] | The called program ended with its LR indicator set on. |
The result field is optional and may contain the name of a parameter list (PLIST) label. The parameter list is used to pass parameters between the programs. If the parameter list is omitted and parameters are required, the CALL operation may be immediately followed by the PARM operation to identify the parameters.
In Example 5.14, the program CUSTINQ is called and is passed two parameters: a customer number and some search data. The program CUSTINQ accepts parameters and those parameters are defined immediately following the CALL operation. Therefore, a parameter list (PLIST) is not needed in the result field of the CALL operation.
Example 5.14: Calling a program and passing two parameters.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C CALL 'CUSTINQ' 56 0020 C PARM SEARCH 0030 C PARM CSTNBR
In Example 5.15, the program name CUSTINQ is defined by the named constant PGMTOCALL (line 50) and is used by the CALL operation (line 60) to call the program CUSTINQ in the library ORDLIB. Because the data structure PARMDS is passed as the parameter (line 70), the data contained in all subfields within the data structure is accessible by the called program. The called program, CUSTINQ, should contain a parameter similar to PARMDS to receive the data.
Example 5.15: Calling a program and passing a data structure name as the parameter.
.....DName+++++++++++EUDS.......Length+TDc.Functions++++++++++++++++++++++++++++ 0010 D ParmDS DS 0020 D CustNbr 7p 0 0030 D SearchData 50A 0040 D RtnCode 1A 0050 D PgmToCall C Const('ORDLIB/CUSTINQ') .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0060 C CALL PgmToCall 56 0070 C PARM PARMDS
In Example 5.15, the program name CUSTINQ is defined by the named constant PGMTOCALL (line 50) and is used by the CALL operation (line 60) to call the program CUSTINQ in the library ORDLIB. The data structure PARMDS is passed as the parameter (line 70), so the data contained in all subfields within the data structure is accessible by the called program. The called program, CUSTINQ, should contain a parameter similar to PARMDS to receive the data. (For more information on parameters and parameter lists, see the PARM and PLIST operation codes in Examples 5.104 and 5.105.)
A called program can be qualified to a library by appending the library to the program name. If a library name is omitted, the library list or path is searched for the program name. Typically, a program is qualified to a library using one of the following methods:
library/program Using the OS/400 convention, the forward slash qualifies the library to the program; the library name is followed by the program name.
d:\directory\program[.exe] Using the SPEC 1170 convention, the back slash qualifies the program name to a directory or subdirectory. Also, a colon can be used to qualify the disk drive on which the program resides.
Note | The terms path and folder are sometimes used in place of directory. Also, the file suffix is optional. |
The CALLB operation evokes a subprogram or subprocedure that has been statically linked (bound) into the main program.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
CALLB(D E) | 'procedure name' | [parameter list] | [error] | [LR} |
See also CALL, CALLP, PARM, and PLIST
Factor 2 must contain the name of the procedure to be called. Factor 2 must contain a value that can be evaluated at compile time. This includes a quoted literal, a named constant, or a procedure pointer.
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | N/A | |
73 – 74 | 2 | [error] | An error occurred during the operation. |
75 – 76 | 3 | [ LR ] | The called program ended with its LR indicator set on. |
The name within the quotes (specified for factor 2) is case sensitive. It must be in the proper upper-/lowercase character mix to match the called procedure name. Factor 2 cannot contain a character field name.
Extender | Description |
---|---|
E | ERROR - Causes the %ERROR and %STATUS built-in functions to be set if an error occurs during the operation. |
D | Operational Descriptor - Causes additional information about each parameter to be passed to the called procedure. |
The result field is optional and may contain the name of a parameter list (PLIST) label. The parameter list is used to pass parameters between the programs. If the parameter list is omitted and parameters are required, the CALLB operation may be immediately followed by one or more PARM operations to identify the parameters.
In Example 5.16, line 30 uses the named constant defined on line 10 to call the procedure. Note that, by using an RPG name in factor 2, uppercasing and lowercasing can be ignored. Line 40 uses the procedure pointer PGETCURSOR to call the procedure. Also, a parameter list is named in the result field. Line 50 uses the standard CALLB operation with a literal specified in factor 2. Note that the literal must be the correct uppercase/lowercase character pattern—matching the actual procedure name.
Example 5.16: Calling a bound procedure.
.....DName+++++++++++EUDS.......Length+TDc.Functions++++++++++++++++++++++++++++ 0010 D GetCsrLoc C Const('QsnGetCsrLoc') 0020 D pGetCursor S * INZ('%paddr('QsnGetCsrLoc')) PROCPTR .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0030 C CALLB GETCSRLOC 0040 C CallB pGetCursor TheParms 0050 C CallB 'QsnGetCsrLoc'
In Example 5.16, lines 30, 40, and 50 all produce the same result. They illustrate the three basic methods of calling a bound procedure with the CALLB operation.
The names defined on lines 10 and 20 in Example 5.16 can be used in any combination of upper- and lowercase. However, the value they represent, 'QsnGetCsrLoc', must be in the correct uppercase/lowercase format or the compiler won't able to resolve the procedure's address correctly at compile time.
Any procedure can be called with the CALLB operation. The procedure must exist at compile time within a *MODULE object. That *MODULE object name is specified as an argument (parameter) of the compiler when the program/procedure containing the CALLB operation is compiled.
The CALLP operation evokes a statically bound procedure or dynamically calls a program. The procedure or program specified in factor 2 must be defined with a prototype on the definition specifications.
Factor 1 | OpCode | Extended Factor 2 |
---|---|---|
CALLP(E M R) | procedure-name(parm1 : parm2 ...) |
See also CALL and CALLB
Factor 2 must contain the name of a prototype. The prototype (which can also be a prototype for a procedure or program) must be prototyped on a definition specification. The actual name of the procedure or program to call is specified on the EXTPGM or EXTPROC keyword of the definition specification. If EXTPROC or EXTPGM is not specified, then EXTPROC is assumed and the name on the definition specification (positions 7 to 21) is used as the procedure name.
Extender | Description |
---|---|
E | ERROR - Causes the %ERROR and %STATUS built-in functions to be set if an error occurs during the operation. |
M | If expressions are specified for any of the parameters, the maximum-digits format for expressions is used. |
R | If expressions are specified for any of the parameters, the result value's decimal positions are used for any intermediate result values. This is only useful, on this operation, when the %DEC built-in function is specified for one of the parameter values. |
Use this operation in place of the CALL and CALLB operations. It combines the function of these other operations and provides a single, consistent method for calling other procedures and programs.
In Example 5.17, the AS/400 system API (QWCRSVAL) is used to retrieve the serial number of the system. Lines 120 to 170 are the prototype for QWCRSVAL. The EXTPGM keyword identifies the external name of the program that is being prototyped, and GETSYSVALUE is the name assigned to the prototype. The prototype name is the name that must be used within the RPG program.
Example 5.17: Calling a procedure or program that has been prototyped.
.....DName+++++++++++EUDSFrom+++To+++++TDc.Functions++++++++++++++++++++++++++++ 0010 D APIerror DS 0020 D* Number of bytes in error return code parameter 0030 D Length 10i 0 INZ(%size(ApiError)) 0040 D ByteAvail 10i 0 INZ(0) 0050 D MsgID 7A 0060 D MsgText 80A * 0080 D nSysValLen S 10I0 INZ(%Size(SRLNBR)) 0090 D nCount S 10I0 INZ(1) 0100 D SrlNbr S 8A * 0120 D GetSysValue PR ExtPgm('QWCRSVAL') 0130 D gsvRtnVar 8A 0140 D gsvSVLen 10I Const 0150 D gsvCount 10I 0160 D gsvSysVal 10A Const 0170 D gsvApiErr 96A .....CSRn01..............OpCode(ex)Extended-factor2+++++++++++++++++++++++++++++ 0200 C CallP GetSysvalue('QSRLNBR' : nSysValLen : nCount : 0210 C SrlNbr : APIError)
Lines 20 and 21 use the CALLP operation to call QWCRSVAL. The prototype name GETSYSVALUE is used on line 20 to identify the program to call. The program parameters are specified as arguments of the GETSYSVAL program, and are separated by colons.
The CASxx operation compares factor 1 to factor 2. If the result is true, one or both of the following occurs:
The subroutine (internal call) named in the result field is performed.
Any resulting indicators are set on.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
[compare value 1] | CASxx | [compare value2] | subroutine | [1>2] | [1<2] | [1=2] |
See also EXSR, BEGSR, ENDSR, IF, SELECT, and WHEN
Factor 1 can contain any valid data type. Factor 2 must contain a value with attributes similar to factor 1. For example, if factor 1 contains a numeric field, factor 2 must contain a numeric value (such as another numeric field), a numeric literal, or a numeric-figurative constant.
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | [1>2] | Factor 1 is greater than factor 2. |
73 – 74 | 2 | [1<2] | Factor 1 is less than factor 2. |
75 – 76 | 3 | [1=2] | Factor 1 is equal to factor 2. |
The xx is optional and can be any valid Boolean operator (EQ, GE, GT, LE, LT, NE, or blanks). See Table 5.9. The Boolean operator controls the comparison and whether the subroutine specified in the result field is called.
At least one resulting indicator must be specified when the xx operator is blank. The resulting indicator(s) is set on based on the result of the comparison. If factor 1 and factor 2 are not specified, then no resulting indicators can be specified.
If the comparison between factor 1 and factor 2 is met, the subroutine specified in the result field is called. Upon completion of the subroutine, control passes to the END or ENDCS statement associated with this CASxx group. If the comparison is not met, control passes to the next sequential CASxx operation. If no additional CASxx operations are specified for this CASxx group, control passes to the END or ENDCS statement associated with this CASxx group.
If xx is blank, the subroutine named in the result field is performed unconditionally (after any comparison is made). This form of CASxx (the CAS operation) is often used as a catchall routine at the end of a CASxx group.
The IF and SELECT-WHEN-OTHER operations provide an in-line form of the CASE group. Whereas CASxx calls a subroutine, these other operations control operations that immediately follow them. When using the IFxx operation, try to avoid nesting the IF statements more than three levels deep. If further nesting is required, the CASxx and SELECT-WHEN-OTHER operations provide better readability. For more information on in-line CASE groups, see the subheadings IFxx (If Conditional Comparison) and SELECT (Start In-Line Case Group).
The CASE group of a CASxx operation is a list of one or more consecutive CASxx statements that conditionally perform (i.e., call) an internal subroutine. The CASE group is ended with a single ENDCS statement. An ENDCS statement must be used to close the CASE group, regardless of the number of CASxx statements. In Example 5.18, assume the fields are set to the following values:
QTYORD=100, QTYOH=200 ORDSTS='S', SHPSTS='S'
Example 5.18: Testing for less than, equal, and a catch-all situation.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C QTYORD CASLT QTYOH SHIP 0020 C ORDSTS CASEQ SHPSTS BILL 545658 0030 C CAS POST 0040 C ENDCS
The result of the comparison (line 10) is true; therefore, subroutine SHIP is called.
After subroutine SHIP has completed, control returns to the ENDCS statement associated with the CASE group (line 40); lines 20 and 30 are not performed. Figure 5.1 illustrates the logic of the two CASE constructs.
Figure 5.1: Logic flow of the two forms of CASxx.
In Figure 5.1, the left-most flowchart illustrates the traditional CASE construct—a relationship test followed by a process; another relationship test is followed by a process, and is repeated as needed.
The right-most flowchart shown in Figure 5.1 illustrates an alternative form of the CASE construct—a relationship test followed by a process; another relationship test is followed by a process; and then a default process, which is performed when all of the CASE relationship tests are false.
Only one process of a CASE group is performed when the CASE group is entered. After a process is performed, control passes to the corresponding ENDCS statement for the CASE group.
The CAT operation concatenates factor 1 and factor 2, placing the concatenated string in the result field.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
[string 1] | CAT (P) | string 2 [:blank-count] | concatenated result |
See also EVAL, +, MOVE, MOVEL, and %TRIM
Factor 1 is optional and can contain any character variable, constant, or named constant. If factor 1 is omitted, the result field is used in place of factor 1. Factor 2 is required and can contain any character variable, constant, or named constant.
Factor 2 accepts one optional parameter: BLANK-COUNT. This parameter is used to specify the number of blanks inserted between the last nonblank character of factor 1 and the first nonblank character of factor 2. If the BLANK-COUNT parameter is omitted, factor 2 is concatenated to the end of factor 1. BLANK-COUNT can be a literal value, named constant, numeric field, or numeric-data structure subfield.
The result field must be a character field, array element, data structure, or data-structure subfield. If the length of the result field is less than the sum of the result of the CAT operation, the concatenated value is stored left justified in the result field.
The P operation extender can be specified to cause the result to be padded; that is, the result field is replaced before the CAT operation is performed. In Example 5.19, the constant 'RPG ' is concatenated with 'Lang':
After line 10 is performed, NAME1 contains: 'RPG Lang '
After line 20 is performed, NAME2 contains: 'RPGLang '
After line 30 is performed, NAME3 contains: 'RPGIV '
After line 40 is performed, NAME3 contains: 'RPGIV Language'
Example 5.19: Concatenating two values.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C 'RPG ' CAT(p) 'Lang' NAME1 15 0020 C 'RPG ' CAT(p) 'Lang':0 NAME2 15 0030 C 'RPG ' CAT(p) 'IV':0 NAME3 15 0040 C CAT 'Language':1 NAME3
The CAT operation is typically used to build proper salutations, such as: 'Dear President Kennedy,' or to format an address, such as: 'Washington, DC 20500'. In Example 5.20, the fields shown in Figure 5.2 are initialized as indicated.
Example 5.20: Using CAT to build an address line.
.....C*Rn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq C 'President' CAT (p) FNAME:1 ADDR1 35 C If MIDDLE <> *Blanks C CAT MIDDLE:1 ADDR1 C CAT '.':0 ADDR1 C EndIf C CAT LNAME:1 ADDR1 * Second, simply copy the street address. C MOVEL(p) ADDR ADDR2 35 * Third, build the city, st zip line. C CITY CAT(p) ',':0 ADDR3 35 C CAT STATE:1 ADDR3 C CAT ZIP:2 ADDR3
Positions: *...v... 1 ...v... 2 ...v... 3 ...V FNAME = 'John ' MIDDLE = 'F' LNAME = 'Kennedy ' ADDR = '1600 Pennsylvania Ave ' CITY = 'Washington ' STATE = 'DC ' ZIP = '20500 '
The output from Example 5.20 is as follows:
President John F. Kennedy
1600 Pennsylvania Ave
Washington, DC 20500
The CHAIN operation retrieves a single record using the key index or relative record number specified in factor 1 from the file represented in factor 2.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
key value or record | CHAIN(N E) | format name | n/f | [error] | ||
key value or record | CHAIN(N E) | file name | [data structure] | n/f | [error] |
See also READ, READE, READPE, SETLL, SETGT, WRITE, UPDATE, DELETE, and UNLOCK
Factor 1 is required and must be a constant index, a constant relative record number, a field containing an index, a field containing a relative record number, or a key list. Factor 2 is required and must conform to the following rules:
For an externally described file, a file or record format name may be specified.
For a program-described file, only a file name may be specified.
For a workstation file, only the name of a subfile record format may be specified.
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | n/f | The record identified by the key value or record number in factor 1 does not exist in the file specified in factor 2. |
73 – 74 | 2 | [error] | An error occurred during the operation. |
75 – 76 | 3 | N/A | Not used by this operation. |
Extender | Description |
---|---|
E | ERROR - Causes the %ERROR and %STATUS built-in functions to be set if an error occurs during the operation. |
N | NO LOCK - Causes the operation to avoid placing a record lock on records for files that have been open for update operations. |
The result field can be specified for a program-described file only. The result field can contain the name of a data structure into which the retrieved record's data is placed. When a record is retrieved, the data is placed directly into the data structure.
The following characteristics apply when a database record is accessed with the CHAIN operation.
For INPUT files, the record is retrieved, but no record locking occurs.
For OUTPUT-only files, this operation is not valid.
For UPDATE files, if the N operation extender is specified, no record locking is applied; if no operation extender is specified, the record is retrieved and locked until it is released by one of the following:
Another READ, READE, READP, READPE, or CHAIN operation.
The record is updated by an UPDATE or EXCEPT operation.
The record is deleted by the DELETE or the EXCEPT with DEL operations.
The record is implicitly released by one of the following operations:
Except operation to an empty output format (EXCEPT).
Unlock the record (UNLOCK).
Set lower limit (SETLL).
Set greater than (SETGT).
Force end of data (FEOD).
Close file (CLOSE).
In Example 5.21, the key list PART contains two key fields: the part number (PRTNBR) and the date sold (DTESLD). The key list PART is used to retrieve a record from the record format PARTFMT (line 40).
Example 5.21: Accessing an externally described file using a key list.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C PART KLIST 0020 C KFLD PRTNBR 0030 C KFLD DTESLD 0040 C PART CHAIN PARTFMT 54 0050 C MOVE *IN54 NF 0060 C NF CASEQ *ON ERROR 0070 C CAS UPDATE 0080 C END
If a record does not exist with a matching index, resulting indicator 1 (indicator 54) is set on. That indicator is then placed into the field NF (line 50), which is subsequently used to control the flow of the program's logic.
In Example 5.22, a program-described file is accessed through the INDEX key field. The index value is assembled using the fields PRTNBR (part number) and DTESLD (date sold). Then the CHAIN operation is used to access the file PARTMST. If a record exists with an index value that matches factor 1, the data from that record is moved into the data structure PARTDS. Resulting indicator 1 (indicator 54) remains off.
Example 5.22: Reading a program-described file into a data structure.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C MOVEL PRTNBR INDEX 0020 C MOVE DTESLD INDEX 0030 C INDEX CHAIN PARTMST PARTDS 54 0040 C MOVE *IN54 NF 0050 C NF CASEQ *ON ERROR 0060 C CAS UPDATE 0070 C END
The CHECK operation verifies that each character of factor 2 is one of the list of characters in factor 1. This is accomplished by comparing the characters of factor 2, character by character, to the list of characters in factor 1 until a difference is detected or until the end of factor 2 is reached. If a difference is detected, its position is returned to the result field.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
check list | CHECK (E) | base value [ : start] | [position(s)] | [error] | [found] |
See also CHECKR, SCAN, and %FOUND
Factor 1 is required and must contain a character field, data structure, data structure subfield, array element, constant, or named constant. Factor 1 contains a list of one or more characters that is used to verify factor 2. Factor 2 is required and can contain a field, data structure, data-structure subfield, array element, constant, or named constant that is verified against factor 1.
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | N/A | Not used by this operation code. |
73 – 74 | 2 | [error] | The operation ended in error. |
75 – 76 | 3 | [found] | A character other than those specified in factor 1 is found in factor 2. |
Extender | Description |
---|---|
E | ERROR - Causes the %ERROR and %STATUS built-in functions to be set if an error occurs during the operation. |
Factor 2 accepts one optional parameter: START-POSITION . This parameter is used to specify the starting position of factor 2 where the verification begins. If the START-POSITION parameter is omitted, verification begins in position one of factor 2. START-POSITION can be a literal value, named constant, or numeric field.
The result field is optional and can contain a numeric field, array, or array element. The CHECK operation returns the position within factor 2 that is not contained in the list of characters located in factor 1. If all the characters of factor 2 match factor 1, zero is returned to the result field. If the result field contains an array, the positions of as many occurrences of invalid characters as there are array elements can be returned with one CHECK operation.
The CHECK operation is primarily used for two functions. One function is to find the first character position of factor 2 that is not in factor 1. An example would be to find the first nonblank character position of the field in factor 2. The second function is to verify that factor 2 contains valid characters—those specified in factor 1. An example would be to verify that factor 2 contains only numbers or only lowercase alphabetic characters.
In Example 5.23, the character field INPUT is verified against the named constant HEXCHARS.
Example 5.23: Verifying factor 2 against a list of characters.
.....DName+++++++++++..C...................Functions++++++++++++++++++++++++++++ 0001 D HexChars C Const('1234567890ABCDEFabcdef') .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0002 C HexChars Check Input Pos 5 0 0003 C If Pos > 0 0004 C EXSR Error 0005 C EndIF
If INPUT contains any characters other than those specified for HEXCHARS, the position within INPUT of the invalid character is returned in the POS field.
Before:
*...v... 1 ...v... 2 ...v... 3 INPUT = 'FDE6GE7B ' POS = 0
After:
*...v... 1 ...v... 2 ...v... 3 INPUT = 'FDE6GE7B ' POS = 5
In Example 5.24, the CHECK operation is used to locate the first nonblank position in the field LASTNAME.
Example 5.24: Using CHECK to find first nonblank character in a field.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0001 C ' ' CHECK LASTNAME NonBlank 5 0 * Left justify the value within the field 0002 C If NonBlank > 0 0003 C Eval LastName = %subst(LastName : NonBlank) 0004 C EndIF
The %SUBST (substring) built-in function is used to left justify the value.
Before:
*...v... 1 ...v... 2 ...v... 3 LASTNAME = ' Kennedy '
After:
*...v... 1 ...v... 2 ...v... 3 LASTNAME = 'Kennedy '
Example 5.25 begins by locating the first nonblank position of the LSTNAM field.
Example 5.25: Using CHECK to build a proper salutation.
.....C*Rn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0001.C ' ' CHECK LASTNAME FirstBlank 5 0 0002 C Eval LastName = %SUBST(lastname : FirstBlank) 0003 C FIRSTNAME CAT(p) LASTNAME:1 NAME 30
Using the %SUBST built-in function, the value is left justified. Finally, the CAT operation is used to build the concatenated salutation.
Before:
*...v... 1 ...v... 2 ...v... 3 FIRSTNAME = 'Robert ' LASTNAME = ' Kennedy ' NAME = ' '
After:
*...v... 1 ...v... 2 ...v... 3 FIRSTNAME = 'Robert ' LISTNAME = 'Kennedy ' NAME = 'Robert Kennedy '
The CHECKR operation verifies that each character of factor 2 is contained in the list of characters in factor 1. This is accomplished by comparing each character in factor 2, starting with the right-most position, to the list of characters in factor 1. The verification stops when a difference is detected or the first position of factor 2 is reached. If a difference is detected, its position is returned to the result field.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
check list | CHECKR (E) | char value [: start] | [position(s)] | [error] | [found] |
See also CHECK and SCAN
Factor 1 is required and must contain a character value. The character value identifies the svalid characters that can appear in factor 2. Factor 2 is required and must contain a character value. This character value is verified against the list of characters specified in factor 1. Verifications begin with the right-most character in factor 2 or, if specified, with the start position.
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | N/A | Not used by this op code. |
73 – 74 | 2 | [error] | The operation ended in error. |
75 – 76 | 3 | [found] | A character other than those specified in factor 1 is found in factor 2. |
Extender | Description |
---|---|
E | ERROR – Causes the %ERROR and %STATUS built-in functions to be set if an error occurs during the operation. |
Factor 2 accepts one optional parameter: START-POSITION. This parameter is used to specify the starting position where the verification begins in factor 2. If the START-POSITION is omitted, verification begins in the right-most position of the value specified for factor 2. The START-POSITION can be any numeric value.
The result field is optional and, if specified, must contain the name of a numeric field, array, or array element. The CHECKR operation returns the right-most position of factor 2 that is not listed in factor 1 to the result field. Multiple unmatched positions can be located with a single CHECKR operation by specifying a numeric array in the result field. If an array is specified for the result field, the operation is repeated until all available array elements have been filled or until the beginning of factor 2 is reached.
If no result field is specified, resulting indicator 3 is required and can be used to signal when a character other than those specified in factor 1 is found in factor 2. Alternatively, the %FOUND built-in function can be used to detect when the value in factor 1 is found in factor 2.
If the result field is not specified, resulting indicator 3 is required. Indicator 3 also is used to signal when a character is found in factor 2 that is other than those specified in factor 1. The CHECKR operation is the complement of the CHECK operation. The CHECK operation begins checking from the left and continues checking to the right. The CHECKR operation begins checking on the right and continues checking to the left.
The CHECKR operation is useful for determining the length of the data in a field. When variable-length data is used in an RPG program, the program must maintain the length of the data. The CHECKR operation can be used to retrieve the length of the data, and then store that length as a 2-byte integer field that precedes the variable-length field's data.
For example, by specifying a blank in factor 1, the CHECKR operation returns the position of the last nonblank in factor 2. This position is the length of the data in the field specified for factor 2 (see Example 5.26).
Example 5.26: Finding the length of data for a variable-length field.
.....DName+++++++++++EUDS.......To/Len+TDc.Functions++++++++++++++++++++++++++++ 0001 D VarLenText DS 0002 D Length 5I 0 INZ 0003 D Title 512A .....C*Rn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0004 C 'President' CAT (p) 'John':1 Title 35 0005 C CAT 'F.':1 Title 0006 C CAT 'Kennedy':1 Title 0007 C ' ' CHECKR Title LENGTH
After the CAT operations on lines 4 to 6 are performed, the length field is set to 25 and the title field contains the following:
The CLEAR operation sets the result field to blanks, zeros, or the logical '0', depending on its attribute. The CLEAR operation is primarily used to clear all the subfields of a data structure or all the fields of a display-file record format.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
[*NOKEY] | CLEAR | [*ALL] | variable to clear |
See also RESET and *INZSR
Factor 1 is optional and can contain the constant *NOKEY when the result field contains a record format of a keyed database (DISK) file. This indicates that the key fields of the record are to be preserved (i.e., not cleared) when the record format is cleared.
Factor 2 is optional and can contain the constant *ALL. When *ALL is specified and the result field contains an array, multiple-occurrence data structure, or a record format that is declared as input-only or output-only, all elements, occurrences, or fields are cleared in that object. The result field is required and can contain a field, data structure, data-structure subfield, record format, array, array element, table, or named indicator.
If the result field contains a record format, the corresponding file must be opened for update, output-only, or combined (input/output) processing, and must be used in the program with an output operation code or cycle output. The *ALL option in factor 2 is required in order to clear a record format for a file that is declared as input-only. If *ALL is not used, only fields defined as output or input/output are cleared. Fields declared as input-only are not cleared.
If the result field contains an array name, the entire array (every element) is cleared. When the result field contains an array element, such as ARR(3), only that element is cleared.
If the result field contains a multiple-occurrence data structure, the current occurrence of the data structure is cleared unless *ALL is specified in factor 2. When the result field contains a data structure, each subfield is cleared in order of its appearance in the data structure. The sequence in which the subfields are specified in the definition specifications controls the sequence of the clearing. The first field listed in the data structure definition specification is cleared first, followed by the second field, followed by the third field, etc.
The CLEAR operation ignores initial values because it moves either blanks or zeros into a variable based on the variable's attribute. If the application requires resetting a variable to its initial value, the RESET operation should be used. For more information, see the subheading RESET (Reset Variable to Its Initial Value).
Each data type supported by RPG is set to a specific low value when it is cleared. Table 5.16 lists the value to which each data type is set by the CLEAR operation.
Data Type | Value Set by the CLEAR Operation |
---|---|
Numeric | 0 |
Character | Blanks |
Indicator | '0' |
Pointer | *NULL |
Date | 1st of January, 0001 (with century) 1st of January, 1940 (*MDY, *DMY, *YMD, and *CYMD formats) |
Time | 00:00:00 (*ISO format)12:00 AM (*USA format) |
Timestamp | 0001-01-01-00.00.00.000000 |
It should be pointed out that the default initial value for all data structure subfields is blanks. Unlike the RESET operation, which moves the initial value into a variable, the CLEAR operation moves the values listed in Table 5.16 to the various fields. When used in conjunction with a data structure, the CLEAR operation sets each subfield to an appropriate value versus the RPG initial value of blanks.
The initial value for data structure subfields also can be set to reflect the subfield's attribute by specifying the INZ keyword on the data structure header or on the individual subfields. Also, a distinct initial value can be specified as the parameter of the INZ keyword.
When the CLEAR operation is performed within the *INZSR subroutine, the cleared value becomes the initial value. Using CLEAR within the *INZSR subroutine overrides any initial value specified for the variable.
In Example 5.27, the subfields of the data structure named ITEM are cleared as follows:
Zeros are moved to the subfield PRICE.
Zeros are moved to the subfield COST.
Zeros are moved to the subfield ITEMNUM.
Blanks are moved to the subfield ITEMCHAR—replacing the zeros moved into the ITEMNUM subfield.
Blanks are moved to the subfield ITEMDESC.
Example 5.27: Clearing a data structure.
.....DName+++++++++++EUDS.......Length+TDc.Functions++++++++++++++++++++++++++++ 0001 D Item DS 0002 D Price 7P 2 0003 D Cost 7P 2 0004 D ItemNum 4S 0 0005 D ItemChar 4A Overlay(ItemNum) 0006 D ItemDesc 50A .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0007 C CLEAR Item
The CLOSE operation closes the file specified in factor 2 and optionally closes all opened files when *all is specified for factor 2.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
CLOSE(E) | file name | [error] | ||||
CLOSE(E) | *ALL | [error] |
See also OPEN and %OPEN.
Factor 2 must contain the name of the file being closed or *ALL. If factor 2 contains the value *ALL, all files currently opened in the program are closed. When a file is closed, it is disconnected from the program and can no longer be accessed by the program. If the file must be accessed again—in the same program—it must be opened with the OPEN operation.
A pre-runtime table or array file name (indicated by the FROMFILE keyword on the definition specification) cannot be specified in factor 2. While an output table or array (indicated by the TOFILE keyword on the definition specification) can be specified in factor 2, its records aren't written out to disk until the program ends with the LR indicator on.
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | N/A | Not used by this operation. |
73 – 74 | 2 | [ error ] | An error occurred during the operation. |
75 – 76 | 3 | N/A | Not used by this operation. |
Extender | Description |
---|---|
E | ERROR – Causes the %error and %status built-infunctions to be set if an error occurs during the operation. |
In Example 5.28, the file CUSTMAST is closed. If the CLOSE operation doesn't complete successfully, resulting indicator 2 (indicator 73 in this example) is set on, signaling that the close attempt failed.
Example 5.28: Closing a data file by naming the file.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C CLOSE CUSTMAST 73
The COMMIT operation is a relational database management function. It performs the commitment function of the Relation Model by making all modifications that have been performed since the previous commit or ROLBK operation.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
[boundary] | COMMIT(E) | [error] |
See also ROLBK
Factor 1 is optional and can contain a value that is used as a boundary identification. A recovery process can use this identification after an abnormal application termination occurs. The boundary identifier is logged to one of many optional locations, such as a data file, message queue, or data area. One optional location can be specified outside the RPG program to a system function.
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | N/A | |
73 – 74 | 2 | [error] | An error occurred during the operation. |
75 – 76 | 3 | N/A |
Extender | Description |
---|---|
E | ERROR – Causes the %ERROR and %STATUS built-in functions to be set if an error occurs during the operation. |
The COMMIT operation is performed on all files that currently are under commitment control for the session or activation group regardless of whether they are actually defined in the program performing the COMMIT operation.
When the COMMIT operation is performed, all records that have been locked during and by the commit process are released (including records that have been committed outside of the domain of the current program). The COMMIT and ROLBK operations are ignored at runtime when the value for the file continuation keyword for commitment control (COMMIT) has a value of '0' (such as *OFF) specified. Example 5.29 shows code to commit with a boundary identifier.
Example 5.29: Committing with a boundary identifier.
.....FFileName++IFEASFRlen+LKeylnKFDevice+.Functions++++++++++++++++++++++++++++ 0010 FCUSTMAST IF E DISK COMMIT .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0020 C MOVE 'POST03' BNDRY 16 0030 C BNDRY COMMIT 56
The COMP operation compares factor 1 to factor 2. Resulting indicators 1, 2, and 3 are set on according to the outcome of the comparison. One or more resulting indicators are required for the COMP operation. If three resulting indicators are specified, no more than two may be the same indicator.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
compare value 1 | COMP | compare value 2 | [1>2] | [1<2] | [1=2] |
See also IFxx, CABxx, CASxx, and WHENxx.
Factor 1 can contain any RPG variable, including a literal value, field, data structure, data structure subfield, array, array element, or figurative constant such as *BLANKS.
Factor 2 must contain a value with attributes similar to factor 1. For example, if factor 1 contains a numeric field, factor 2 must be a numeric field, a numeric constant, or a numeric-figurative constant (such as *ZEROS). If factor 1 is a character, factor 2 must also be a character.
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | [1>2] | Factor 1 is greater than factor 2. |
73 – 74 | 2 | [1<2] | Factor 1 is less than factor 2. |
75 – 76 | 3 | [1=2] | Factor 1 is equal to factor 2. |
In Example 5.30, the STATE field is compared to the constant 'IL' on line 10. If STATE is equal to 'IL', resulting indicator 3 (indicator 58 in this example) is set on. On line 20, the numeric field AMOUNT is compared to the constant 5000.00 and sets on the appropriate indicators.
Example 5.30: Comparing fields to constants.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C STATE COMP 'IL' 58 0020 C AMOUNT COMP 5000.00 545658
The DEALLOC operation is used to return storage (memory) allocated at runtime to the system. Only memory previously allocated with the ALLOC or REALLOC operations can be de-allocated.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
DEALLOC (E N) | Pointer variable | [error] |
See also ALLOC and REALLOC
The result field is required and must contain a field of type pointer. The address stored in the pointer must be that of memory allocated by an ALLOC or REALLOC operation. Any time storage is allocated, it should be deallocated (returned back to the system) before the program ends. The RPG language does not perform so-called garbage collections. In other words, RPG doesn't automatically return allocated storage to the system when the program ends.
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | N/A | |
73 – 74 | 2 | [error] | An error occurred during the operation. |
75 – 76 | 3 | N/A |
Extender | Description |
---|---|
E | ERROR – Causes the %ERROR and %STATUS built-in functions to be set if an error occurs during the operation. |
N | SET TO NULL – Causes the pointer variable specified in the result field to be set to null (X'00') after the storage is returned/released back to the system. |
Line 5 in Example 5.31 returns the memory allocated on line 3 to the system. The pointer field pSTRING is set to null after the DEALLOC operation is performed.
Example 5.31: Using DEALLOC to return memory to the system.
.....DName+++++++++++EUDS.......Length+TDc.Functions++++++++++++++++++++++++++++ 0001 D String S 500A Based( pString ) .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0002 * Allocate 500 bytes of memory 0003 C ALLOC(E) 500 pString 0004 C MoveL 'abcdefg' STRING 0005 C DeAlloc(N) pString
The DEFINE operation can be used to declare new fields based on existing fields. DEFINE also is used to assign an external data area to a program variable. The data area is then accessible through the program variable. Conditioning indicators are not valid for this operation. Result indicators also are not valid for this operation.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
*LIKE | DEFINE | based-on variable | variable | |||
*DTAARA | DEFINE | source | target |
See also IN, OUT, *DTAARA, and the LIKE keyword
The first form of DEFINE defines a derived field. It is a field based on the attributes of another field. The length and data-type are inherited. This form of the DEFINE operation is deprecated. See the LIKE keyword on the definition specification.
The second form of DEFINE assigns a field to an external data area. When the field is referenced by an IN, an OUT, or an UNLOCK operation, the data area assigned to the variable is read, written, or unlocked. Factor 1 is required and can contain one of the following:
Factor 1 | Description |
---|---|
*LIKE | Defines a derived field. The field specified in the result field inherits the attributes of the field specified in factor 2. If factor 2 contains an array name, the result field is based on the attributes of an array element (not the array). If factor 2 contains a numeric field, the attribute of the new field is always (incorrectly) packed decimal. This is in contrast with the LIKE keyword, which correctly declares the new field with the same attributes as its "based on" field. |
*DTAARA | Defines a field as a data area. The data in factor 2 is assigned to the field. When the variable specified in the result field is referenced by the IN, OUT, or UNLOCK operations, the data area specified in factor 2 is accessed. |
The preferred method to declare a field reference or a data area is to use the LIKE and DTAARA keywords on the definition specification. While there is no performance or storage penalty for using the DEFINE operation, the definition specification is generally accepted as the preferred method of declaring derived fields. If *LIKE is specified for factor 1, the following conditions apply:
Factor 2 must contain the name of a field, data structure, array, or array element that is used as a basis for a derived field.
If factor 2 contains an array name, an element of the array is used as the basis for the derived field.
The result field must contain the name of the field that is derived from (based on) factor 2.
The derived field's length is equal to the length of the field specified in factor 2. The field's derived length can be overridden by specifying a relative or absolute field length in the result field length.
Relative size allows a shorter field length to be calculated by the compiler. To indicate a relative field length, prefix the derived field's length with a plus (+) or minus (-) sign. By specifying the plus or minus sign, the result field length is used as the relative size of the new field. Therefore, for example, a value of +5 in the result field length generates a derived field where the length is five positions longer than the based-on field's length.
On line 10 in Example 5.32, the field ACTNBR is defined and is three positions longer than the field CSTNBR. Line 20 defines the field OLDACT with a length of two positions less than CSTNBR, and line 30 defines the field SAVCST with the same attributes (i.e., length and type) as CSTNBR.
Example 5.32: Defining three derived fields.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C *LIKE DEFINE CSTNBR ACTNBR +3 0020 C *LIKE DEFINE CSTNBR OLDACT -2 0030 C *LIKE DEFINE CSTNBR SAVCST
If *DTAARA is specified for factor 1, the following conditions apply:
Factor 2 may optionally contain the name of an external data area. If the system supports a Local Data Area, *LDA may be specified in factor 2. If the system supports the program information Parameters Data Area, *PDA may be specified for factor 2. If factor 2 is omitted, then the value specified in the result field is used as the name of the external data area.
The result field is required and must contain the name of a field, data structure, data structure subfield, or data area data structure. The entry in the result field is used to access the external data area's data. The result field is "assigned" to the data area and is used by the IN and OUT operations.
The length of the field being assigned to the data area may be specified in the result field length
An external data area can be retrieved (read) and rewritten (updated) with the IN and OUT operations. See the subheadings IN (Read in a Data Area) and OUT (Output an External Data Area).
In Example 5.33, Line 10 defines the external data area CONTROL and assigns it to the CTRL field. In this example, the attributes (i.e., length and type) of CTRL are defined as a seven-digit packed numeric. However, the result field can be a field, data structure, or data structure subfield.
Example 5.33: Defining an external data area and assigning the data area to the field named.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C *DTAARA DEFINE CONTROL CTRL 7 0 0020 C IN CTRL 56
Line 20 retrieves (i.e., reads) the external data area CONTROL into the CTRL field. The data in the CTRL field can be used (moved, copied, changed, or deleted) without affecting the data contained in the external data area. The data in the external data area is not affected until an OUT operation to CTRL is performed.
If the data area doesn't exist or if it has been locked by another process, resulting indicator 2 (indicator 56 in this example) is set on by the IN operation on line 20.
The DELETE operation deletes a single record from the file specified in factor 2. Factor 2 can be a file name or a record-format name.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
[key value] | DELETE (E) | file name | [n/f] | [error] | ||
[key value] | DELETE (E) | format name | [n/f] | [error] |
See also WRITE, UPDATE, READ, READPE, and CHAIN.
Indexed files may contain the following in factor 1:
A field or data structure name containing the key value.
A key-list name whose key fields contain the key or partial key value.
A constant representing the key value.
Blanks, which cause the DELETE operation to delete the record currently locked by the program.
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | [ n/f ] | Record not found. |
73 – 74 | 2 | [ error ] | Error occurred during the operation. |
75 – 76 | 3 | N/A | Not used by this operation code. |
Extender | Description |
---|---|
E | ERROR – Causes the %ERROR and %STATUS built-in functions to be set if an error occurs during the operation. |
Relative record number accessed files may contain the following in factor 1:
A numeric field with zero decimal positions that contains a positive nonzero number.
An integer constant such as 27 for record number 27.
Blanks, which cause the DELETE operation to delete the record currently locked by the program.
For externally described files, factor 2 can be either the name of the file containing the record that is deleted or the name of a file's record format whose record is deleted.
The file represented in factor 2 must be declared as an update file (i.e., the letter U must appear in position 17 of the file's file specification) to allow the DELETE operation to function. When factor 1 is used to access the record, resulting indicator 1 must be specified to signal a record-not-found condition.
In Example 5.34, the examples use the file ORDERS. The file ORDERS contains a record format name of HEADER. The file's index is made up of the key fields CSTNBR and ORDNBR. Access by CSTNBR is all that is needed in these examples.
Example 5.34: Deleting a record by specifying a key list in factor 1.
.....FFileName++IFEASFRlen+LKeylnKFDevice+.Functions++++++++++++++++++++++++++++ 0010 FORDERS UF E K DISK .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0030 C* Key list by customer number only. 0040 C CSTKEY KLIST 0050 C KFLD CSTNBR 0060 C* Delete first order for customer = 200 0070 C Z-ADD 200 CSTNBR 0080 C CSTKEY DELETE HEADER 5456
In Example 5.34, the key list CSTKEY is used by the DELETE operation to access the file ORDERS by key. If a matching key is found, its corresponding record is deleted. If no matching key is found, resulting indicator 1 is set on. If the record exists but could not be allocated, resulting indicator 2 is set on. Factor 2 of the DELETE operation contains the record format name HEADER. This is the name of the record format for the file named ORDERS.
Optionally, resulting indicator 2 may be used to signal errors that might occur during the attempt to delete the record. Possible errors that would set on resulting indicator 2 are: record allocation time-out or lack of proper authority to delete records from the file. The *STATUS variable should be checked to identify the error that caused resulting indicator 2 to be set on. See Table 5.15 for specific error codes.
In Example 5.35, the key list CSTKEY is used to access the file ORDERS through the CHAIN operation on line 80. If a record is found, the DELETE operation on line 130 deletes the record from the file.
Example 5.35: Deleting a record using CHAIN/DELETE combination.
.....FFileName++IFEASFRlen+LKeylnKFDevice+.Functions++++++++++++++++++++++++++++ 0010 FORDERS UF E K DISK .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0030 C* Key list by customer number. 0040 C CSTKEY KLIST 0050 C KFLD CSTNBR 0060 C* Delete first order for customer = 200 0070 C Z-ADD 200 CSTNBR 0080 C CSTKEY CHAIN(E) HEADER 0090 C If %ERROR 0100 C If %STATUS = 1218 0110 C EXSR TIMOUT 0120 C ENDIF 0130 C ENDIF 0140 C If %FOUND 0150 C DELETE ORDERS 0160 C ENDIF
Note | The file ORDERS is accessed through the record format HEADER on line 80 and deleted through its file name on line 150. The DELETE deletes the last record read by the program. Also, line 150 avoids using resulting indicator 2 or checking for an error condition because the CHAIN operation on line 80 retrieves and locks the record for update. |
Unlike the CHAIN, READ, and READP operations, the DELETE operation does not copy the contents of a file's fields to the input buffer. Therefore, when the program knows the index of a record, using only the DELETE operation with factor 1 specified yields better performance.
When the DELETE operation deletes a record, that record is permanently erased from storage. Also, a subsequent READ operation reads the record following the deleted record, and a READP operation reads the record prior to the deleted record.
The DIV operation is used to produce the quotient (result) of a divide operation in the form factor 1 divided by factor 2 (F1/F2)—long form—or result field divided by factor 2 (RF/F2)—short form.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
dividend | DIV(H) | divisor | quotient | [+] | [-] | [0] |
DIV(H) | divisor | quotient and dividend | [+] | [-] | [0] |
See also ADD, SUB, MULT, EVAL, MVR, %DIV, and %REM.
If factor 1 contains a value, factor 1 is the dividend, factor 2 is the divisor, and the result field is the quotient. If factor 1 is blank, the result field is used as the dividend, factor 2 is the divisor, and the result field is the quotient.
The H operation extender can be specified to cause the result to be half-adjusted—that is, rounded up. If the DIV operation is immediately followed by the MVR operation, the operator extender cannot be specified for the DIV operation.
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | [ + ] | The result field is greater than zero. |
73 – 74 | 2 | [ – ] | The result field is less than zero. |
75 – 76 | 3 | [ 0 ] | The result field is equal to zero. |
If the dividend (factor 1, long form; result field, short form) is 0, the result is 0. If the divisor (factor 2) is 0, a "divide by zero error" occurs. In this case, the default exception/error handling subroutine receives control. Therefore, the exception/error handling subroutine must be coded in the program or factor 2 must be tested before performing the divide operation. Normally, the program would compare the divisor (factor 2) to zero before the DIV operation is performed, thus avoiding a divide-by-zero error.
To capture the remainder of a DIV operation, the MVR (Move Remainder) operation must immediately follow the DIV operation. If MVR is specified, the remainder from the DIV operation is placed into the result field of a MVR operation; the H operation extender (half-adjust) cannot be specified for the DIV operation. For more information, see the subheading MVR (Move Remainder of Division).
In Example 5.36, the first DIV operation divides field A by field B, and the quotient is placed in field C.
Example 5.36: Long and short forms of division.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C If B 0 0020 C A DIV B C 0030 C DIV B C 545658 0040 C ENDIF
In the second DIV operation, field C is divided by field B, and the quotient replaces the value in field C. Also, if the quotient is greater than zero (i.e., a positive number), resulting indicator 1 is set on. If the quotient is less than zero (i.e., a negative number), resulting indicator 2 is set on. If the quotient is equal to zero, resulting indicator 3 is set on.
In Example 5.37, the remainder of A/B is stored into the field REMAINDER. If A = 5 and B = 3, then as a result of the calculations in Example 5.37, C = 1 and REMAINDER = 2.
Example 5.37: Long form division with remainder.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C A DIV B C 0020 C MVR Remainder 3 0
In Example 5.38, the H operation extender causes the quotient (result field) to be rounded. For example, if A = 7 and B = 4, then A/B = 1.75; with half-adjust in effect; the quotient is C = 2. The quotient varies based on the number of decimal positions of the result field. For example, if the quotient is defined with one decimal position, the result of the calculation would be C = 1.8 (rounding to the tenths position).
Example 5.38: Division with rounding (half-adjust).
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0020 C A DIV(H) B C
The DO operation begins a DO/ENDDO loop. The code between the DO and the ENDDO statement is called the DO group and is performed a number of times. The END or ENDDO statements close a DO/ENDDO loop. The DO operation is a structured programming construct. It contributes to, but does not cause, structured programming.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
[starting value] | DO | [limit] | [counter variable] |
See also FOR, DOW, DOU, and ENDDO
The structure of the DO/ENDDO loop is shown in Example 5.39.
Example 5.39: Structure of a DO/ENDDO loop.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq C in1Start DO Limit Count C . * Do group code goes here. C . C in2 ENDDO Increment
START is an optional starting value of COUNT. When the DO loop is entered, the value of START is placed into COUNT. If START is omitted, 1 is used as the starting value.
LIMIT is the optional upper limit of the number of times the DO loop is performed. LIMIT is compared to COUNT at the "top" of the DO loop. If COUNT is greater than LIMIT, the DO group is not performed. If LIMIT is omitted, 1 is used as the upper-limit value.
COUNT is the index or counter of the DO loop. COUNT is increased by INCREMENT at the end of each pass through the DO loop. At the top of each pass of the DO loop, COUNT is compared to LIMIT. If COUNT is greater than LIMIT, the DO loop is ended. If COUNT is omitted, an internal variable is used for the counter.
INCREMENT is factor 2 of the ENDDO statement, which contains the value that is added to COUNT when the ENDDO statement is encountered. If INCREMENT is not specified, a value of 1 is used as the INCREMENT.
IN1 is an optional indicator or set of indicators that controls the entry into the DO loop. If the conditioning indicator test is met when the DO loop is encountered, the DO loop is entered. If the conditioning indicator test is not met, the program branches to the statement following the ENDDO statement.
IN2 is an optional indicator that controls the unnatural exit from the DO loop. When the ENDDO statement is encountered and one or more conditioning indicators are present, the indicator conditions are tested. If the condition is met, the ENDDO statement is performed and control passes back up to the DO statement. If the condition is not met, control passes to the statement following the ENDDO statement, and the DO loop is exited.
The ENDDO statement is the DO loop's end marker . The end marker defines the end of the block of code controlled by the DO operation. When used in conjunction with the DO statement, ENDDO adds INCREMENT to COUNT, and then branches to the top of the DO loop.
In Example 5.40, line 40 begins the DO loop. Factor 2 of line 40 indicates that the DO loop is performed 12 times. The result field on line 40 is the field X. Defined on line 20, the X field is the counter for the DO loop. Each iteration through this DO loop increments X by 1. Lines 50 and 60 use X as an index of the ARRAY array.
Example 5.40: Performing a DO group multiple times.
.....DName+++++++++++EUDS.......Length+TDc.Functions++++++++++++++++++++++++++++ 0010 D Array S 10A Dim(12) 0020 D X S 10I 0 0030 D ArrayCount C Const(%elem(Array) .....CSRn01Factor1+++++++<—OpCode(ex)—>Factor2+++++++Result++++++++Len++DcHiLoEq 0040 C DO ArrayCount X 0050 C | If Array(x) = 'Q38' 0060 C | | MOVEL 'Midrange' ARRAY(X) 0070 C | ENDIF 0080 C ENDDO
Each time the DO loop is encountered (i.e., each time the program flow causes the DO loop to be processed), the count field (the result field of the DO operation) is automatically initialized to the value specified in factor 1 of the DO operation.
In Example 5.41, lines 10 and 20 set the outer DO...END loop START and INCREMENT fields to 5. When the DO group is started, Y is set to 5, and then it is increased by 5 during each pass through the DO loop. The limit for the outer loop is 15 and the DO group is performed three times. Because the inner loop (lines 40 to 80) is performed 12 times the number of times the outer DO loop is performed, the inner DO loop is performed 36 times.
Example 5.41: Nested DO...END groups.
.....CSRn01Factor1+++++++<—OpCode(ex)—>Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C Z-ADD 5 Start 5 0 0020 C Z-ADD 5 Increment 5 0 0030 C Start DO 15 Y 5 0 0040 C | DO 12 X 5 0 0050 C | | IF OLD(Y) = 'Q38' 0060 C | | | MoveL 'Midrange' NEW(X) 0070 C | | EndIf 0080 C | EndDo 0090 C EndDo Increment
The DOUxx operation begins a DO UNTIL loop. The code between the DOUxx and the ENDDO statement is called the DO group and is performed at least once. Conditioning indicators, if specified, are tested once before entry into the DO UNTIL group. The DOUxx operation is a structured operation. It contributes to, but does not cause, structured programming. The fixed-format versions of DOUxx (DOWEQ, DOUNE, DOULT, DOULE, DOUGT, and DOUGE) have been deprecated by the DOU operation.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
compare value 1 | DOUxx | compare value 2 | ||||
DOU | conditional expression |
See also IF, DOW, DO, FOR, WHEN, and ENDDO
The DOUxx operation performs a relationship test xx, where xx may be any one of the Boolean operators (EQ, GE, GT, LE, LT, and NE). See Table 5.8 for details. Factor 1 is compared to factor 2 based on the xx operator. Factor 1 and factor 2 must be similar data types. For the secondary form of DOU, the extended factor 2 must contain a conditional expression.
The DO UNTIL construct logically tests its condition at the bottom of the DO loop (i.e., when the ENDDO statement is encountered) and, therefore, always performs its DO group at least once. Indicators can condition the ENDDO statement. If the indicator condition is true, the ENDDO is performed normally. If the indicator condition is false, the ENDDO is not performed, and control passes to the statement following the ENDDO.
The DOUxx Boolean test can be extended with the ANDxx or ORxx operations. ANDxx allows compound conditions to be tested and ORxx allows distinct conditions to be tested.
The ANDxx and ORxx operations cannot be used in conjunction with the DOU form of this operation.
In Example 5.42, the DO group is performed until A is equal to B and D is greater than C, but it is always performed at least once.
Example 5.42: DOUxx with ANDxx extension.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C A DOUEQ B 0020 C D ANDGT C 0030 C ADD 1 B 0040 C ADD 2 D 0050 C ENDDO
In Example 5.43, the database file named DATAFILE is accessed on line 10 with the CHAIN operation. If an index exists for the key value contained in CSTNBR, the record is retrieved. The DOU operation on line 40 begins the DO loop and controls the iterations through the DO loop. The ENDDO operation on line 100 is where the logical occurrence of the relationship test is performed.
Example 5.43: DOU with OR extension to fill a subfile with 20 records.
.....CSRn01Factor1+++++++<—OpCode(ex)—>Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C CSTNBR CHAIN DATAFILE 0020 C IF %FOUND 0030 C | Z-ADD 0 RELNO 3 0 0040 C | DOU %EOF or RELNO >= 20 0050 C | | ADD 1 RELNO 0060 C | | WRITE SUBFILE 0070 C | | If NOT %EOF(subfile) 0080 C | | | READ DATAFILE 0090 C | | endif 0100 C | ENDDO 0110 C ENDIF
In Example 5.44, the DOU operation checks the variable named KEYPRESSED (line 10). If it is equal to the named constant F3, the DOU loop is ended. On line 70, the variable I is set to ZERO, and then the DOU loop is entered. This DOU loop is performed until the variable I is greater than or equal to the number of elements in the ARR array.
Example 5.44: DOU with extended factor 2 to condition a DO UNTIL loop.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C dou KeyPressed = F3 0020 C EXFMT OrdEntry 0030 C If NOT (KeyPressed = F3) 0040 C Exsr Process 0050 C endif 0060 C enddo 0070 C eval i = 0 0080 C dou i >= %elem(arr) or *IN56 0090 C Eval ARR (i + 1) = 'TK421' 0100 C Add 1 i 56 0110 C enddo
The DOWxx operation begins a DO WHILE loop. The code between the DOWxx and the ENDDO statement is called the DO group. Conditioning indicators, if specified, are tested once before entry into the DO group. The DOWxx operation is a structured operation. It contributes to, but doesn't cause, structured programming. The fixed-format versions of DOWxx (DOWEQ, DOWNE, DOWLT, DOWLE, DOWGT ,and DOWGE) have been deprecated by the DOW operation.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
compare value 1 | DOWxx | compare value 2 | ||||
DOW | conditional expression |
See also IFxx, DOUxx, DO, WHENxx, and ENDDO
The DOWxx operation performs a relationship test xx, where xx may be any one of the Boolean operators (EQ, GE, GT, LE, LT, and NE). See Table 5.8 for details. Factor 1 is compared to factor 2 based on the xx operator. Factor 1 and factor 2 must be similar data types. For the secondary form of DOW, the extended factor 2 must contain a conditional expression.
The DO WHILE construct logically tests its condition at the top of the DO loop and, therefore, only performs its DO group when the condition is true. The ENDDO statement can be conditioned by indicators. If the indicator condition is true, the ENDDO is performed normally. If the indicator condition is false, the ENDDO is not performed, and control passes to the statement following the ENDDO.
The DOWxx test can be extended with the ANDxx or ORxx operations. ANDxx allows compound conditions to be tested; ORxx allows additional, but separate, conditions to be tested. The ANDxx and ORxx operations cannot be used in conjunction with the DOW form of this operation.
In Example 5.45, the DO loop is performed while A is equal to B or C is not equal to D.
Example 5.45: DOWxx with ORxx extension.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C A DOWEQ B 0020 C C ORNE D 0030 C ADD 1 B 0040 C ADD 2 D 0050 C ENDDO
In Example 5.46, the database file named CUSTMAST is accessed on line 10 with the CHAIN operation. If an index exists for the key value contained in CSTNBR, the record is retrieved and the field EOF is set off.
Example 5.46: DOWxx with ANDxx extension to fill a subfile with 20 records.
.....CSRn01Factor1+++++++<—OpCode(ex)—>Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C CSTNBR CHAIN CUSTMAST 54 0020 C Eval EOF = *IN54 0030 C Z-ADD 0 RELNO 3 0 0040 C EOF DOWEQ *OFF 0050 C RELNO ANDLT 20 0060 C | ADD 1 RELNO 0070 C | WRITE SUBFILE 0080 C | READ CUSTMAST 58 0090 C | Eval EOF = *IN58 0100 C ENDDO
The DOWEQ ANDLT operations control entry into the DO group. First, the field RELNO (subfile relative record number) is increased on line 60, and then a SUBFILE (or tabular list panel) detail record named subfile is written. Finally, the database file CUSTMAST is read, and the DO loop is performed again. If end-of-file is reached or RELNO is equal to 20, the DO loop ends.
Normally, when processing a database file with this operation, the file is positioned to the first record to be processed before entering into the DO WHILE group.
In Example 5.47, the DOW operation checks the variable named INDEX to see if it is less than the number of elements in the STATES array (line 10). If it is less than the number of elements of STATES, the DO WHILE loop is entered. Note that the LEAVE operation (line 50) is used to exit the DO WHILE loop when the end-of-file condition is detected.
Example 5.47: DOW with extended factor 2 to condition a DO WHILE loop.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C Eval Index = 1 0020 C dow Index < %elem(States) 0030 C READ CustRec 58 0040 C If *IN58 0050 C Leave 0060 C EndIf 0070 C Eval States(Index) = CM_State 0080 C Eval Index = Index + 1 0090 C enddo 0100 C read CustRec 58 0110 C dow NOT %EOF(CUSTMAST) and NOT %EOF(subfile) 0120 C write subfile 58 0140 C read CustRec 58 0150 C enddo
On line 10, the file CUSTMAST's record (CUSTREC) is read. Then the DOW operation (line 11) is performed. The DO WHILE loop is performed while there are records read from the CUSTMAST file and while the subfile is not full.
The DSPLY operation provides a primitive form of message-level communication between the workstation operator or the system operator and the RPG program. A message can be sent (up to 52 characters) so that it returns an operator response. A message not requiring a response is also supported.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
[message text] | DSPLY(E) | [message queue] | [reply variable] | [error] |
See also DEBUG
Factor 1 is optional and can contain a message ID, a literal value, or a field with information to be displayed. If a message ID is specified, it must conform to one of the following formats:
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | N/A | |
73 – 74 | 2 | [ error ] | An error occurred during the operation. |
75 – 76 | 3 | [ 0 ] |
*Myyyy—Where *M is constant and yyyy is a user-defined message ID. For example, *M10 generates user message USR0010. The yyyy message ID must be one to four characters in length, left-justified against the *M constant.
*Mxxxyyyy—Where xxx is a message prefix such as USR, RPG, or MCH, and yyyy is a user-defined message ID. For example, *MRPG400 would generate user message RPG0400. The xxx must be three characters in length, left justified against the *M constant. The yyyy message ID must be one to four digits in length, left justified against the *Mxxx constant.
Factor 2 is optional and can contain the name of the message queue that receives the message. For example, 'QSYSOPR' causes the message to be sent to the system operator, and '*EXT' causes the message to be sent to the workstation operator. For interactive jobs, factor 2 defaults to '*EXT'. For batch jobs, factor 2 defaults to 'QSYSOPR'.
The result field can contain the name of a field that receives the workstation or system operator's reply. If the result field is omitted, the operator is not allowed to type in a reply.
If factor 1 contains a message ID, RPG retrieves the message text of the message ID from the message file named QUSERMSG. This message file name can be overridden to some other name by running the OS/400 command OVRMSGF. This command can be run outside of the RPG program or by calling a system-command processing program (e.g., QCMDEXC on AS/400) from within RPG, and passing it a string containing the OVRMSGF command.
The message ID text, constant, or field specified in factor 1 is displayed at the workstation or system operator message queue, along with any data that is contained in the result field when the DSPLY operation is performed.
If factor 1 is blank and the result field is specified, only the data contained in the result field is displayed. If the result field is blank and factor 1 is omitted, nothing is displayed.
In Example 5.48, the user-defined message USR0010, indicated by *MUSR010 in factor 1, is sent to the workstation operator. The value *EXT in factor 2 of line 10 controls where the message is sent.
Example 5.48: Display a message at the workstation.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C *MUSR010 DSPLY '*EXT' REPLY 1 0020 C IF Reply ='C' 0030 C Eval *inlr = *ON 0040 C Return 0050 C EndIf
Any response the workstation operator types in is returned to the program in the field REPLY, which is specified in the result field.
The DUMP operation generates a list of all fields, data structures, indicators, internal fields, pointers, storage areas, tables, and arrays. The DUMP operation is valid only when the DEBUG keyword is specified on the header specification. Resulting indicators are not valid for this operation.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
[descriptive text] | DUMP |
See also DEBUG keyword
Factor 1 is optional and may contain a dump identifier that is printed on the generated dump listing. The dump listing is quite similar to the formatted dump generated by the operating system.
Example 5.49 produces a formatted dump listing with 'DivBYZER' as its identifier. The fields TOTAL, ORDQTY, UNIT, and STATUS, and the indicator LR are included in the formatted dump listing along with several compiler-generated fields.
Example 5.49: Producing a dump when divide by zero occurs.
H.Functions++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 0010 H DEBUG(*YES) .....DName+++++++++++EUDS.......Length+TDc.Functions++++++++++++++++++++++++++++ 0020 D SDS 0030 D Status *STATUS .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0040 C Z-ADD 123 TOTAL 7 0 0050 C Z-ADD 0 ORDQTY 7 0 0060 C TOTAL DIV(H) ORDQTY UNIT 5 2 0070 C MOVE *ON *INLR .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0080 CSR *PSSR BEGSR 0090 C IF Status = 0102 0100 C 'DivByZer' DUMP 0110 C EndIf 0120 CSR ENDPSR EndSR
The ELSE operation is used with the IFxx operation. The ELSE operation follows the IFxx group and precedes the corresponding ENDIF statement. The group of statements between the ELSE operation and the corresponding ENDIF statement is performed when the condition specified for the IFxx is false. Conditioning indicators are not valid for this operation.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
ELSE |
See also IF and ENDIF
In Example 5.50, the field DAYS is compared to 30 and 60 days. When the IFLE operation is true, the MOVEL operation that immediately follows the IFLE operation is performed. Control then passes to the ENDIF statement associated with the IFLE operation. When the IFLE operation tests false, control passes to the ELSE statement within the IFLE group. In the example, this performs a subsequent IFLE operation.
Example 5.50: Using ELSE for conditioning.
.....CSRn01Factor1+++++++<—OpCode(ex)—>Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C IF Days <= 30 0020 C | MOVEL '0-30' AGING 0030 C +ELSE 0040 C | IF Days <= 60 0050 C | | MOVEL '31-60' AGING 0060 C | +ELSE 0070 C | | MOVEL 'Over-Due' AGING 0080 C | ENDIF 0090 C ENDIF
The ELSEIF operation evaluates the conditional expression in the extended factor 2. If the comparison is true, the group of calculations between the ELSEIF and its associated ENDIF operation (or another ELSEIF operation) are performed. Conditioning indicators are not valid for the ELSEIF operation.
Factor 1 | Op Code | Factor 2 | Result Field | Resulting Indicators |
---|---|---|---|---|
elseif (m r) | conditional expression |
See also IF, SELECT, WHEN, ELSE, DOWxx, DOUxx, CASxx, and FOR
The ELSEIF operation requires a relationship test in the extended factor 2. If the condition is true the set of operations following the ELSEIF and the corresponding ENDIF or secondary ELSEIF statement are performed. The IF operation supports the M and R operation extenders:
Extender | Description |
---|---|
M | If expressions are specified for any of the arguments of the operation, the maximum-digits format for intermediate results is used. |
R | If expressions are specified for any of the arguments of the operation, the result value's decimal positions are used for intermediate result values. This extender is useful only when the %DEC built-in function is specified for the argument. |
The ELSEIF operation is used within an if statement to allow alternative operations to be perform, should the IF statement condition fail. When an ELSEIF is used instead of separate ELSE and IF statements, only a single ENDIF statement is required. The result is that the IF/ELSEIF/ENDIF clause is an in-line case similar in functionality to the SELECT/WHEN/ENDSL CLAUSE.
In Example 5.51 that follows the ELSEIF operation is used on line 30 to test for an alternate condition. Note the use of a single ENDIF statement (line 70) for the IF/ELSEIF/ELSE/ENDIF clause.
Example 5.51: Using elseif for conditioning.
.....CSRn01Factor1+++++++<—OpCode(ex)—>Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C IF Days <= 30 0020 C | MOVEL '0-30' AGING 0030 C +ELSEIF Days <= 60 0040 C | | MOVEL '31-60' AGING 0050 C +ELSE 0060 C | | MOVEL 'Over-Due' AGING 0070 C ENDIF
The ENDxx operation closes a DO, DOUxx, DOWxx, CASxx, IFxx, or SELECT group.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
ENDxx | [increment] |
See also SELECT, WHENxx, IFxx, DO, DOwxx, DOUxx, ENDSR, and CASx
The xx of the ENDxx operation is optional and can be specified to document the type of END operation.
Op Code | Description |
---|---|
END | End an IFxx, DOxxx, SELECT, or CAS operation. |
ENDCS | End a CASxx operation. |
ENDDO | End a DO, DOwxx, or DOUxx operation. |
ENDIF | End an IFxx operation. |
ENDFOR | End a FOR operation. |
ENDMON | End a MONITOR/ ON-ERROR group. |
ENDSL | End a SELECT operation. |
Factor 2 (allowed only when closing a DO...ENDDO group) is optional and may contain the increment value for a DO loop counter.
Conditioning indicators are optional when closing a DO, DOWxx, or DOUxx group. If the conditioning indicator test is true, the ENDDO statement is performed and control passes back to the top of the loop. If the conditioning indicator test is false, control passes to the operation following the ENDDO statement. See Example 5.52.
Example 5.52: Ending a DOU loop and an IF.
.....CSRn01Factor1+++++++<—OpCode(ex)—>Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C CSTNBR CHAIN CUSTMAST 0030 C IF %EOF = *OFF 0040 C | DOU %EOF = *ON 0050 C | or RelNo >= 20 0060 C | | ADD 1 RELNO 0070 C | | WRITE SUBFILE 0080 C | | READ CUSTMAST 0100 C | ENDDO 0110 C ENDIF
The ENDSR operation marks the end of a subroutine. It must be the last statement of a subroutine. Factor 1 is optional and may contain a label that is used as the target of a GOTO or CABxx operation.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
[label] | ENDSR | [return point] |
See also BEGSR, EXSR, LEAVESR, CABxx, and CASxx
Controlling level indicators, conditioning indicators, and resulting indicators are not valid for this operation. Columns 7 and 8 must contain either the constant SR or blanks. The letters SR can be used in columns 7 and 8 of this operation to provide a visual indication of the end of a subroutine. Example 5.53 shows an example using a label. Example 5.54 shows how to cancel the program using *CANCL.
Example 5.53: Ending subroutine with a label.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C EXSR COUNT 0020 C ENDPGM TAG 0030 C MOVE *ON *INLR 0040 CSR COUNT BEGSR 0050 C ADD 1 Cnt 0060 C MOVE 'MIDRANGE' NEW(Cnt) 0070 CSR EndCount ENDSR
Example 5.54: Exception/error subroutine with program cancel.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C READ CUSTMAST 5658 0020 C *IN56 CASEQ *ON *PSSR 0030 C END 0040 CSR *PSSR BEGSR 0050 C IF Status = TIMOUT 0060 C MOVE *ON *INLR 0070 C ENDIF 0080 CSR EndPSSR EndSR '*CANCL'
Factor 2 may contain a six-position field, constant, or named constant when the subroutine is an exception/error handling subroutine. Factor 2 can contain a field name or a constant that identifies the returning point after the subroutine is performed. If the exception/error handling routine is called with either the EXSR or CASxx operations and factor 2 is blank, control returns to the statement following the EXSR or CASxx operation.
The valid exception/error return points that can be specified in factor 2 for the ENDSR operation are listed in Table 5.17.
Routine | Description |
---|---|
*DETC | Beginning of detail-time calculations. |
*DETL | Beginning of detail-time output. |
*GETIN | Get input routine (read next record). |
*TOTC | Beginning of total-time calculations. |
*TOTL | Beginning of total-time output. |
*OFL | Beginning of overflow lines. |
*CANCL | Abnormal end of program. |
blanks | Return to statement following interruption. |
The EVAL operation evaluates a mathematical equation or string expression and assigns the result to the variable specified on the left side of the equals (=) sign. For a description of RPG IV expressions and expression syntax, see chapter 4.
Factor 1 | OpCode | Extended Factor 2 |
---|---|---|
EVAL(H) | Variable or expression = variable or expression |
See also: EVALR, ADD, SUB, MULT, DIV, MVR, and MOVEL
Factor 2 is required and must contain either a string expression or a numeric equation. The expression consists of three components: the l-value, the assignment symbol, and the r-value. The l-value is the term used to describe the value to the left of the assignment symbol. The r-value is the term used to describe the value to the right of the assignment symbol. The assignment symbol is the special symbol use to separate the l-value and r-value. The equals sign (=) is used as the assignment symbol for the EVAL operation in RPG.
The result (i.e., the l-value) can be any type of variable. Also, the %SUBST built-in function can be used on either side of the assignment. When an array name is specified or an array name with an index value of * is specified for the l-value, the value specified for the r-value is copied to each element of the array. Remember the following when using the EVAL operation:
Numeric expressions that require the half-adjust operation extender can be specified.
The MVR (Move Remainder) operation is not supported following an EVAL operation. Use the %REM built-in function if a remainder is required.
Data is stored right adjusted in the resulting field.
Expressions can be used within array indexes and in %SUBST subscripts when used on the left side or right side of the expression.
Date and time data types can be used in an expression, but format conversion of date and time values to character values requires the use of the %CHAR built-in function.
The result of a conditional expression can be assigned to an indicator or named indicator variable.
The EVAL operation is the general-purpose assignment operation. It can be used to copy data from one variable to another or to perform complex mathematical and string expressions.
Example 5.55 illustrates various uses of expressions with the EVAL operation. For a description of RPG IV expressions and expression syntax, see chapter 3.
Example 5.55: Using an expression on the EVAL operation.
.....CSRn01..............OpCode(ex)Extended-factor2+++++++++++++++++++++++++++++ * Character string assignments 0001 C Eval Message = YourName + ' Ph.D' 0002 C Eval %SUBST(name : 7 : 5) = 'Cozzi' 0003 C Eval name ='Bob' + ' ' + 'Cozzi' 0004 C Eval msg = ItemDesc + %CHAR(ItemNo) + ' is out + 0005 C of stock.' * Numeric assignments 0006 C Eval Result = (1 - (Term * Principal) * Interest)/2 0007 C Eval(h) Profit = SalesQTY * (Price - Cost) 0008 C Eval area = 4*PI*Radius**2 0009 C Eval *IN58 = (Amt_Due > 1000 AND Price > 500) 0010 C Eval *INLR = count <= 30 or count > 10000 * Date/Time assignments 0011 C Eval dateSold = D'1996-06-01'
The following is a description of what occurs in Example 5.55.
Line | Description |
---|---|
1 | The YOURNAME field is concatenated together with the literal ' PH.D' and stored in MESSAGE. |
2 | The %SUBST built-in function is used to copy 'COZZI' to positions 7 through 11 of the NAME field. |
3 | Two literals and a blank are concatenated together. |
4 and 5 | The ITEMNO field is converted to character and then concatenated with the ITEMDESC field. Then a literal is concatenated to it and copied to the result. |
6 | A typical mathematical equation is performed. |
7 | The PROFIT field is assigned the value of PRICE minus cost, multiplied by SALESQTY. |
8 | The area of a sphere is calculated as 4πR2. |
9 and 10 | The indicator *IN58 is set on when the conditional expression is TRUE. |
11 | The DATESOLD field (which is of type DATE) is assigned a date literal. |
The EVALR operation evaluates a mathematical equation or string expression and assigns the result to the variable specified on the left side of the equals (=) sign. The resulting value is stored right justified in the variable specified to the left of the equals sign. For a description of RPG IV expressions and expression syntax, see chapter 4.
Factor 1 | OpCode | Extended Factor 2 |
---|---|---|
EVAL(E H M R) | Variable or expression = variable or expression |
See also EVALR, ADD, SUB, MULT, DIV, MVR, and MOVEL
Factor 2 is required and must contain either a string expression or a numeric equation. The expression consists of three components: the l-value, the assignment symbol, and the r-value. The l-value is the term used to describe the value to the left of the assignment symbol. The r-value is the term used to describe the value to the right of the assignment symbol. The assignment symbol is the special symbol use to separate the l-value and r-value. The equals sign (=) is used as the assignment symbol in RPG.
The result (i.e., the l-value) can be any type of variable. The resulting value is stored in the l-value right justified. The %SUBST built-in function can be used on either side of the assignment. When an array name is specified or an array name with an index value of * is specified for the l-value, the value specified for the r-value is copied to each element of the array. Remember the following when using the EVALR operation:
Numeric expressions that require the half-adjust operation extender can be specified.
The MVR (move remainder) operation is not supported following an EVALR operation. Use the %REM built-in function if a remainder is required.
Data is stored right adjusted in the resulting field.
Expressions can be used within array indexes and in %SUBST subscripts when used on the left side or right side of the expression.
Date and time data types can be used in an expression, but format conversion for date and time values to character values requires the use of the %CHAR built-in function.
The result of a conditional expression can be assigned to an indicator or named indicator variable.
The EVALR operation is the general-purpose assignment operation. It can be used to copy data from one variable to another or to perform complex mathematical and string expressions. The EVAL operation is the primary assignment operation code. EVALR is used when the need to store a result value right adjusted is required.
Example 5.56 illustrates the use of the EVALR operation. For a description of RPG IV expressions and expression syntax, see chapter 4.
Example 5.56: Using an expression on the EVAL operation.
.....DName+++++++++++EUDS.......Length+TDc.Functions++++++++++++++++++++++++++++ D Website S 35A .....CSRn01..............OpCode(ex)Extended-factor2+++++++++++++++++++++++++++++ * Character string assignments 0002 C EvalR website = 'www.RPGIV.com' *...v....1....v....2....v....3....v.... website = ' www.RPGIV.com'
The EXCEPT operation performs an immediate write to either a program-defined output file or an externally described file's record format.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
EXCEPT | [except label] |
See also WRITE and UNLOCK
Factor 2 can contain the name of an EXCEPT label. EXCEPT labels are used to control the output to the output record. When an EXCEPT label is present, only those output specifications that contain the EXCEPT label are written. More than one output specification can contain the same EXCEPT label.
When an EXCEPT label is not used, only those exception output records without an EXCEPT label are written, provided that the output format conditioning indicators are true. The EXCEPT operation can be used to release records of a database file that have been locked by another operation.
When an EXCEPT operation is performed on an externally described file and database fields are specified on the output specification, only those fields specified are written to the database record. Other fields within the record go unchanged. To write out all fields in the record format, the figurative constant *ALL must be the first and only field specified for the exception output.
When updating a record, fields not specified for output go unchanged. When writing a new record, fields that are not specified for output are set to their default value, typically zero or blanks—depending on their attribute. For date and time variables, they are set to their default value. If no default value has been specified in the file description (DDS) for a date or time field, the current date or time is inserted.
Examples 5.57 through 5.60 illustrate four uses of the EXCEPT operation:
EXCEPT output to a program-defined printer file.
EXCEPT output with an EXCEPT label to a program-defined print file.
EXCEPT output to an externally described database file format.
EXCEPT output to release a locked record.
In Example 5.57, the first record matching the key value in the field INDEX is retrieved from the customer master file CUSTMAST. Next, an exception output line is printed (printing the customer number and customer name). Because the EXCEPT operation on line 40 contains no except name, the output specifications on lines 80 to 100 are output and lines 110 to 120 are not.
Example 5.57: Exception output to a program-defined printer file.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C INDEX CHAIN CUSTMAST 0030 C DOW %Found 0040 C EXCEPT 0050 C INDEX READE CUSTMAST 58 0070 C ENDDO .....OFormat++++DAddn01n02n03Except++++SpbSpaSkbSka 0080 OQPRINT E 1 .....O..............n01n02n03Field+++++++++YB?End++PConstant/Editword+++++++++++ 0090 O CUST# Z 10 0100 O CSTNAM +2 0110 OQPRINT E DETAIL 1 0120 O BALDUE 3 10
In Example 5.58, the exception label DETAIL is used to control the output of the printer file. The output specifications on lines 110 and 120 print the balance due. The output specifications on lines 80 to 100 are not output because they are not conditioned by the DETAIL exception name.
Example 5.58: Exception output with an EXCEPT label to a program-described file.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C INDEX CHAIN CUSTMAST 0030 C DOW %Found 0040 C EXCEPT DETAIL 0050 C INDEX READE CUSTMAST 0070 C ENDDO .....OFormat++++DAddn01n02n03Except++++SpbSpaSkbSka 0080 OQPRINT E DETAIL 1 .....O..............n01n02n03Field+++++++++YB?End++PConstant/Editword+++++++++++ 0090 O CUST# Z 10 0100 O CSTNAM +2 0110 OQPRINT E DETAIL 1 0120 O BALDUE 3 10
In Example 5.59, the first record matching the key value in the field INDEX is retrieved from the customer orders file CUSTINV. Then, the balance-due field BALDUE is zeroed, giving the customer a zero-balance-due account. To update only that field, an exception label is used on line 70 to update the customer record with a zero balance.
Example 5.59: Exception output to an externally described database file format.
.....FFileName++IFEASFRlen+LKeylnKFDevice+.Functions++++++++++++++++++++++++++++ 0010 FCustInv IF E K DISK .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0020 C INDEX CHAIN CUSTINV 0040 C DOW %Found 0050 * Zero out the existing balance due field. 0060 C Eval BalDue = 0 0070 C EXCEPT NewBalDue 0080 C INDEX READE CustRec 0100 C EndDo .....OFormat++++DAddn01n02n03Except++++SpbSpaSkbSka 0110 OCustRec E NewBalDue 0120 O BALDUE
In Example 5.60, the record matching the key value in the field INDEX is retrieved from the customer master file CUSTMAST. Because CUSTMAST is opened for update, data management locks the record. To release this record lock, the EXCEPT operation can be used, although the UNLOCK operation is more intuitive.
Example 5.60: Exception output to release a locked record.
.....FFileName++IFEASFRlen+LKeylnKFDevice+.Functions++++++++++++++++++++++++++++ 0010 FCustMast UF E K DISK .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0020 C INDEX CHAIN CUSTMAST 0040 C IF %Found 0050 C EXCEPT Release 0060 C ENDIF 0070 C EXFMT DISPLAY .....OFormat++++DAddn01n02n03Except++++SpbSpaSkbSka 0080 OCustRect E RELEASE
To release the record lock, an EXCEPT operation is performed on line 50. The EXCEPT label RELEASE is specified. RELEASE is an empty output format (that is, it contains no output fields). This is the key to this technique. By specifying no output fields, the system performs an "empty" output operation and releases the record lock. Note that the exception label name "RELEASE" is used for easy identification of the release function.
This technique works with program-defined and externally described database files that are open for UPDATE. It's functionally equivalent to the UNLOCK operation. The UNLOCK operation is better suited for releasing records because it was designed for this purpose.
Warning | When an EXCEPT name is used on a file that has been opened for OUTPUT only and no output fields have been specified for the exception output—as described in Example 5.57—a record containing blank and zero fields (depending on the field attribute) is written to the database file. |
The EXFMT operation performs a WRITE followed by a READ to the same WORKSTN file record format. The EXFMT operation is a combined and optimized form of WRITE followed by READ.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
EXFMT (E) | workstn format | [error] |
See also READ and WRITE
Factor 2 must contain the name of a WORKSTN file record format. Resulting indicator 2 is optional and, if specified, it signals when a workstation error has occurred. EXFMT, however, cannot be used for workstation timeout. See the subheading READ (Read from a File) for information on workstation timeout.
In Example 5.61, the database fields in the file CUSTMAST are the same as those used in the workstation file format CUSTFMT. Consequently, no MOVE operations need to be performed to get the database information into the workstation record format.
Example 5.61: Retrieving and displaying a data file record.
.....FFileName++IFEASFRlen+LKeylnKFDevice+.Functions++++++++++++++++++++++++++++ 0010 FCustMast IF E K DISK 0020 FCUSTINQ CF E WORKSTN .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0030 C INDEX CHAIN CustRec * If the customer is not found, add a new customer 0040 C IF NOT %Found 0050 C EXFMT NEWCUST 0060 C ELSE * If the customer is found, display the existing record 0070 C EXFMT UPDCUST 0080 C ENDIF
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | N/A | |
73 – 74 | 2 | [ error ] | An error occurred during the operation. |
75 – 76 | 3 | N/A |
The EXSR operation calls an internal subroutine (known as a procedure in some languages). After the subroutine has completed, or the LEAVESR operation is performed, control returns to the statement following the EXSR operation.
If a GOTO operation within the subroutine caused branching outside of the domain of the subroutine, or an exception/error handling subroutine caused branching to a different part of the program cycle, control doesn't return to the statement following the EXSR operation.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
EXSR | Subroutine |
See also BEGSR, ENDSR, CASxx, and LEAVESR
Factor 2 can contain a user-written subroutine name, the name of the exception/error subroutine (*PSSR), or the initialization subroutine (*INZSR). It also can contain a file exception/error subroutine (INFSR) name. The subroutine name can be up to 14 characters in length for fixed format operations, and any length for free-format operations.
In Example 5.62, the database file ITEMMAST (item master) is accessed on line 10. The subroutine PROFIT is then performed on line 50 to compute the gross profit of the item retrieved by the CHAIN operation on line 10. The subroutine PROFIT begins on line 80 with the BEGSR operation. The gross profit is calculated. The subroutine ends with the ENDSR operation (line 120). Control returns to line 60.
Example 5.62: Performing a subroutine to compute profit.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C INDEX CHAIN ITEMMAST 54 0030 C IF %FOUND 0040 C MOVEL 'FOUND' MSG 0050 C EXSR PROFIT 0060 C ENDIF 0070 C MOVE *ON *INLR 0080 CSR PROFIT BEGSR 0090 C PRICE MULT QTYORD EXTEND 0100 C ITMCST MULT QTYORD EXTCST 0110 C EXTPRC SUB EXTCST GRSPFT 0120 CSR ENDSR
Each subroutine must be outside the domain of other subroutines. In other words, a subroutine cannot contain another subroutine—although a subroutine can call another subroutine.
Any RPG operation may be specified with a subroutine, including the EXSR and CASxx operations. Therefore, a subroutine can call another subroutine. However, recursive calls to a subroutine can cause the program to loop.
Control level-break indicators are not allowed. The constant SR can be specified in the control level-break indicator columns 7 and 8 to indicate that this is a subroutine. Most programs contain the SR only on the BEGSR and ENDSR statements. This visually identifies the beginning and end of the subroutine.
The GOTO operation can be used to branch within the subroutine (such as to a LABEL on a TAG or ENDSR statement). It also can branch to a location outside of the subroutine's domain, within the mainline calculations. The GOTO operation cannot, however, branch to a label contained within another subroutine. Figure 5.3 shows a diagram of the mainline and subroutines.
Figure 5.3: Diagram of mainline flow with EXSR.
The EXTRCT operation code can be used to extract a part of a date, time, or timestamp value. The extracted date component is copied into the result field.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
EXTRCT(E) | Date : duration | numeric variable | [error] |
See also %SUBDT, ADDDUR, SUBDUR, and TEST
The date, time, or timestamp value is specified in factor 2 and is followed immediately by a duration code. The duration code identifies which part is to be extracted. Valid duration codes are *YEARS, *MONTHS, *DAYS, *HOURS, *MINUTES, *SECONDS, *MSECONDS, and the shorthand forms *Y, *M, *D, *H, *MN, S, *MS. For a description of each duration code, see Table 5.6.
The result field can be either a character or a numeric variable. If the result field is a character, the extracted value is copied left justified and zero suppressed; unneeded positions in the character field are filled with blanks. If the result field is numeric, the extracted value replaces the value of the result field.
In Example 5.63, the EXTRCT operation on line 4 extracts the day of the month from the DUEDATE field. Because DUEDATE has been initialized to February 17, 1996, the day of the month is 17. On line 6, a similar EXTRCT operation also retrieves 17. Note that, regardless of the date format of factor 2, the day of the month is retrieved.
Example 5.63: Using EXTRCT to retrieve the day of the month.
.....DName+++++++++++EUDSFrom+++To/Len+TDc.Functions++++++++++++++++++++++++++++ 0001 D DueDate S D INZ(D'1996-02-17') 0002 D JuliDate S D DatFmt(*JUL) INZ(D'1996-02-17') .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0003 * Extract the day from the date. The field THEDAY receives the value 17. 0004 C Extrct DueDate:*Days theDay 2 0 0005 * Extract the day from the date. Field JULIDAY also receives the value 17. 0006 C Extrct JuliDate:*DaysJuliDay 2 0
The FEOD operation positions a file's "cursor" to the end-of-file, releases any record locks that exist, and force any buffered data to be written to the device. For example, the last few lines of a printed report are normally not sent to the printer until after the print file is closed. The FEOD operation forces those last few printed lines to the printer device (output queue) without requiring the file to be closed.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
FEOD(E) | File name | [error] |
See also CLOSE, SETLL, and OPEN
Factor 2 must contain the name of the file for the FEOD operation. If the FEOD fails, resulting indicator 2 is set on.
The FEOD operation differs from the CLOSE operation in that acquired device files (see the subheading ACQ [Acquire]) are not released (i.e., disconnected) from the program. The file must be repositioned before any subsequent read operation can access the file's data.
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | N/A | |
73 – 74 | 2 | [ error ] | An error occurred during the operation. |
75 – 76 | 3 | N/A |
In Example 5.64, the file CUSTMAST is forced to the end of data. Any CUSTMAST records locked by the program are released. Resulting indicator 2 (indicator 56 in this example) is set on if the FEOD fails.
Example 5.64: Forcing the end of data of a data file.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C FEOD CUSTMAST 56
The FOR operation begins an iterative group of operations. An index, increment, and limit are specified to control the iterative process.
Factor 1 | OpCode | Extended Factor 2 |
---|---|---|
FOR | Index [ = start] [TO | DOWNTO limit ] [BY increment] |
See also LEAVE, ITER, DO, and ENDFOR
The FOR operation begins a FOR/ENDFOR loop. The operations enclosed within the FOR and ENDFOR operations are performed a number of times. The number of times the operations are performed is controlled by the limit. Each iteration through the FOR/ENDFOR loop increments or decrements the index by increment value until the limit is breached.
When the FOR operation is encountered, the start value is assigned to the index variable. The index value is compared with the limit. When the TO keyword is specified, and if the index is greater than the limit, control is passed to the statement following the ENDFOR operation. When the DOWNTO keyword is specified, and if the index is less than the limit, control is passed to the statement following the ENDFOR operation. Otherwise, the operations enclosed within the FOR/ENDFOR operations are performed.
The FOR operation supports three parameters. Index is a type of loop counter variable. It can be assigned an initial start value when the FOR/ENDFOR loop is started. Limit is the threshold for the loop. It represents the minimum or maximum value allowed for the index variable. Increment is the value that is added to or subtracted from the index variable after each pass through the FOR/ENDFOR loop.
The TO keyword indicates that the index is incremented on each pass; whereas, the DOWNTO keyword indicates that the index is decremented on each pass. The BY keyword identifies the amount added to or subtracted from the index on each pass through the FOR/ENDFOR loop. Normally, the BY value is a positive value.
Figure 5.4 shows the full syntax of the FOR/ENDFOR operations. Conditioning indicators on the FOR operation are tested when the FOR operation is initially performed. They are not tested as the FOR/ENDFOR loop is iterating. Conditioning indicators control whether or not the FOR/ENDFOR is performed at all, but not whether the iterations themselves are performed. Conditioning indicators are tested each time the ENDFOR operation is encountered.
.....CSRn01..............OpCode(ex)Extended-factor2+++++++++++++++++++++++++++++ C FOR index [= start value ] C TO [DOWNTO] limit ] C [ BY increment ] C C endfor
Example 5.65 shows an example of the operation codes. Upon normal completion of the FOR/ENDFOR loop, the value of the index is one more than the limit for the TO keyword or one less than the limit for the DOWNTO keyword. This is always true unless the LEAVE operation is used to prematurely exit the FOR/ENDFOR loop.
Example 5.65: An example of the FOR/ENDFOR operation.
.....CSRn01..............OpCode(ex)Extended-factor2+++++++++++++++++++++++++++++ .....CSRN01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHILOEQ.... ** Do the routine 50 times, adding 1 to I each time. C FOR i=1 to 50 C add i Counter C endfor ** NOTE: X = 51 after this statement. ** Start at 10, do until X is 1. .....CSRn01..............OpCode(ex)Extended-factor2+++++++++++++++++++++++++++++ C for X = 10 DownTo 1 C if %Subst(Name : X : 1) = *BLANK C eval %subst(Name : X : 1) = '_' C else C Leave C endIF C endFOR ** NOTE: X=0 after this statement.
The FORCE operation controls the sequence in which records are read by the RPG cycle. Only primary and secondary files are read by the RPG cycle. The FORCE operation is valid within detail-time calculations only.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
FORCE | File name |
See also NEXT.
Factor 2 must contain the name of the primary or secondary file that is read on the next RPG cycle. If the file specified in factor 2 is at end of file, the FORCE operation is ignored and the RPG cycle selects the next file to be read.
When more than one FORCE operation occurs during the same RPG cycle, the final FORCE operation has priority over all other FORCE operations. In Example 5.66, the file ORDERS is read on the next input cycle, bypassing the normal primary/secondary selection priority.
Example 5.66: Forcing input from a secondary file.
.....FFileName++IFEASFRlen+LKeylnKFDevice+.Functions++++++++++++++++++++++++++++ 0010 FCustMast IPE E DISK 0020 FITEMMAST ISE E DISK 0030 FORDERS ISE E DISK .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0040 C IF Count = 0 0050 C ADD 1 COUNT 3 0 0060 C FORCE ORDERS 0070 C ENDIF * Additional code would go here...
Extender | Description |
---|---|
M | If expressions are specified for any of the arguments of the operation, the maximum-digits format for intermediate results is used. |
R | If expressions are specified for any of the arguments of the operation, the result value's decimal positions are used for intermediate result values. This extender is useful only when the %DEC built-in function is specified for the argument. |
The GOTO operation allows branching to different areas of the program. A label, called a tag in RPG, is the target of the GOTO operation. Labels are declared with the TAG and ENDSR operation.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
GOTO | label |
See also TAG, CABxx, IF, SELECT, WHEN, DO, DOW, DOU, LEAVESR, and ENDSR
The GOTO operation performs a permanent branch to the label specified in factor 2. Control never returns to the GOTO statement. For the most part, the GOTO can branch anywhere in the program from anywhere in the program. However, a subroutine cannot be branched into from outside of that subroutine. Also, detail-time calculations cannot be the target of a branch operation from within total-time calculations. In Example 5.67, the GOTO operation on line 500 performs an unconditional branch to the label READ on line 10.
Example 5.67: GOTO controlled looping.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C READ TAG 0020 C READ CUSTMAST LR 0030 C *INLR CABEQ *ON ENDPGM C*... user code ......... 0500 C GOTO READ C*... more user code..... 0900 C ENDPGM TAG
The IFxx operation compares the value in factor 1 to the value in factor 2. If the comparison is true, the group of calculations between the IFxx and its associated ENDIF operation (or ELSE operation) are performed. Conditioning indicators are valid for the IFxx operation. However, conditioning indicators cannot be used on ANDxx and ORxx operations.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
Compare value 1 | IFxx | compare value 2 | ||||
IF (M R) | conditional expression |
See also ELSEIF, SELECT, WHEN, ELSE, DOWxx, DOUxx, CASxx, and FOR
The IFxx operation requires a relationship test xx, where xx may be any one of the Boolean operators (EQ, GE, GT, LE, LT, and NE). See Table 5.9 for details. Factor 1 is compared to factor 2 based on the xx operator. Factor 1 and factor 2 must be similar data types. For the secondary form of IF, the extended factor 2 must contain a conditional expression. The IF operation supports the M and R operation extenders.
If a conditioning indicator is used, it is tested before the IFxx operation. When the indicator condition is false, the IFxx operation is not performed. Control passes to the associated ENDIF operation for this IFxx operation even if an ELSE operation is specified. When the indicator condition is true, the IFxx operation, along with any ANDxx and ORxx conditioning, is performed.
The IFxx operation can be used to conditionally perform a group of operations by testing a range, a list of values, a single value, or a compound set of values. See Examples 5.68 through 5.72 for details.
Example 5.68: Conditioning a group of operations on a single comparison.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C INDEX CHAIN CUSTMAST 0020 C IF %FOUND 0030 C EXFMT DISPLAY 0040 C ENDIF
The IFxx test can be extended with the ANDxx or ORxx operations. The ANDxx operation allows compound conditions to be tested; ORxx allows additional, but separate, conditions to be tested. The ANDxx and ORxx operations cannot be used in conjunction with the IF form of this operation.
In Example 5.68, the CHAIN operation on line 10 accesses the database file CUSTMAST. If a record is found, resulting indicator 1 (if specified) is set off. The IF operation on line 20 tests the %FOUND status and performs an EXFMT operation if the condition is true.
In Example 5.69, the EXFMT operation prompts the user. The format DISPLAY is written to and read from the display device. After the format is read, the compound IFxx operation on lines 20 to 40 compares the field OPTION to 'A1', 'B1', or 'C1'. If the field OPTION is equal to any of these values, the MOVE operation on line 50 is performed.
Example 5.69: Using the IFxx and the ORxx to test for a list of values.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C EXFMT DISPLAY 0020 C OPTION IFEQ 'A1' 0030 C OPTION OREQ 'B1' 0040 C OPTION OREQ 'C1' 0050 C MOVE 'OK' STATUS 0060 C ENDIF
In Example 5.70, the workstation format DISPLAY is sent to and read from the display through the EXFMT operation. When the workstation file is read, the IF operation on line 20 compares the field OPTION to be between 1 and 9. If the field OPTION satisfies this condition, the EVAL operation on line 30 is performed.
Example 5.70: Using the IF and the AND to test for a range.
.....CSRn01..............OpCode(ex)Extended-factor2+++++++++++++++++++++++++++++ 0010 C EXFMT DISPLAY 0020 C IF Option > = 1 and Option <= 9 0030 C EVAL Status = 'OK' 0040 C ENDIF
To rewrite Example 5.71 with the alternate form of IF, the code in Example 5.72 can be specified.
Example 5.71: Using the compound form of IFxx to control entry into a subroutine.
.....CSRn01Factor1+++++++<—OpCode(ex)—>Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C EXFMT DISPLAY 0020 C OPTION IFEQ '9' 0030 C FILE ANDNE *BLANKS 0040 C LIBR ANDNE *BLANKS 0050 C FILE ANDNE '*DELETED' 0060 C USERID | IFEQ 'SECURITY' 0070 C USERID | OREQ 'MANAGER' 0080 C AUT | ANDEQ 'DELRGHT' 0090 C | | EXSR DeleteUser 0100 C | ENDIF 0110 C ENDIF
Example 5.72: Using alternate IF to control entry into a subroutine.
.....CSRn01..............OpCode(ex)Extended-factor2+++++++++++++++++++++++++++++ 0010 C EXFMT DISPLAY 0020 C If Option = 9 and (FileName *Blanks 0030 C and LibName *Blanks and FileName '*DELETED') 0050 C If (userID = 'SECURITY' or userID='MANAGER') 0060 C and authority = 'DELRIGHTS' 0070 C USERID CHAIN UserFile 0080 C If %FOUND 0090 C EXSR DeleteUser 0100 C EndIf 0110 C EndIf 0120 C EndIf
In Example 5.72, the workstation format DISPLAY is written to and read from the workstation using the EXFMT operation. When the workstation file is read, the IF operation on lines 20 and 30 is tested. When the condition is met, the nested IF operation that begins on line 50 is tested. If that condition is met, the user's record is retrieved. If the retrieval is successful, the EXSR operation (line 90) is performed.
Figure 5.5 shows diagrams of the two forms of IF-THEN-ELSE. The left-most flowchart in Figure 5.5 illustrates a traditional IF-THEN operation. If the test is true, the process is performed; if the test is false, the process is bypassed. The right-most flowchart illustrates the IF-THEN-ELSE operation. If the test is true, the process is performed; if the test is false, an alternate process is performed.
Figure 5.5: The two forms of IF-THEN-ELSE.
The IN operation retrieves one or all of the data areas defined in the program. Optionally, it also allows the data area to be locked. When a data area is locked, no other program can access that data area until an UNLOCK (unlock data area) operation is performed.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
[*LOCK] | IN (E) | data area variable | [error] | |||
[*LOCK] | IN (E) | *DTAARA | [error] |
See also OUT, *DTAARA DEFINE, and DTAARA keywords
Factor 1 can contain the constant *LOCK, which causes the data area specified in factor 2 to be locked. Factor 1 can be blank, causing the data area specified in factor 2 to be retrieved without being locked. If factor 1 is blank for an IN operation, the previous IN operation dictates the lock/no-lock status. The first IN operation of a succession of IN operations for a specific data area controls the object lock placed on the data area.
Factor 2 can contain a data area name or the constant *DTAARA. When a data area name is specified, the data area is retrieved and optionally locked by the program. When *DTAARA is specified, all data areas declared to the program are retrieved.
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | N/A | |
73 – 74 | 2 | [ error ] | An error occurred during the operation. |
75 – 76 | 3 | N/A |
In Example 5.73, the data area ACCTCTL is defined to the program on line 10. The field CTLNBR is the field that is assigned to the data area. Line 20 retrieves the data area ACCTCTL into the field CTLNBR. The data area is locked.
Example 5.73: Defining then retrieving a data area.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C *DTAARA DEFINE ACCTCTL CTLNBR 0020 C *LOCK IN CTLNBR
The ITER operation can be used within a DO, DOWxx, and DOUxx to cause the iteration of the loop being processed. Iteration is accomplished by transferring control to the logical "top" of the DO loop.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
ITER |
See also DO, DOW, DOU, and LEAVE
The ITER operation is used within a DO or FOR loop, typically in conjunction with the LEAVE operation, to enhance control of the loop. To control the ITER operation, conditioning indicators or more properly, an IF operation can be used.
In Example 5.74, the I (index) field is initialized to the length of the ITEMDS variable (a data structure name, not shown). Then, each character of ITEMDS is compared to a blank. Any position of ITEMDS that is blank is bypassed. The ITER operation on lines 3, 4, 5 is used to bypass the blanks in the field. All other characters are processed by the remaining operations of the FOR group.
Example 5.74: Using ITER to bypass unnecessary code.
.....CSRn01Factor1+++++++<—OpCode(ex)—>Factor2+++++++Result++++++++Len++DcHiLoEq 0002 C FOR Count = 1 TO %len(ITEMDS) BY 1 0003 C | If %SUBST(ITEMDS : Count:1) = *Blank 0004 C | | ITER 0005 C | EndIf C | . C* additional code can go here. C | . C ENDFOR
The KFLD operation is a declarative operation that defines an element of a key list. Multiple successive KFLD operations are used to define a key list, which is used in accessing keyed database files. The KFLD operation may appear anywhere in the calculation specifications, but it must follow a KLIST operation (see the subheading KLIST [Key List]) or another KFLD operation code. Conditioning indicators are not valid for this operation.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
KFLD | key field |
See also %KDS, KLIST, CHAIN, SETLL, and DELETE
The result field must contain the name of the field that defines the key field. This field is used with other key fields (if specified) to form a key list (KLIST). The key list is used to access a database file.
One or more KFLD operation codes are needed to define a key list. The attributes of each key field must match those of the database file that is accessed by the key list. The number of KFLD operations that is permitted per key list depends on the index (i.e., access path) of the database file that is being accessed. The key list may contain as many KFLD operation codes as there are key fields defined for the database file's index. If fewer KFLD operation codes appear on the key list than are actually contained in the database file's index, then that subset is used to access the file. See Example 5.75.
Example 5.75: Using a key field for access by warehouse and part number.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C PART KLIST 0020 C KFLD WHSNBR 0030 C KFLD PRTNBR 0040 C PART CHAIN PARTMAST 54
The KLIST operation defines a composite key or key list made up of one or more KFLD operation codes. The key list is used to access a database file by an index. Conditioning indicators are not valid for this operation.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
key list name | KLIST |
See also KFLD, %KDS, CHAIN, SETLL, and DELETE
Factor 1 must contain the name of the key list that is being defined. The KLIST operation must be followed by one or more KFLD operation (see the preceding subheading). The KLIST operation defines the key list name; the KFLD operations define the key fields. For externally described files only, the key list name can appear in factor 1 of the CHAIN, DELETE, READE, READPE, SETGT, and SETLL operation codes.
In Example 5.76, line 10 defines the key list WHSE consisting of the field WHSNBR. Line 30 defines the key list PART consisting of the fields WHSNBR and PRTNBR.
Example 5.76: Accessing a part master file via a key list.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C WHSE KLIST 0020 C KFLD WHSNBR 0030 C PART KLIST 0040 C KFLD WHSNBR 0050 C KFLD PRTNBR 0060 C PART CHAIN PARTMAST 54 0070 C WHSE CHAIN PARTMAST 54
The LEAVE operation can be used to exit a DO, DOWxx, and DOUxx group. The LEAVE operation transfers control to the statement following the DO group's ENDDO operation.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
LEAVE |
See also ITER, DO, DOW, DOU, and FOR
The LEAVE operation is used within a DO loop, to enhance control of the DO loop. To control performing the LEAVE operation, conditioning indicators or the IF operation can be used.
In Example 5.77, the FOR group fills a subfile with up to 20 orders for a given customer. If the end of orders indicator is detected (line 4), the LEAVE operation (line 5) is performed and control is transferred to the statement following the ENDDO operation. In other words, control is transferred to line 9.
Example 5.77: Using LEAVE to exit a DOUEQ loop.
.....CSRn01Factor1+++++++<—OpCode(ex)—>Factor2+++++++Result++++++++Len++DcHiLoEq 0001 C Eval CustNo = 911 0002 C FOR SFLRecNo = 1 to 20 0003 C CustNo | ReadE ORDERS 0004 C | IF NOT %FOUND 0005 C | | LEAVE 0006 C | ENDIF 0007 C | WRITE SubFile 0008 C ENDFOR 0009 C EXFMT OrdPanel
The LEAVESR operation can be used to immediately exit a subroutine. The LEAVESR operation transfers control to the ENDSR operation for the subroutine in which the LEAVESR operation is performed. This causes control to return to the caller of the subroutine.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
LEAVESR |
See also ITER, DO, DOW, DOU, and FOR
The LEAVESR operation can be used only within the BEGSR and ENDSR operations (shown in Example 5.78). Use the LEAVESR operation within a conditional expression to cause a branch to the end of the subroutine. Unlike the GOTO operation, the ENDSR operation doesn't need to contain a label in factor 1 in order for the LEAVESR operation to function properly.
Example 5.78: Using LEAVESR to exit a subroutine.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 CSR AddMarkUp BegSR 0020 C If Cost <= 0 0030 C LeaveSR 0040 C endIf 0050 C Cost Div 10 MarkUp 0060 C If MarkUp < 1.00 0070 C LeaveSR 0080 C endIf 0090 C Eval Price = cost + Markup 0100 CSR endMarkUp endSR
The LOOKUP operation searches an array or table for a search argument. At least one resulting indictor is required with this operation.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
search argument | LOOKUP | array[(search index)] | [HI] | [LO] | [EQ] | |
search argument | LOOKUP | table to search | [alternate table] | [HI] | [LO] | [EQ] |
See also %LOOKUPXX, %TLOOKUPXX, SORTA, SCAN, and CHAIN.
Factor 1 must contain a search argument. The search argument must be the same attribute as the elements of the array or table. When a lookup is performed on an array, factor 2 can contain an optional starting index. If a starting index is specified, the lookup begins with that array element. If the starting index is specified as a numeric field, when the search is successful, the index field is set to the element where the search was satisfied.
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | [ HI ] | Causes LOOKUP to search for the first element greater than factor 1. |
73 – 74 | 2 | [ LO ] | Causes LOOKUP to search for the first element less than factor 1. |
75 – 76 | 3 | [ EQ ] | Causes LOOKUP to search for the first element equal to factor 1. Sets the %EQUAL built-in function to *ON or *OFF. |
When a lookup is performed on a table, the result field can contain an alternate table name. If the lookup operation is successful, the table in the result field is set to the corresponding element where the search argument is located.
Resulting indicators control the type of search that is performed by LOOKUP. At least one, and no more than two, resulting indicators can be specified for the LOOKUP operation.
Resulting indicators 1 and 3 can both be specified to cause the LOOKUP to search for the first element that is greater than or equal to factor 1. Resulting indicators 2 and 3 can both be specified to cause the LOOKUP to search for the first element that is less than or equal to factor 1. When resulting indicator 3 is specified, the %EQUAL built-in function is set using the same conditions as resulting indicator 3.
The LOOKUP operation is widely used in RPG. Although more flexible string-handling operation codes have been added to the language in recent years, LOOKUP still proves valuable. Example 5.79 shows a typical use of the LOOKUP operation.
Example 5.79: Searching an array for a valid code.
.....DName+++++++++++EUDS.......Length+TDc.Functions++++++++++++++++++++++++++++ 0010 D ValidCode S 1 DIM(4) PerRcd(4) CTDATA 0020 D CodeText S 20 DIM(4) PerRcd(1) CTDATA .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0030 C Eval Inx = 1 0040 C Code LOOKUP ValidCode(Inx) 58 0050 C If *IN58 0060 C MOVEL CodeText(Inx) MsgLine 0070 C ENDIF **CTDATA VALIDCODE ABCD **CTDATA CODETEXT Advanced lesson Beginner lesson Change answers Delete test results
In Example 5.79, line 10 defines the four-element array named VALIDCODE. Line 20 defines the four-element array named CODETEXT. The array VALIDCODE is a valid code array, and CODETEXT is the code's text description. A description of each code stored in the VALIDCODE array is located in the corresponding element of the CODETEXT array.
When the LOOKUP operation on line 40 is successful, the variable IDX is set to the index of the located value. By using that variable as the array element of the CODETEXT array, the code's description is copied to the MSGLINE field.
The MONITOR operation is used perform error handling for a group of operation codes. The operation codes between the MONITOR and the first ON-ERROR operation are monitored for error conditions.
Factor 1 | Op Code | Factor 2 | Result Field | Resulting Indicators |
---|---|---|---|---|
MONITOR |
See also ON-ERROR, ENDMON, %ERROR, %STATUS
The MONITOR operation creates a boundary around one or more regular operation codes. When an error condition is signaled by any of those operations, the ON-ERROR operations that are also part of the MONITOR group are tested. If the error is trapped by an ON-ERROR operation, then the corresponding operations below the ON-ERROR operation are performed until another ON-ERROR operation or an ENDMON operation is detected.
If the operations within the ON-ERROR statements run without error, then control continue by branching to the ENDMON statement for the MONITOR group.
In Example 5.80, the MONITOR statement (line 1) and the ENDMON statement (line 11) create a monitor group. This monitor group consists of the regular operation codes on lines 2 through 6, and the ON-ERROR error-trapping statements on lines 7 through 10.
Example 5.80: Monitor Group.
.....CSRn01..............OpCode(ex)Extended-factor2++++++++++++++++++++++ 0001 C Monitor 0002 C Eval X = A + B / C 0003 C CustNo Chain CustMast 0004 C If %Found 0005 C Eval BalDue = X 0006 C Endif 0007 C On-Error 0102 0008 C 'Divisor err' Dsply 0009 C On-Error 1218 : 1222 0010 C 'Locked Rec' Dsply 0011 C EndMon
The operation codes on lines 2 through 6 are performed. If any error occurs during those operations, the list of ON-ERROR operation codes enclosed in the monitor group is tested. If an error matching factor 2 of one of the ON-ERROR statements is detected, the statements following that On-Error statement are performed up to the next On-Error statement or the ENDMON statement.
Monitor groups may monitor for any valid program status error or file status error. In addition, generic "catch-all" figurative constants may be used to trap messages of any given type. These figurative constants that may be tested on the On-Error operation are as follows:
Figureative Constant | Description |
---|---|
*PROGRAM | All program status error codes. The range tested is 100 to 999. |
*FILE | All file status error codes. The range is tested is 1000 to 9999. |
*ALL | Both program status and file status errors. The range tested is 100 to 9999. |
The four MxxZO operations copy the specified zone of either the left-most or right-most character of factor 2 to the left-most or right-most character of the result field. Except when the program is processing data from a system other than the host computer, this operation is rarely used.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
MxxZO | source | target |
See also BITON and BITOFF
The four Move Zone to Zone operations are as follows:
The MHHZO (Move High to High Zone) operation copies the zone portion (i.e., bits 0, 1, 2, and 3) of the left-most character in factor 2 to the zone portion of the left-most character of the result field. Factor 2 must contain a character field. The result field must contain a character field.
The MHLZO (Move High to Low Zone) operation copies the zone portion (i.e., bits 0, 1, 2, and 3) of the left-most character in factor 2 to the zone portion of the right-most character of the result field. Factor 2 must contain a character field. The result field can contain either a character or numeric field.
The MLHZO (Move Low to High Zone) operation copies the zone portion (i.e., bits 0, 1, 2, and 3) of the right-most character in factor 2 to the zone portion of the left-most character of the result field. Factor 2 can contain either a character or numeric field. The result field must contain a numeric field.
The MLLZO (Move Low to Low Zone) operation copies the zone portion (i.e., bits 0, 1, 2, and 3) of the right-most character in factor 2 to the zone portion of the right-most character of the result field. Factor 2 can contain either a character or numeric field. The result field also can contain a character or numeric field.
The MOVE operation copies the data from factor 2 right-justified to the result field. The MOVEL operation copies the data from factor 2 left justified to the result field. For the remainder of this operation description, the MOVE operation is used. However, unless otherwise noted, everything listed here applies to both the MOVE and MOVEL operations. The only difference is that MOVEL moves data left justified whereas MOVE moves data right justified.
The MOVE operation copies data and automatically performs data-type conversion when necessary. Specific operations performed are character to numeric, numeric to character, and date and time to non-date and time.
Resulting indicators are valid only when moving data to a numeric or character field and indicate whether the result field is positive, negative, zero, or blank.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
[date format][sep] | MOVE(P) | source | target | [+] | [-] | [0 or b] |
[date format][sep] | MOVEL(P) | source | target | [+] | [-] | [0 or b] |
See also EVAL, EVALR, SUBST, MOVEL, CLEAR, and CAT
Factor 1 is optional and is supported only when factor 2 or the result field (but not both) contains a date or time value. The format of the non-date or time value is specified in factor 1. If factor 1 is omitted for MOVE operations involving date and timedata types, the date or time format specified for the DATFMT keyword on header specification is used. Factor 2 can be any data type—literal value or variable. The result field variable can be any data type. When the result field is an array, factor 2 is moved into each element of the array. Factor 2 and the result field cannot be overlapping data-structure subfields.
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | [ + ] | The numeric result field is greater than zero. |
73 – 74 | 2 | [ – ] | The numeric result field is less than zero. |
75 – 76 | 3 | [ 0 or ] | The numeric result field is equal to zero or the character result field is blank. |
Extender | Description |
---|---|
P | PAD – Causes the result field's value to be cleared before the MOVE or MOVEL operation is performed. This has the same effect as performing the CLEAR operation immediately before performing the MOVE or MOVEL operation. |
When the length of factor 2 is less than the length of the result field, the number of characters replaced in the result field is equal to the length of factor 2. Unless the P (pad) operation extender is specified, other positions within the result field are not affected.
When the length of factor 2 is greater than or equal to the length of the result field, a complete replacement of the result field with factor 2 is performed. Any additional data in factor 2 is not moved.
The MOVE operation traditionally has been used to clear the contents of the character-result field by moving *BLANKS to the result field. The CLEAR operation, however, accomplishes the same task and is data-type independent. Therefore, character, numeric, date, and time fields as well as data structures, record formats, arrays, and array elements can be cleared with a single CLEAR operation.
In addition to the standard date and time formats (see Tables 5.4 and 5.5), several date format codes that are unique to MOVE and MOVEL are supported. This allows simple conversion between date and non-date fields. Table 5.18 lists the set of date format codes that are supported by the MOVE and MOVEL operations.
Date/Time Format Code | Description | Format |
---|---|---|
*CDMY | CL Date Century-digit, Day, Month, Year | CDDMMYY |
*CMDY | CL Date Century-digit, Month, Day, Year | CMMDDYY |
*CYMD | CL Date Century-digit, Year, Month, Day | CYYMMDD |
*JOBRUN | Runtime job DATFMT attribute | Runtime job DATFMT |
*JUL | Julian (2-digit year) | YY/DDD |
*LONGJUL | Long Julian (4-digit year). | YYYY/DDD |
*MDY | Month, Day, Year (2-digit year) | MM/DD/YY |
*DMY | Day, Month, Year (2-digit year) | DD/MM/YY |
*YMD | Year, Month, Day (2-digit year) | YY/MM/DD |
*ISO | International Standards Organization Standard | YYYY-MM-DD |
*USA | United States Standard | MM/DD/YYYY |
*EUR | European Standard | DD.MM.YYYY |
*JIS | Japanese International Standard | YYYY-MM-DD |
The *CYMD, *CMDY, and *CDMY date format codes support a one-position century digit in the first position in the date. This digit can be 0 through 9. The value 0 equates to 1900, the value 1 equates to 2000, the value 2 equates to 2100, and so on. By adding the year to these values, the true four-digit year is calculated.
Examples 5.81 through 5.83 illustrate the MOVE and MOVEL operations. Figure 5.6 shows the type and lengths that are assumed for each field name.
.....DName+++++++++++EUDS.......Length+TDc.Functions++++++++++++++++++++++++++++ D ARR S 7P 0 DIM(5) D ErrMsg S 30A INZ('The customer number is 1234567') D MsgLine S 10A D MsgCon S 4A D CstNbr S 7P 0
After line 10 in Example 5.81 is performed, the field MSGLIN contains the following:
MSGLINE = ' is 1234567'
Example 5.81: Various MOVE operations.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C MOVE ERRMSG MsgLine 0020 C MOVE ERRMSG CSTNBR 0030 C MOVE CSTNBR ARR
After line 20, the field CSTNBR contains the following:
CSTNBR = 1234567
After line 30, each element in the ARR array contains the value 1234567. The value of CSTNBR is moved to each array element as though independent MOVE operations to each ARR(x) were performed (with x being the array index).
ARR = 1234567,1234567,1234567,1234567,1234567
In Example 5.82, after the MOVE operation is performed, the result field contains the following:
MSGCON = '4567'
Example 5.82: Moving with length of factor 2 greater than the result field.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C MOVE MsgLine MsgCon
In Example 5.83, after the MOVE operation on line 20 is performed, the ERRMSG result field contains the following:
*... ... 1 ... ... 2 ... ... 3 ERRMSG = 'The customer number is 123XXXX'
Example 5.83: Moving with length of factor 2 shorter than the result field.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C MOVE 'XXXX' MSGCON 0020 C MOVE MSGCON ERRMSG
The MOVEA operation is a string manipulation operation code. It copies the contents of factor 2 and is left justified to the result field. Factor 2 or the result field or both must be an array.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
MOVEA(P) | source | target | [+] | [-] | [0 or b] |
See also MOVEL, MOVE, SUBST, LOOKUP, and SORTA
Factor 2 can contain a field, data structure, data structure subfield, array, array element, constant, or named constant. The result field can contain a field, data structure, data structure subfield, array, or array subscript. However, it cannot contain the same array name as factor 2.
An array or array subscript must be specified in factor 2 or the result field. If an array subscript is specified, the move operation begins with the specified array element. For example, if the array subscript ARR(3) is used with the MOVEA operation, the move begins with the third element of the ARR array.
The MOVEA operation operates with either character or zoned numeric arrays. It does not operate on arrays where elements are defined as binary or packed numeric. The MOVEA operation operates on a byte-by-byte basis. It aligns factor 2 and the result field based on any array index, and then performs the equivalent of the MOVEL (move left) operation code. Except when an array index is used as a starting point for the MOVEA operation code, the length of array elements is meaningless.
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | [ + ] | The result field is greater than zero. |
73 – 74 | 2 | [ – ] | The result field is less than zero. |
75 – 76 | 3 | [ 0 or b ] | The result field is equal to zero or if the result field is character-based, the result field contains blanks. |
Extender | Description |
---|---|
P | PAD – The result field is cleared before the MOVEA operation is performed. Numeric fields are set to zero and character fields are set to blanks. |
The shorter length of factor 2 and the result field determines the length of the string that is moved. The length of the string can be calculated with the following formula:
E = The number of elements in the array. L = Length of a single array element. I = The index of the array. Length = E * L - ((I - 1) * L)
For example, if an array consists of 10 elements of 5 characters each and the array index is 4, then the length of the string moved is 35.
10 * 5 - ((4 - 1) * 5) = 35
There is no way to control the ending element for the move. If the field in factor 2 is longer than the total length of the array specified in the result field, the move continues through the last element in the array. In Example 5.84, the MSG field is moved into the STRING array.
Example 5.84: Moving a field to an array—no indexing.
.....DName+++++++++++EUDS.......Length+TDc.Functions++++++++++++++++++++++++++++ 0010 D String S 1A DIM(256) 0020 D Msg S 512A INZ(*ALL'Q') .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0030 C MOVEA MSG String
While the STRING array contains 256 single-character elements, each position of the MSG field occupies a single-array element. If the defined length of the MSG field is less than 256, the balance of the array remains as it was before the MOVEA operation was performed. If the defined length of the MSG field is greater than 256 (the number of elements in STRING times their length), every array element is replaced. The data in positions beyond 256 in the MSG field is not moved, and the storage beyond the last element in STRING is not touched by the operation. In Example 5.83, the MSG field is moved into the STRING array starting with array element x as the index. Because x is set to 45 on line 20, the move replaces data in the STRING array beginning with the 45th element.
Example 5.85: Moving a field to an array with indexing in the result field.
.....DName+++++++++++EUDS.......Length+TDc.Functions++++++++++++++++++++++++++++ 0010 D String S 1A DIM(256) .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0020 C Eval X = 45 0030 C MOVEA MSG String(X)
In Example 5.86, the array STRING is moved, beginning with its 128th element, to the MSG field. Because you are starting with the 128th array element, 127 array elements are not eligible to be moved. Therefore, the length of the move does not exceed 129 characters.
Example 5.86: Moving an array to a field with indexing in factor 2.
.....DName+++++++++++EUDS.......Length+TDc.Functions++++++++++++++++++++++++++++ 0010 D String S 1A DIM(256) .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0020 C Eval X = 128 0030 C MOVEA String(X) MSG
In Example 5.87, the EXTRACT array is moved to the STRING array. The move begins with the 128th element of the EXTRACT array, which is moved into the 211th element of the STRING array.
Example 5.87: Moving an array to an array with indexing in factor 2 and the result field.
.....DName+++++++++++EUDS.......Length+TDc.Functions++++++++++++++++++++++++++++ 0010 D String S 1A DIM(256) 0020 D Extract S 1A DIM(256) .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0030 C Eval X = 128 0040 C Eval Y = 211 0050 C MOVEA Extract(Y) String(X)
It is often useful to move a repeating string to an array. This enables all zeros, blanks, or other characters to be moved to each element of an array. The MOVEA operation used in conjunction with figurative constants provides this function.
In Example 5.88, the figurative constant *ZEROS is used on line 30 to move zeros into all locations of each element of the array ARR1. After the MOVEA operation on line 30 is performed, each array element of the array ARR1 contains '000'.
Example 5.88: Moving a value repeatedly to an array.
.....DName+++++++++++EUDS.......Length+TDc.Functions++++++++++++++++++++++++++++ 0010 D Arr1 S 3A DIM(50) 0020 D Arr2 S 5A DIM(8) .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0030 C MOVEA *ZEROS Arr1 0040 C MOVEA *ALL'XYZ' Arr1 0050 C MOVEA *ALL'XYZ' Arr2
The figurative constant *ALL is used with XYZ on line 40 to move a literal value of 'XYZ' to each element of the array ARR1. After this MOVEA operation is performed, each array element of the array ARR1 contains 'XYZ'. The figurative constant *ALL is used with XYZ on line 50 to move a repeating literal value to the array ARR2. After the MOVEA operation is performed, each element of the array ARR2 contains the following pattern:
ARR2 Element Values after MOVEA | |||||||
---|---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
XYZXY | ZXYZX | YZXYZ | XYZXY | ZXYZX | YZXYZ | XYZXY | ZXYZX |
The MOVEL operation copies the data from factor 2, left justified, to the result field. When the result field is an array, resulting indicators are not valid for this operation.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
[date format][sep] | MOVEL(P) | source | target | [+] | [-] | [0 or b] |
See also MOVE, MOVEA, SUBST, CAT, CLEAR, and EVAL
Factor 1 is optional, and is supported only when factor 2 or the result field (but not both) contain a date or time value. The format of the non-date or time value must be specified in factor 1. The MOVE and MOVEL operations support additional format codes. See Tables 5.4 and 5.18.
When the length of factor 2 is greater than or equal to the length of the result field, a complete replacement of the result field with factor 2 is performed, regardless of the presence of the operation extender. The data in factor 2 extending beyond the length of the result field is not copied. This is known as low-order truncation.
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | [ + ] | The numeric result field is greater than zero. |
73 – 74 | 2 | [ - ] | The numeric result field is less than zero. |
75 – 76 | 3 | [ 0 or b ] | The numeric result field is equal to zero or the character result field is blank. |
Extender | Description |
---|---|
P | PAD - Causes the result field's value to be cleared before the MOVE or MOVEL operation is performed. This has the same effect as performing the CLEAR operation immediately before performing the MOVE or MOVEL operation. |
When the length of factor 2 is less than the length of the result field and the operation extender is not specified, the number of characters replaced in the result field is equal to the length of factor 2 unless the P operation extender is specified.
Factor 2 can be a data structure, data structure subfield, literal value, named constant, figurative literal value, array, or array element. Factor 2 and the result field cannot be overlapping data structure subfields.
The result field can be any variable data type. When the result field is an array, factor 2 is moved into each element of the array.
The MOVEL operation differs from the MOVE operation in that the MOVEL operation copies data from factor 2, placing it left justified in the result field. In contrast, the MOVE operation copies data from factor 2, placing it right-justified in the result field. For more information on MOVE, see the subheading MOVE (Copy Data).
When data is moved to a numeric field, if the length of factor 2 is greater than or equal to the result field, the sign of factor 2 is used as the sign for the result field. If the length of factor 2 is less than the result field, the sign of the result field is retained.
In Example 5.89, after the MOVEL operation is performed, the AREACODE field contains the following:
*... ... 1 ... ... 2 ... ... 3 AREACODE = 630
Example 5.89: Moving a 10-digit phone number to an area-code field.
.....DName+++++++++++EUDS.......Length+TDc.Functions++++++++++++++++++++++++++++ 0010 D Phone S 10A INZ('6305551212') 0020 D AreaCode S 3S 0 .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0030 C MOVEL PHONE AreaCode
In Example 5.908, after the MOVEL operation is performed, the result field contains the following:
Partial = 'The customer'
Example 5.90: Moving left with factor 2 longer than the result field.
.....DName+++++++++++EUDS.......Length+TDc.Functions++++++++++++++++++++++++++++ 0010 D Text S 30A INZ('The customer number is 1234567') 0020 D Partial S 12A .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0030 C MOVEL TEXT Partial
In Example 5.91, after the MOVEL operation is performed, the result field contains the following:
*... ... 1 ... ... 2 ... ... 3 TEXT = 'XXXXcustomer number is 1234567'
Example 5.91: Moving left with factor 2 shorter than the result field.
.....DName+++++++++++EUDS.......Length+TDc.Functions++++++++++++++++++++++++++++ 0010 D Text S 30A INZ('The customer number is 1234567') .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0020 C MOVEL 'XXXX' TEXT
In Example 5.92, after the MOVEL operation with the operation extender is performed, the result field contains the following:
*... ... 1 ... ... 2 ... ... 3 TEXT = 'ZZZZZ '
Example 5.92: Moving left with factor 2 shorter than the result field with pad.
.....DName+++++++++++EUDS.......Length+TDc.Functions++++++++++++++++++++++++++++ 0010 D Text S 30A INZ('The customer number is 1234567') .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0020 C MoveL(P) 'ZZZZZ' TEXT
In addition to the standard date and time formats (see Table 5.4), several date and time format codes that are unique to the MOVE and MOVEL operations are supported. This allows simple conversion between date and non-date fields. Table 5.19 lists the set of date format codes that are supported by the MOVE and MOVEL operations. The most notable additions are the AS/400 CL date formats.
Format Code | Description | Year Length | Format[1] |
---|---|---|---|
*CDMY | CL Date Century-digit, Day, Month, Year | 3 | CDD/MM/YY |
*CMDY | CL Date Century-digit, Month, Day, Year | 3 | CMM/DD/YY |
*CYMD | CL Date Century-digit, Year, Month, Day | 3 | CYY/MM/DD |
*JOBRUN | Job runtime DATFMT attribute | 2 | Job Runtime DATFMT |
*JUL | Julian (2-digit year) | 2 | YY/DDD |
*LONGJUL | Long Julian (4-digit year) | 4 | YYYY/DDD |
*MDY | Month, Day, Year (2-digit year) | 2 | MM/DD/YY |
*DMY | Day, Month, Year (2-digit year) | 2 | DD/MM/YY |
*YMD | Year, Month, Day (2-digit year) | 2 | YY/MM/DD |
*ISO | International Standards Organization Standard | 4 | YYYY-MM-DD |
*USA | United States Standard | 4 | MM/DD/YYYY |
*EUR | European Standard | 4 | DD.MM.YYYY |
*JIS | Japanese International Standard | 4 | YYYY-MM-DD |
[1]The example with the separators is valid for moves from/to character fields. Moves between date/time fields and numeric fields are the same format as depicted. However, separators are not part of the move. |
The TIME format codes that can be used with MOVE and MOVEL include *HMS, *USA, and *JIS that use the colon as a separator, and *ISO and *EUR that use a period as a separator. In addition, all time formats except *USA are in a 24-hour clock format of HHMMSS. In contrast, *USA uses AM/PM notation to indicate time.
The *CYMD, *CMDY, and *CDMY date format codes support a one-position century digit in the first position in the date. This digit can be 0 through 9. The value 0 equates to 1900, the value 1 equates to 2000, the value 2 equates to 2100, and so on. By adding the year to these values, the true four-digit year is calculated.
When moving data from a numeric or character field to a date or time field, the format code (see Table 5.19) in factor 1 identifies the format of the non-date value of factor 2. When moving data from a date or time field to a numeric or character field, the format code in factor 1 identifies the format of the resulting non-date value stored in the result field.
Example 5.93 illustrates the use of the MOVE and MOVEL operations with date fields.
Example 5.93: Using MOVE and MOVEL with date fields.
.....DName+++++++++++EUDS.......Length+TDc.Functions++++++++++++++++++++++++++++ 0010 D InvDate S D DATFMT(*ISO) 0020 D OrdDate S D DATFMT(*MDY) 0030 D DueDate S D DATFMT(*USA) 0040 D Message S 30A Inz('The date value is...xx yy zzzz') 0060 D dbDate S 8S 0 .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0070 C *MDY MoveL '12/31/98' InvDate ** The result is, INVDATE = D'1998-12-31' 0080 C *USA Move '12/31/98' Message ** The result is, Message = 'The date value is...12/31/1998') C Reset Message 0090 C *USA MoveL '12/31/98' Message ** The result is, Message = '12/31/1998alue is...xx yy zzzz') 0100 C *ISO MoveL INVDATE dbDate ** The result is, dbDATE = 19981231
The MULT operation is used to calculate the product (result) of the multiplication of two operands.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
multiplier | MULT(H) | multiplicand | product | [+] | [-] | [0] |
MULT(H) | multiplicand | multiplier and product | [+] | [-] | [0] |
See also ADD, SUB, DIV, SQRT, and EVAL.
Factor 1 is optional and, if specified, is multiplied by the value specified for factor 2. The product is stored in the result field. If factor 1 is not specified, the result field is used in place of factor 1 and is multiplied by factor 2. The product is returned to the result field.
Example 5.94, if written in traditional mathematical expressions and using the asterisk as the multiplication symbol, would read as follows:
A * B = C C * B = C
Example 5.94: Long and short forms of multiply.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C A MULT B C 3 0 0020 C MULT B C
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | [ + ] | The result field is greater than zero. |
73 – 74 | 2 | [ - ] | The result field is less than zero. |
75 – 76 | 3 | [ 0 ] | The result field is equal to zero. |
Extender | Description |
---|---|
H | HALF ADJUST - The result field value is rounded after the mathematical operation is performed. |
In Example 5.94, the MULT operation on line 10 multiplies field A by field B, and the product is placed in field C.
On line 20, field C is multiplied by field B and the product replaces the value in field C. If the product is greater than zero, resulting indicator 1 is set on. If the product is less than zero, resulting indicator 2 is set on. If the product is equal to zero, resulting indicator 3 is set on.
In Example 5.95, the H operation extender (half-adjust) causes the product (result field) to be rounded. The product varies based on the decimal positions of the result field. For example:
If A = 3 and B = 4.25, then A * B = 12.75
Example 5.95: Multiplication with rounding.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C A Mult(H) B C 3 0
With half-adjust in effect, the product would be:
C = 13
If the product were defined as a three-digit variable with one decimal position, the result would be:
C = 12.8 (rounding to the tenths position)
The MVR operation moves the remainder of a division operation to the result field. The MVR operation must immediately follow a DIV operation code (see the DIV [Divide] sub-heading). If it does not, the RPG runtime exception/error handling routine is called. The half-adjust operation extender cannot be specified for this operation. Nor can it be specified for the DIV operation that immediately precedes the MVR operation.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
MVR | remainder | [+] | [-] | [0] |
See also DIV and %REM.
Factor 1 and factor 2 must not contain an entry. The remainder of the previous DIV operation is stored in the result field.
In Example 5.96, suppose A = 10 and B = 4 . If A, B, and C are defined as three-digit numeric fields with no decimal positions, the result of the MVR operation stores a value of 2 in the REMAINDER field.
Example 5.96: Integer division with remainder.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C A DIV B C 3 0 0020 C MVR Remainder 3 0
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | [ + ] | The result field is greater than zero. |
73 – 74 | 2 | [ - ] | The result field is less than zero. |
75 – 76 | 3 | [ 0 ] | The result field is equal to zero. |
The NEXT operation forces input from a specific device file. For example, if a single program is communicating with multiple workstations, the NEXT operation can be used to force a READ operation to read from a specific workstation.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
workstn device ID | NEXT (E) | workstn file | [error] |
See also ACQ and FORCE
Factor 1 must contain the name of the device that is read from by the next explicit READ operation or cycle read. Factor 1 must be either a quoted constant or a 10-position character-field name containing the name of the device. Factor 2 must contain the name of the device file from which the READ operation is requested.
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | N/A | |
73 – 74 | 2 | [error] | An error occurred during the operation. |
75 – 76 | 3 | N/A |
Extender | Description |
---|---|
E | ERROR - Causes the %ERROR and %STATUS built-in functions to be set if an error occurs during the operation. |
After the NEXT operation is issued, a read is issued to the program device specified in factor 1. The read function must be either an RPG cycle read or the READ operation. The NEXT operation is often used in conjunction with the ACQ operation. The ACQ operation acquires the devices for the program; the NEXT operation is used to control the input sequence.
A file specification keyword—MAXDEV, DEVID, or SAVEDS—is required to define a workstation file as a multiple device file. In Example 5.97, lines 30 and 40 acquire the workstation devices named DSP01 and DSP02. Lines 50 and 60 send the workstation file record format named PROMPT to the device named DSP01. Lines 70 and 80 do the same for the device named DSP02.
Example 5.97: Controlling input sequence with the NEXT operation.
.....FFileName++IFEASFRlen+LKeylnKFDevice+.Functions++++++++++++++++++++++++++++ 0010 FGLENTRY CF E WORKSTN MaxDev(*FILE) DevID(WSID) .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0030 C 'DSP01' ACQ GLENTRY 56 0040 C 'DSP02' ACQ GLENTRY 56 0050 C MOVEL 'DSP01' WSID 0060 C WRITE PROMPT 0070 C MOVEL 'DSP02' WSID 0080 C WRITE PROMPT 0090 C 'DSP01' NEXT GLENTRY 56 0100 C READ PROMPT 0110 C EXSR DoTheWork 0120 C 'DSP02' NEXT GLENTRY 56 0130 C READ PROMPT 0140 C EXSR DoTheWork
Line 90 in Example 5.97 issues the NEXT operation code. Factor 1 contains the constant 'DSP01', which conditions the program to access the DSP01 device. When line 100 is performed, the READ operation issues its read to the device named DSP01. Line 110 processes the data received on that read operation. Lines 120 to 140 do the same for the device named DSP02.
The OCCUR operation code performs one of two functions:
It sets the occurrence index of the multiple-occurrence data structure specified in factor 2. Once the occurrence index is set, all subsequent RPG operations performed against the data structure affect that occurrence until another OCCUR operation changes the occurrence index.
It retrieves the current occurrence index for a multiple-occurrence data structure specified in factor 2.
The OCCUR operation can be used within the *INZSR subroutine to assign unique initial values to each data-structure occurrence. The OCCUR operation can only be used on data structures that are declared as multiple occurrence (using the OCCURS keyword) and not when they are declared as arrays (using the DIM keyword).
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
[occurrence to set] | OCCUR (E) | data structure | [occurrence] | [error] |
See also OCCUR and DIM keywords and %ELEM.
Factor 1 is optional; if specified, it causes the OCCUR operation to set the occurrence of the data structure specified in factor 2 to the occurrence specified by factor 1. Factor 1 can be a numeric field (with zero decimal positions), a numeric constant (e.g., 15), or another multiple-occurrence data structure.
If factor 1 contains a constant or a numeric field, the value of factor 1 is used to set the occurrence of the data structure specified in factor 2.
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | N/A | |
73 – 74 | 2 | [error] | An error occurred during the operation. |
75 – 76 | 3 | N/A |
Extender | Description |
---|---|
E | ERROR - Causes the %ERROR and %STATUS built-in functions to be set if an error occurs during the operation. |
For example, if factor 1 contains the number 12, the occurrence of the data structure specified in factor 2 is set to its 12th occurrence.
If factor 1 contains another data structure name, that data structure's occurrence is used to set the occurrence of the data structure specified in factor 2. For example, if the data structure in factor 1 is set to its 14th occurrence, the occurrence of the data structure in factor 2 is set to 14. Factor 2 must contain the name of a multiple occurrence data structure, the occurrence of which is set or retrieved by the OCCUR operation.
The result field is optional unless factor 1 is omitted. It can contain a numeric field name (with zero decimal positions) that receives the number of the current occurrence of the data structure specified in factor 2.
Resulting indicator 2 can be specified to signal when the value specified in factor 1 is less than or equal to zero, or greater than the maximum number of occurrences for the data structure.
The OCCUR operation provides a high level of function. For example, because arrays can be specified as a data-structure subfield, two-dimensional arrays can be created. See Example 5.98.
Example 5.98: Illustrating the use of the OCCUR operation.
.....DName+++++++++++EUDS.......Length+TDc.Functions++++++++++++++++++++++++++++ 0020 D TwoDims DS Occurs(10) 0030 D Arr 10 DIM(10) 0040 D DataF2 DS Occurs(10) 0050 D FieldD 6A 0050 D FieldE 6A .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0070 C 3 OCCUR TWODIMS 0080 C Z-ADD 4 INDEX 3 0 0090 C INDEX OCCUR DATAF2 0100 C Occur TwoDims CurOccur 3 0 0110 C Eval NumOccurs = %Elem(DataF2) 0120 C DATAF2 OCCUR TWODIMS NEWOCR 3 0 56 0130 C *IN56 CASEQ *ON OnDSError 0140 C END
In Example 5.98, line 70 sets the occurrence of the data structure TWODIMS to its third occurrence. Line 80 initializes the field INDEX to 4 and line 90 sets the occurrence of the data structure DATAF2 to the value contained in the field INDEX. Line 100 contains no value for factor 1; therefore, the occurrence of the data structure TWODIMS is unchanged and its occurrence is placed into the CUROCCUR result field.
Line 110 retrieves the number of occurrences declared for the DATAF2 data structure. The %ELEM built-in function is used to extract the occurrences and store them in the numeric field named NUMOCCURS.
Line 120 sets the occurrence of the data structure TWODIMS to the same occurrence as the data structure DATAF2, specified in factor 1. Line 120 also stores the occurrence set by the operation in the result field NEWOCR. If the occurrence set on line 120 is outside the range of the TWODIMS data structure, resulting indicator 2 (indicator 56 in our example) is set on, and subroutine ONDSERROR is called (line 130).
Single-occurrence data structures don't need to be named. If a data structure is a multiple-occurrence data structure, it must be named. For example, a multiple-occurrence data structure consisting of four occurrences, each containing two fields, is described in Example 5.99.
Example 5.99: A multiple occurrence data structure.
.....DName+++++++++++EUDS.......Length+TDc.Functions++++++++++++++++++++++++++++ 0010 D Company DS Occurs(4) 0020 D ActNbr 7P 0 0030 D CstNam 20A
Line 10 of Example 5.99 defines the data structure name as COMPANY. The OCCURS keyword indicates that there are four occurrences. Lines 20 and 30 define the two fields that make up the data-structure format. If this data structure is filled with data, it might look like the data listed in Table 5.20.
Occurrence | ACTNBR | CSTNAM |
---|---|---|
1 | 05320 | PeaTree.com Corp. |
2 | 05340 | Skyline Pigeon Productions |
3 | 01207 | Maui Pineapple |
4 | 09404 | Cozzi Research |
The ON-ERROR operation is used perform error tests within an error monitor group. When an operation within a monitor group generates an error, is transferred to the first ON-ERROR operation for the monitor group.
Factor 1 | Op Code | Factor 2 | Result Field | Resulting Indicators |
---|---|---|---|---|
On-Error | { error status code1 {: error status code2 : … }) |
See also MONITOR, ENDMON, %ERROR, %STATUS
The ON-ERROR operation specifies the exception/error status codes that are being monitored by the monitor group. If the error status code is not included in one of the ON-ERROR statements within this monitor group, then the normal RPG exception/error handling routines are called.
Multiple status codes may be specified on each ON-ERROR statement, or one of the figurative constants listed below may be specified to monitor for a range of error status conditions. If more than one error status code is specified, separate each status code with a colon. The figurative constants that may be monitored on the ON-ERROR operation are as follows:
Error Status Code | Description |
---|---|
*PROGRAM | All program status error codes. The range tested is 100 to 999. |
*FILE | All file status error codes. The range is tested is 1000 to 9999. |
*ALL | Both program status and file status errors. The range tested is 100 to 9999. |
Multiple ON-ERROR statements are allowed within an monitor group. Error status codes are tested on a first come, first served basis. That is the first ON-ERROR statement is tested first. If it handles the particular status code, then its group of error handling operations is performed. Then control is passed to the ENDMON statement. Consequently, no other ON-ERROR statements are called. If, however, the error status code is not being monitored by the ON-ERROR statement, control passes to the next ON-ERROR statement (if any). If all ON-ERROR statements have been tested and the error status code is not trapped by one of the statements, control passes to the normal RPG exception/error handling routines.
In Example 5.100, the MONITOR statement (line 1) and the ENDMON statement (line 11) create a monitor group. This monitor group consists of the regular operation codes on lines 2 through 6, and the On-Error error-trapping statements on lines 7 through 10. The operation codes on lines 2 through 6 are performed.
Example 5.100: Monitor Group.
.....CSRn01..............OpCode(ex)Extended-factor2++++++++++++++++++++++ 0001 C Monitor 0002 C Eval X = A + B / C 0003 C CustNo Chain CustMast 0004 C If %Found 0005 C Eval BalDue = X 0006 C Endif 0007 C On-Error 0102 0008 C 'Divisor err' Dsply 0009 C On-Error 1218 : 1222 0010 C 'Locked Rec' Dsply 0011 C EndMon
The ON-ERROR operation codes that appear on lines 7 and 9 check for a divide-by-zero error (line 7) and a record locking or other locking condition (line 9).
The OPEN operation opens the full procedural file specified in factor 2. The file must be closed in order to avoid an error. The User Controlled Open (USROPN) keyword can be specified for the file on its file specification. When the USROPN keyword is specified, the OPEN operation is normally required to open the file.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
OPEN (E) | file name | [error] |
See also CLOSE, FEOD, ACQ, and %OPEN.
Factor 2 must contain the name of the file being opened. The file must be closed; otherwise an exception/error is generated. When RPG programs start, unless the USROPN keyword is specified, the RPG cycle automatically opens files for processing. In this situation, the file must be closed with the CLOSE operation before an OPEN operation will succeed.
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | N/A | |
73 – 74 | 2 | [error] | An error occurred during the operation. |
75 – 76 | 3 | N/A |
Extender | Description |
---|---|
E | ERROR - Causes the %ERROR and %STATUS built-in functions to be set if an error occurs during the operation. |
When a WORKSTN device file is opened and the DEVID keyword is specified, the associated workstation ID field is set to blanks. For more information, see the ACQ (Acquire) subheading.
In Example 5.101, the file CUSTMAST is opened. If the OPEN operation (line 50) doesn't complete successfully, resulting indicator 2 (indicator 56 in the example) is set on, signaling that the open attempt failed. The remainder of the program reads and prints each record in the file CUSTMAST. The file is then closed and a line of totals is printed.
Example 5.101: Opening a file, printing it, then closing the file.
.....FFileName++IFEASFRlen+LKeylnKFDevice+.Functions++++++++++++++++++++++++++++ 0010 FCUSTMAST IF E DISK USROPN 0020 FPRINTER O E PRINTER .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0030 C If NOT %OPEN(CUSTMAST) 0040 C OPEN CUSTMAST 56 0050 C ENDIF 0060 C If *IN56 0070 C READ CUSTMAST LR 0080 C Dow *INLR = *OFF 0090 C ADD AMOUNT TOTAL 0100 C WRITE DETAIL 0110 C READ CUSTMAST LR 0120 C ENDDO 0130 C CLOSE CUSTMAST 0140 C WRITE TOTALS 0150 C ENDIF
Example 5.101 uses the DOW loop and READ operation to set on and test the condition of indicator LR, which controls the ending of the DO loop—and the program.
The ORxx operation is used in conjunction with the IFxx, DOUxx, DOWxx, and WHENxx operations. The ORxx operation complements these other operation codes in that their conditioning is extended through the use of the ORxx operation. Conditioning indicators aren't allowed for this operation.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
compare value 1 | ORxx | compare value 2 |
See also ANDxx, IFxx, DOWxx, DOUxx, and WHENxx
Factor 1 and factor 2 are required and must contain a variable, literal value, array element, or figurative constant. Factor 1 is compared to factor 2 using the ORxx operation Boolean operator. See Table 5.9 for information on the Boolean operators (GE, GT, LE, LT, EQ, and NE). Factor 1 and factor 2 must be the same type.
In Example 5.102, the DO UNTIL loop is performed until indicator 58 is set on or field C equals 10. Note that this form of OR cannot be used with the IF, DOW, DOU, and WHEN natural expression operations.
Example 5.102: Using OREQ to extend the DOUxx operation.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C *IN58 DOUEQ *ON 0020 C OREQ 10 0030 C ADD 1 C 3 0 0040 C READ CUSTMAST 58 0050 C ENDDO
The OTHER operation is used to perform a default or "catch all" routine within an in-line case group delimited with the SELECT/ENDSL operations. Conditioning indicators are not valid for this operation.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
OTHER |
See also SELECT, WHEN, and ENDSL.
The OTHER operation identifies one or more operations that are run when no WHENxx (When) condition within the case group has been satisfied. Only one OTHER operation can be specified per in-line case group. An in-line case group is defined by the SELECT-WHEN-OTHER-ENDSL operations.
Most operation codes can appear within an in-line case group, including another in-line case group. The BEGSR and ENDSR operations cannot appear within an in-line case group.
Example 5.103 shows how to code the OTHER operation.
Example 5.103: Testing input and performing a routine.
.....CSRn01Factor1+++++++<—OpCode(ex)—>Factor2+++++++Result++++++++Len++DcHiLoEq * Stay in loop until exit is requested C DOU Funct = Exit C | EXFMT INQUIRY 58 C | EXSR RTVMAC C | SELECT * If the exit key was pressed, then leave the Do loop C | When Funct = EXIT C | | Eval *INLR = *ON C | | LEAVE * If the OPTION is B to Z, then send an error C | When Option >= 'B' and Option <= 'Z' C | | Eval Msg = 'ERROR' * Otherwise, ask the user to confirm their choice C | OTHER C | | EXFMT CONFIRM C | ENDSL C ENDDO
The OUT operation code sends data to the data area named in factor 2. Before an OUT operation can be used on a data area, the data sent to the data area replaces all data in the data area.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
[*LOCK] | OUT (E) | data area field | [error] | |||
[*LOCK] | OUT (E) | *DTAARA | [error] |
See also IN and UNLOCK
Factor 1 can contain the reserved word *LOCK to retain the lock on the data area.
Factor 2 is required and must contain the name of the field assigned to the data area being written. Optionally, all data areas can be output with a single OUT operation by specifying *DTAARA in factor 2.
In Example 5.104, lines 10 and 20 define the data structure CONTROL. The DTAARA keyword is used to assign the CTRLDATA data area to the CONTROL data structure. The data area is input to the program on line 40. The contents of the data area is altered (line 50) and output with the OUT operation (line 70).
Example 5.104: Using a data area to store a control number.
.....DName+++++++++++EUDS.......Length+TDc.Functions++++++++++++++++++++++++++++ 0010 D Control DS Dtaara(CtrlData) 0020 D NextNbr 5S 0 INZ .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0040 C *LOCK IN Control 0050 C ADD 1 NextNbr 0060 C Eval ActNbr = NextNbr 0070 C OUT Control
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | N/A | |
73 – 74 | 2 | [error] | An error occurred during the operation. |
75 – 76 | 3 | N/A |
Extender | Description |
---|---|
E | ERROR - Causes the %ERROR and %STATUS built-in functions to be set if an error occurs during the operation. |
The PARM operation is used to define a parameter. A parameter is a method used to pass data between programs. Parameters are passed between programs using the CALL or CALLB operation. A parameter can be defined on a parameter list with the PLIST operation or directly following a CALL or CALLB operation. If the PARM operation follows a CALL or CALLB operation, that PARM operation is associated with the CALL or CALLB operation. If the PARM operation follows a PLIST operation, the parameter is associated with the PLIST. To use the parameter list, the name of the PLIST must appear in the result field of the CALL or CALLB operation.
Parameters are used extensively in the modern RPG language. Modular program design, structured programming, and flexible systems design all contribute to the need for the program-to-program CALL operation. The parameter is a useful part of this operation.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
input from parm | PARM | output to parm | parameter | *OMIT |
See also PLIST, CALL, CALLB, and CALLP
Factor 1 and factor 2 are optional and, if present, must be the same type of field as the result field. Factor 1, if present, must be a field, (i.e., it cannot be a constant). Factor 2 can be a field or a constant.
Factor 1 can be used to receive the value of the parameter. If factor 1 is specified, data passed to the program by a CALL or CALLB operation from another program is moved to the field in factor 1 from the result field. This technique is often used to move data into a data structure subfield, indicator variable, or array element.
Factor 2 can be used to place data into the parameter when a program ends or calls another program. The data in factor 2 is moved into the result field when the program ends or calls another program. This technique is often used to move a data structure subfield, indicator variable, constants, or array elements into the result field before calling another program and upon program completion.
The parameters of a CALLB operation can be omitted by specifying the *OMIT value. This value indicates that no value is being passed to the called program/procedure. When *OMIT is specified, a *NULL value is passed to the called program. Checking for a *NULL in the called procedure will indicate whether *OMIT was specified.
The effect on the result field when using factor 2 with the PARM operation is equivalent to using a MOVEL or Z-ADD operation. Character fields are moved to the result field, left justified, and padded with blanks. Numeric data is moved to the result field, right justified, and padded with zeros.
The result field is required and must conform to the following criteria: If factor 1 is specified, the result field must match its type and length. It must match the type and length of factor 2 when factor 2 contains a field name, and it must match the type of factor 2 when factor 2 is a literal value, figurative constant, or reserved word.
When used as an *ENTRY PLIST parameter, the result field can be a field name, array name, or data structure name, but cannot be a data structure subfield name or an array element.
When used as a parameter of the CALL or CALLB operation, the result field can be a field name, data structure name, data structure subfield name, array name, or an array element.
Parameters are passed by reference, not value. The address or pointer of the parameter is passed to the program being called. The called program references the parameter by defining a parameter of its own. Both parameters address the same memory location. Therefore, if the value of a parameter in one program is changed, the value in the second program also is changed.
The program status data structure can be used to determine the number of parameters passed to a program. A predefined subfield location, referred to as *PARMS, provides a value for the number of parameters passed to the RPG program. If no parameters are passed, *PARMS equals zero. In addition, the %PARMS built-in function can be used to retrieve the number of parameters passed to a procedure.
Note | Numeric fields that are defined within the scope of a calculation specification default to packed numeric in RPG III and RPG IV, and to zoned numeric in RPG II. This can cause problems when passing parameters between programs. To avoid these problems, ensure that numeric parameters are of the same type (e.g., zoned, packed, binary) and length. |
In Example 5.105, lines 60 to 100 move the parameters into fields that are used in the program. If the number of parameters passed to a program is different from the number of parameters defined on the *ENTRY PLIST parameter list, %PARMS can be used to avoid referencing parameters that are not passed. For example, if only one parameter (the field PACCT) is received by the program, and the field PMODE (the second parameter) is addressed in any way by the RPG code, a runtime error is generated.
Example 5.105: Passing parameters to a called program.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C *ENTRY PLIST 0020 C PARM PACCT 0030 C PARM PMODE * If two parms are passed in, then use parm 2, * else, use a default value for MODE. 0060 C If %Parms >= 2 0070 C MOVE PMODE MODE 0080 C ELSE 0090 C MOVE 'INQUIRY' MODE 0100 C ENDIF 0110 C DOU Funct = 'EXIT' C Select 0120 C When Mode = 'INQUIRY' 0130 C CALL 'CUSTINQ' 0140 C PARM ACTNBR 0150 C PARM SEARCH 0160 C ELSE 0170 C When Mode = 'UPDATE' 0180 C CALL 'CSTUPD' PLIST1 0190 C ELSE 0200 C When Mode = 'DELETE' 0210 C CALL 'CSTDEL' PLIST1 0220 C endsl 0240 C ENDDO 0250 C PLIST1 PLIST 0260 C PARM ACTNBR 0270 C PARM MODE FUNCT 0280 C RETURN PARM RTNCOD
In Example 5.105, note that the comparison for the number of parameters (line 60) uses the operation IF GREATER THAN OR EQUAL TO. This operation is used instead of the EQUAL operation to ensure that the program continues to function without changing line 60 should additional parameters be added in the future.
Parameters are a part of a parameter list. See the following subheading, PLIST (Parameter List Declaration) for more information. A named parameter list is produced with the PLIST operation. An unnamed parameter list is a parameter list built by placing PARM operations immediately following a CALL or CALLB operation. Examples of each of these methods are shown in Examples 5.106 and 5.107.
Example 5.106: Defining a parameter list.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C GETPRT PLIST 0020 C PARM PRTNBR 0030 C PARM CMPNTS ... program code can go here. xxxx C CALL 'PARTINQ' GETPRT 56
Example 5.107: Specifying parameters without a parameter list.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C CALL 'PARTINQ' 56 0020 C PARM PRTNBR 0030 C PARM CMPNTS
The PLIST operation defines a list of parameters (PARM) that is used when the program is called, when a program calls another program, and when an I/O operation to a SPECIAL device is performed. At least one PARM operation must appear immediately following the PLIST operation.
A parameter list can be specified as the result field of a program-to-program CALL or CALLB operation. It also can be specified as a value for the PLIST keyword of the file specification for SPECIAL device files.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
parameter list name | PLIST |
See also PARM, CALL, CALLB, and CALLP
Factor 1 must contain a unique name of the parameter list being defined. Optionally, the reserved word *ENTRY can be specified in factor 1. *ENTRY is a special parameter list. It defines the parameters that are received by the program when it is called.
There are two kinds of parameter lists: named and unnamed. Named parameter lists are defined with the PLIST operation. The name of the parameter list is specified in factor 1 of the calculation specification. A named parameter list can be used by one or more CALL or CALLB operations, or as the parameter list of a SPECIAL device file.
Placing the PARM operation immediately following the CALL or CALLB operations specifies an unnamed parameter list. Unnamed parameter lists do not use the PLIST operation.
Examples 5.108 through 5.110 illustrate the three areas where a PLIST is used. Example 5.108 contains an entry parameter list. When this program is called, a single parameter, ACCT#, is received by the program.
Example 5.108: Defining a program-entry parameter list.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C *ENTRY PLIST 0020 C PARM ACCT#
Example 5.109 contains a named parameter list termed GETPRT. Any number of CALL or CALLB operations can use the parameter list. Line 256 uses the parameter list as the result field. All parameters of the parameter list GETPRT are passed to the called program RTVPART.
Example 5.109: Defining a parameter list for a program call.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C GETPRT PLIST 0020 C PARM PRTNBR 0030 C PARM CMPNTS xxxx * ... additional program code goes here. 0256 C CALL 'RTVPART' GETPRT 56
Example 5.110 illustrates the SPECIAL device file use of the PLIST. When a SPECIAL device is used, RPG automatically constructs a parameter list. When additional parameters are required for the SPECIAL device routine, a user-written PLIST has to be created.
Example 5.110: Additional parameters of a SPECIAL device file.
.....FFileName++IFEASFRlen+LKeylnKFDevice+.Functions++++++++++++++++++++++++++++ 0010 FTAPEDRV IF E SPECIAL PGMNAME(TAPEIO) Plist(TapeDrive) .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0020 C TapeDrive PLIST 0030 C PARM TIMDTE 0040 C PARM USERID 0050 C READ TAPEDRV 58
The additional parameters are appended to the parameter list that RPG automatically generates. Example 5.108 illustrates the appending of a date/timestamp and user ID to the SPECIAL device-parameter list.
RPG automatically creates a parameter list consisting of the following parameters for SPECIAL device files:
Operation Code. A single character that identifies the operation that is being requested. Table 5.21 contains a list of possible operations.
Operation Code | Description |
---|---|
O | Open the file. |
C | Close the file. |
R | Read the file and move the contents of the next record read into the DATA AREA parameter (parameter 4). |
W | Write to the file, using the DATA AREA parameter (parameter 4) as the output data. |
D | Delete the current record from the file. |
U | Replace (update) the current record's data with the data from the DATA AREA parameter (parameter 4). |
Return Code. A single-character parameter that contains the status of the operation request. Table 5.22 contains a list of return codes.
Return Code | Description |
---|---|
0 | Normal completion of requested operation. |
1 | End of file detected. |
2 | The operation did not run—an error has occurred. |
Error Code. A five-digit zoned numeric field that contains an error code. When parameter 2, the return code, equals '2', the error code (parameter 3) is moved into the field specified for *RECORD in the file information data structure.
Data Area. A character field that contains the data that is transferred between the program and the SPECIAL device routine. The length of this parameter is equal to the record length of the SPECIAL file.
The POST operation places status or input/output information into the file information data structure.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
workstn device ID | POST (E) | workstn file name | [file info data struc] | [error] |
See also ACQ and REL.
Factor 1 is optional and can contain a field name or quoted constant containing a program device name. Specifying factor 1 causes the POST operation to place status information into the information data structure. If factor 1 is omitted, the POST operation places input/output information into the information data structure.
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | N/A | |
73 – 74 | 2 | [error] | An error occurred during the operation. |
75 – 76 | 3 | N/A |
Extender | Description |
---|---|
E | ERROR - Causes the %ERROR and %STATUS built-in functions to be set if an error occurs during the operation. |
Factor 2 and the result field are mutually optional; one or the other or both must be specified. Factor 2 can contain the name of the workstation file about which the POST operation places information into the information data structure. If the result field is blank, the information data structure associated with the file specified in factor 2 is used as the target of the POST operation.
The result field can contain the name of an information data structure into which the POST operation places the status or input/output information. If both factor 2 and the result field are specified, the result field must contain the name of the information data structure associated with the file specified in factor 2. If factor 2 is blank, the result field is required and the information data structure's associated file name is used as the file for the POST operation.
In Example 5.111, the workstation file GLENTRY is the target of the POST operation.
Example 5.111: POST status information to an information data structure.
.....FFileName++IFEASFRlen+LKeylnKFDevice+.Functions++++++++++++++++++++++++++++ 0010 Fglentry CF E WORKSTN Infds(GL_Infds) .....DName+++++++++++EUDsFrom+++To/L+++TDc.Functions++++++++++++++++++++++++++++ 0020 D PSDS SDS 0030 D WSID 244 253A 0040 D GL_Infds DS 0050 D Status *Status 0060 D Device 272 275A 0070 D Model 276 277A 0075 D Fkey 369 396A .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0080 C WSID POST glentry 56 0090 C If Device = '3180' or Device = '3477' 0100 C Move *ON DS4 1 0110 C else 0120 C Move *ON DS3 1 0130 C Endif 0150 C If DS4 = *ON 0160 C EXFMT Panel4 0170 C else 0180 C EXFMT Panel3 0190 C EndIf
Note | The information data structure for WORKSTN device files differs from system to system. The file information data structure positions in this example are for RPG IV on the IBM AS/400 and may differ on other systems. |
The READ operation reads a record from a full-procedural file (i.e., the letter F appears in column 18 of the file specification for the file). For data files, the record that is read is the next record in the file. For workstation file formats, the record format specified in factor 2 is the record that is read. And for workstation files, the record format that was sent to the workstation last is read.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
READ (N E) | format name | [error] | [EOF] | |||
READ (N E) | file name | [data structure] | [error] | [EOF] |
See also READP, READPE, READE, CHAIN, WRITE, UPDATE, DELETE, and UNLOCK
Factor 2 is required and can contain the name of the file or file record format that is read. If a record format name is specified, the file must be an externally described file.
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | N/A | |
73 – 74 | 2 | [error] | An error occurred during the operation. |
75 – 76 | 3 | [EOF] | Set on when the end of file is reached. |
The result field can contain the name of a data structure when factor 2 contains a program-described file name. When the READ operation completes successfully, the content of the record is copied to the data structure specified in the result field. This technique provides support of external file definitions for program-described files through the use of an externally described data structure.
When a READ operation fails to read a record, as is the case when the end of file is reached, resulting indicator 3 (if specified) and the %EOF built-in function are set on. The following characteristics apply when a record is accessed with the read operation:
Extender | Description |
---|---|
E | ERROR - Causes the %ERROR and %STATUS built-in functions to be set if an error occurs during the operation. |
N | NO LOCK - Causes the database record to be read without placing a record lock on the record. This is useful for files that have been open for update operations. |
For INPUT files, the record is retrieved, but no record locking occurs.
For OUTPUT-only files, this operation is not valid.
For UPDATE files, if no operation extender is specified, the record is retrieved and locked until it is released through one of the following:
Another READ, READE, READP, READPE, or CHAIN operation.
The record is updated by an UPDATE or EXCEPT operation.
The record is deleted by a DELETE or EXCEPT with DEL operation.
The record is implicitly released by one of the following operations:
Except to an empty output format (EXCEPT).
Unlock the record (UNLOCK).
Set lower limit (SETLL).
Set greater than (SETGT).
Force end of data (FEOD).
Close file (CLOSE).
In Example 5.112, the READ operation on line 10 reads the first record in the file CUSTMAST. The DOW operation (line 20) begins the DO WHILE group that processes each record in the file. Resulting indicator 3 (LR in the example) is set on if the file is at end of file when the READ operation is performed (line 40). The %EOF built-in function is set to *ON when end of file is reached.
Example 5.112: Reading a file until end of file is detected.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq * Read the first record in the file. 0010 C READ CUSTMAST LR * If records exist, then enter the read/print loop * and print the first record. 0020 C dow NOT %EOF * Print the record's data. 0030 C Except REPORT * Read the next record in the file. 0040 C READ CUSTMAST LR 0050 C EndDo
When a workstation device file format is specified in factor 2 and the format has not been written to the workstation, the following occurs: If the Write-Before-Read keyword exists in the file definition, the record format is written to the workstation, and then the READ option is performed. If the Write-Before-Read keyword is not specified, resulting indicator 2, if specified, is set on. If resulting indicator 2 is not specified, control is passed to the RPG exception/error routine.
If factor 2 contains a workstation file name, the last workstation file record format written to the device is read. When factor 2 contains a workstation file name, workstation timeout can be detected.
A workstation timeout occurs after a period of inactivity at the workstation. For example, if the workstation operator hasn't pressed <Enter> for a period of time (say 5 minutes), the workstation times out and resulting indicator 2 is set on. After a workstation record format is written, a workstation timeout can be detected by issuing a READ to the workstation file. See Example 5.113.
Example 5.113: Reading a workstation file with timeout support.
.....FFileName++IFEASFRlen+LKeylnKFDevice+.Functions++++++++++++++++++++++++++++ 0010 FCUSTINQ CF E WORKSTN MaxDev(*Only) 0020 FCUSTMAST IF E K DISK INFDS(CM_INFDS) .....DName+++++++++++EUDS.......Length+TDc.Functions++++++++++++++++++++++++++++ 0030 D CM_INFDS DS 0040 D Status *STATUS .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0050 C ACTNBR CHAIN CUSTMAST 54 0060 C IF %FOUND 0070 C WRITE Inquiry 0080 C READ CUSTINQ 5658 0090 C If %ERROR = *ON and %STATUS = 1331 0100 C Exsr TimeOut 0110 C Endif 0120 C EndIf *... the program continues.
To support the workstation timeout feature, the INVITE (Invite from Device) keyword must exist in the device file. Also, a MAXDEV(*ONLY) keyword must be specified.
The READC operation reads the changed records from a subfile. A record is read only if its data has been changed.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
READC | subfile format name | [error] | [EOF] |
See also EXFMT and SFILE keywords
Factor 2 is required and must contain the name of a WORKSTN device file record format that is defined as a subfile. A WORKSTN record format is declared a subfile by specifying the SFILE keyword on the file specification.
In Example 5.114, line 10 defines the record format CUSTLIST as a subfile. Line 20 issues an EXFMT operation that displays the subfile. The READC operation on line 30 reads the first changed record in the subfile. The DO WHILE loop on lines 40 to 70 processes each changed subfile record.
Example 5.114: Displaying a subfile then reading all changed records.
.....FFileName++IFEASFRlen+LKeylnKFDevice+.Functions++++++++++++++++++++++++++++ 0010 FCUSTINQ CF E WORKSTN Sfile(Custlist : rrn) .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0020 C EXFMT LISTCTL 0030 C ReadC CUSTLIST 58 0040 C dow NOT %EOF(CustList) 0050 C** Code to process the changed record goes here. 0060 C ReadC CUSTLIST 58 0070 C EndDo
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | N/A | |
73 – 74 | 2 | [error] | An error occurred during the operation. |
75 – 76 | 3 | [EOF] | The end of subfile has been reached. |
Extender | Description |
---|---|
E | ERROR - Causes the %ERROR and %STATUS built-in functions to be set if an error occurs during the operation. |
The READE operation uses the full-key value or partial-key value specified in factor 1 to sequentially retrieve a record from the keyed file specified in factor 2.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
[key value] | READE (N E) | format name | [error] | [EOF] | ||
[key value] | READE (N E) | file name | [data structure] | [error] | [EOF] |
See also READPE, READP, READ, CHAIN, WRITE, UPDATE, DELETE, and UNLOCK
Factor 1 is optional and can contain the key value for the READE operation. If factor 1 is blank, the next record with a key equal to the current record is retrieved. If a record with an equal key does not exist, resulting indicator 3 is set on. Factor 2 is required and must contain a database file or format name to be read.
The result field can contain the name of a data structure into which the data from the file is copied. This option is valid only for program-defined database files.
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | N/A | |
73 – 74 | 2 | [error] | An error occurred during the operation. |
75 – 76 | 3 | [EOF] | Set on when the end of file is reached. |
Extender | Description |
---|---|
E | ERROR - Causes the %ERROR and %STATUS built-in functions to be set if an error occurs during the operation. |
N | NO LOCK - Causes the database record to be read without placing a record lock on the record. This is useful for files that have been open for update operations. |
When a READE operation fails to read a record, as is the case when the end of file is reached, resulting indicator 3 (if specified) and the %EOF built-in function are set on.
The following characteristics apply when a record is accessed by the READE operation:
For INPUT files, the record is retrieved, but no record locking occurs.
For OUTPUT-only files, this operation is not valid.
For UPDATE files, if no operation extender is specified, the record is retrieved and locked until it is released through one of the following:
Another READ, READE, READP, READPE, or CHAIN operation.
The record is updated by an UPDATE or EXCEPT operation.
The record is deleted by a DELETE or EXCEPT with DEL operation.
The record is implicitly released by one of the following operations:
Except to an empty output format (EXCEPT).
Unlock the record (UNLOCK).
Set lower limit (SETLL).
Set greater than (SETGT).
Force end of data (FEOD).
Close file (CLOSE).
The READE operation is used when a data file contains non-unique full keys or partial keys. The READE operation provides sequential access to those non-unique keys. When the READE operation is the first input/output operation after an OPEN operation, the first record that matches the key value specified in factor 1 is retrieved. Example 5.115 shows an example of using the READE operation.
Example 5.115: Adding up the quantity on hand for a specific part number.
.....FFileName++IFEASFRlen+LKeylnKFDevice+.Functions++++++++++++++++++++++++++++ 0010 FPARTMAST IF E K DISK .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0020 C PART# KLIST 0030 C KFLD PART 10 * Establish the part number to total. 0040 C MOVEL(p) 'CEC01' PART * Position the file to the first record for this PART number. 0050 C PART# SetLL PARTMAST 58 0060 C Eval QtyOh = 0 0070 C dow NOT %EOF 0080 C ADD QTYOH PARTOH 7 0 * Retrieve the next record contain the same part number. 0090 C PART# READE PARTMAST 58 0110 C ENDDO
The READP reads the previous record from the database file specified in factor 2.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
READP (N E) | format name | [error] | [BOF] | |||
READP (N E) | file name | [data structure] | [error] | [BOF] |
See also READ, READE, READPE, CHAIN, WRITE, UPDATE, DELETE, and UNLOCK
Factor 2 is required and must contain the name of a database file or an externally described, database file-format name.
The result field can be specified for a program-described file only. The result field can contain the name of a data structure into which the retrieved record's data is placed. When the record is retrieved, the data is copied into the data structure.
When a READP operation fails to read a record, as is the case when the beginning of file is reached, resulting indicator 3 (if specified) and the %EOF built-in function are set on.
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | N/A | |
73 – 74 | 2 | [error] | An error occurred during the operation. |
75 – 76 | 3 | [BOF] | Set on when the beginning of the file is reached. |
Extender | Description |
---|---|
E | ERROR - Causes the %ERROR and %STATUS built-in functions to be set if an error occurs during the operation. |
N | NO LOCK - Causes the database record to be read without placing a record lock on the record. This is useful for files that have been open for update operations. |
After an unsuccessful READP operation, resulting indicator 3 is set on. A CHAIN, SETLL, or SETGT operation must be used to reposition the file before any other input operation can be performed on the file. The following characteristics apply when a record is accessed with the READP operation:
For INPUT files, the record is retrieved, but no record locking occurs.
For OUTPUT-only files, this operation is not valid.
For UPDATE files, if no operation extender is specified, the record is retrieved and locked until it is released using one of the following:
Another READ, READE, READP, READPE, or CHAIN operation.
The record is updated by an UPDATE or EXCEPT operation.
The record is deleted by a DELETE or EXCEPT with DEL operation.
The record is implicitly released by one of the following operations:
Except to an empty output format (EXCEPT).
Unlock the record (UNLOCK).
Set lower limit (SETLL).
Set greater than (SETGT).
Force end of data (FEOD).
Close file (CLOSE).
In Example 5.116, the workstation file defined on line 20 is used to display a customer master file. Line 40 positions the file to end of file (with the *HIVAL figurative constant). Line 50, therefore, reads the last record in the file CUSTMAST.
Example 5.116: Reading a data file backwards and filling a subfile with the data.
.....FFileName++IFEASFRlen+LKeylnK.Device+.Functions++++++++++++++++++++++++++++ 0010 FCUSTINQ CF E WORKSTN Sfile(Custlist : rrn) 0010 FCUSTMAST IF E K DISK .....CSRn01Factor1+++++++<—OpCode(ex)—>Factor2+++++++Result++++++++Len++DcHiLoEq 0040 C *HIVAL SetGT CUSTMAST 0050 C ReadP CUSTMAST 58 0060 ** In this case, %EOF indicates beginning-of-file 0070 C dow NOT %EOF 0080 C | Add 1 RRN 5 0 0090 C | Write CUSTLIST 0100 C | ReadP CUSTMAST 58 0120 C EndDo 0130 C EXFMT CustPanel 0140 C EXSR RtvMacro
The DO WHILE loop (lines 70 to 120) writes to the subfile CUSTLIST, and then reads the next previous record in the file CUSTMAST (line 10).
The subfile CUSTLIST uses the relative record number field RRN to control the records that are written. Line 80 increments the subfile relative record. Line 90 writes the data retrieved by the previous READP operation to the subfile. This technique assumes that the subfile record contains the same field names as the data file CUSTMAST and that the subfile should be filled completely before presenting the information to the user.
To improve performance, the subfile could be filled with a few records—a page at a time—and then displayed to the user. The code shown in Example 5.117 would replace the DO WHILE loop in the previous example.
Example 5.117: Reading a data file backwards and filling a subfile one page at a time.
.....CSRn01Factor1+++++++<—OpCode(ex)—>Factor2+++++++Result++++++++Len++DcHiLoEq 0020 C dow Funct = 'ROLLDOWN' 0030 C | Eval rrn = 0 0040 C | dow NOT %EOF and RRN <= 20 0050 C | | add 1 RRN 0060 C | | Write CustList 0070 C | | ReadP CustMast 58 0090 C | enddo 0100 C | Exfmt CustPanel 0110 C | exsr RtvMacro 0120 C enddo
In Example 5.117, the DO WHILE loop (line 20) causes the looping processes to occur each time the user presses the ROLLDOWN function key. In addition, only 20 subfile records are written each time this process is performed. (The subroutine RTVMACRO, on line 120, sets the value of the FUNCT field.)
The READPE operation uses the key value specified in factor 1 to sequentially retrieve the prior record from the keyed file specified in factor 2. The READPE operation provides sequential access to records with non-unique keys in descending order ("up" through the file). The full or partial index of the record is equal to the key value specified in factor 1.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
[key value] | READPE (N E) | format name | [error] | [BOF] | ||
[key value] | READPE (N E) | file name | [data structure] | [error] | [BOF] |
See also READ, READE, READP, CHAIN, WRITE, UPDATE, DELETE, and UNLOCK
Factor 1 is optional and can contain the key value for the READPE operation. If factor 1 is blank, the previous record with a key equal to the current record is retrieved. Resulting indicator 3 is set on when a record with an equal key does not exist in the file.
Factor 2 is required and must contain the name of a file or a format of an externally described file. If factor 2 contains a file name, the result field can contain the name of a data structure into which the input data from the file is copied. This option is valid only for program-defined database files.
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | N/A | |
73 – 74 | 2 | [error] | An error occurred during the operation. |
75 – 76 | 3 | [BOF] | Set on when the beginning of the file is reached. |
Extender | Description |
---|---|
E | ERROR - Causes the %ERROR and %STATUS built-in functions to be set if an error occurs during the operation. |
N | NO LOCK - Causes the database record to be read without placing a record lock on the record. This is useful for files that have been open for update operations. |
When a READPE operation fails to read a record, as is the case when the beginning of file is reached, resulting indicator 3 (if specified) and the %EOF built-in function are set on.
The following characteristics apply when a record is accessed with the READPE operation:
For INPUT files, the record is retrieved, but no record locking occurs.
For OUTPUT-only files, this operation is not valid.
For UPDATE files, if no operation extender is specified, the record is retrieved and locked until it is released through one of the following:
Another READ, READE, READP, READPE, or CHAIN operation.
The record is updated by an UPDATE or EXCEPT operation.
The record is deleted by a DELETE or EXCEPT with DEL operation.
The record is implicitly released by one of the following operations:
Except to an empty output format (EXCEPT).
Unlock the record (UNLOCK).
Set lower limit (SETLL).
Set greater than (SETGT).
Force end of data (FEOD).
Close file (CLOSE).
Example 5.118 shows an example of coding the READPE operation.
Example 5.118: Adding the quantity on hand for a specific item number.
.....FFileName++IFEASFRlen+LKeylnKFDevice+.Functions++++++++++++++++++++++++++++ 0010 FITEMMAST IF E K DISK .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0020 C ITEM# KList 0030 C KFld ITEM * Establish the item number to total. 0040 C MoveL(p) 'CEC01' ITEM * Retrieve the last record for the item number 0050 C ITEM# ReadPE ITEMMAST 58 0060 C move *IN58 NotFound 0070 C dow NotFound = *OFF 0080 C add QTYOH ITEMOH * Retrieve previous record containing same item number 0090 C ITEM# ReadPE ITEMMAST 58 0100 C move *IN58 NotFound 0110 C enddo
The REALLOC operation is used to dynamically allocate storage (memory) at runtime. The number of bytes and a pointer variable to which the memory location is returned are passed to the REALLOC operation. Data currently stored at the existing pointer variable address is copied to the newly allocated storage location.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
REALLOC (E) | Length in bytes | Pointer variable | [error] |
See also ALLOC and DEALLOC
Factor 1 is required and must contain a numeric field or literal value. Factor 1 indicates the number of bytes of memory to allocate. The number of bytes that can be allocated must be greater than 0 and less than 16 megabytes (16,776,704). If the number of bytes is outside this limit, status error code 0425 is returned to the %STATUS built-in function.
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | N/A | |
73 – 74 | 2 | [error] | An error occurred during the operation. |
75 – 76 | 3 | N/A |
Extender | Description |
---|---|
E | ERROR - Causes the %ERROR and %STATUS built-in functions to be set if an error occurs during the operation. Status code 0425 is returned if a memory allocation error occurs. Status code 0426 is returned if the existing pointer value is not valid. |
The result field is required and must contain a field of type pointer. This pointer must contain a storage address returned by a previous ALLOC or REALLOC operation. A new memory address is returned to this variable. The storage at the original address is copied to the storage in the new location. Use this operation code to change the size of allocated storage.
In example 5.119, the number of bytes required to allocate 100 array elements is calculated on line 4. Because the %SIZE built-in function returns the number of bytes required for a single array element, it is used in this calculation.
Example 5.119: Reallocating memory based on a calculated value.
.....DName+++++++++++EUDS.......Length+TDc.Functions++++++++++++++++++++++++++++ 0001 D pARR S * 0002 D ARRAY S 5P 0 Dim(5000) Based(pArr) 0003 D nSize S 10i 0 .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq * Allocate 100 elements for the array. 0004 C Eval nSize = %Size(Array) * 100 0005 C ALLOC(E) nSize pArr ** Do something with the array data. ** But be sure not to touch outside the 100 allocated elements. 0006 C Eval nSize = nSize + (%size(Array) * 250) 0007 C ReAlloc nSize pArr ** Do something with the 350 elements now allocated to the array 0008 C DeAlloc(N) pArr 0009 C SetOn LR
Line 5 allocates 300 bytes of memory (100 elements times 3 bytes per element). Line 6 recalculates the number of bytes needed to allocate an additional 250 elements. Line 7 allocates the new memory size. The original pARR value is passed to the REALLOC operation. The storage at the address stored in pARR prior to the first REALLOC operation is copied to the storage at the new location.
If the size of the new storage location is less than the original location, only enough bytes to fill the new storage size are copied. Line 8 returns the storage to the operating system and sets the pARR pointer to null.
The REL operation releases the WORKSTN device ID specified in factor 1. The device ID can be one acquired by the ACQ operation (see the subheading ACQ [Acquire]) or it can be the WORKSTN device running the program.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
workstn device ID | REL | workstn file name | [error] |
See also ACQ
Factor 1 is required and must contain the name—for example, 'DSP12'—of the program device that is released. Factor 1 can be a 10-character field or constant enclosed in apostrophes. Factor 2 is required and must contain the name of the WORKSTN device file that previously has acquired the WORKSTN device ID.
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | N/A | |
73 – 74 | 2 | [error] | An error occurred during the operation. |
75 – 76 | 3 | N/A |
Extender | Description |
---|---|
E | ERROR - Causes the %ERROR and %STATUS built-in functions to be set if an error occurs during the operation. |
In Example 5.120, the acquired program device DSP01 is released from the program on line 80. The field WSID contains the name of the previously acquired device. The MAXDEV keyword for the GLENTRY file (line 10) controls the number of devices that can be acquired for the program.
Example 5.120: Releasing an acquired workstation device.
.....FFileName++IFEASFRlen+LKeylnKFDevice+.Functions++++++++++++++++++++++++++++ 0010 Fglentry CF E WORKSTN MaxDev(*File) .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0030 C 'DSP01' ACQ glentry 56 0040 C *IN56 caseq *ON *PSSR 0050 C endcas 0060 C moveL(p) 'DSP12' WSID 10 0070 C EXFMT PROMPT 0080 C WSID REL GLENTRY 56
The RESET operation changes the value of the variable specified in the result field to its initial value. The RESET operation can be run anywhere in the RPG program except within the *INZSR subroutine or any subroutine that is called by *INZSR.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
RESET | [*ALL] | variable to reset | [error] | |||
[*NOKEY] | RESET | [*ALL] | record format | [error] |
See also: CLEAR and *INZSR
Factor 1 is optional and can be specified only when the result field is a record format for a keyed database file. When a keyed database file is specified, factor 1 can contain the constant *NOKEY. This indicates that the key field values for the record are to be preserved (i.e., not reset) when the record format is reset.
Factor 2 can contain the optional *ALL value. When factor 2 contains *ALL, the result field must contain a data structure, array or table, or workstation device file record format. When a multiple occurrence data structure is specified, all occurrences are reset. When an array or table is specified, all elements are reset. And when a workstation device file record format is specified, all fields (regardless of input/output status) are reset to their initial value.
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | N/A | |
73 – 74 | 2 | [error] | An error occurred during the operation. |
75 – 76 | 3 | N/A |
Extender | Description |
---|---|
E | ERROR - Causes the %ERROR and %STATUS built-in functions to be set if an error occurs during the operation. |
The result field is required and can contain any variable, including a field name, data structure, data structure subfield, record format, array, array element, table, or named indicator.
If the result field contains a record format, the corresponding file must be opened for update, output-only, or combined (input/output) processing. The RESET operation cannot be used on a record format for a file that is opened for input only. Only fields defined as output or input/output are reset. Input-only fields are not reset in the record format.
If the result field contains a multiple occurrence data structure, only the current occurrence of the data structure is reset. If an array is specified, the entire array (every element) is reset. If an array element is specified, such as ARR(3), only that element is reset. When the RESET operation is performed on a data structure, each subfield is reset in order of its appearance in the data structure.
The RESET operation is intended to be used with initial values because it moves the initial value of a variable into the variable. In general, the variable must have been declared within the scope of the routine that contains the RESET operation. For example, when a variable is declared within a subprocedure, the RESET must also appear in that same subprocedure.
Because the RESET operation uses "hidden" storage to reset a field to its initial value, RESET cannot be used on any variable that has been declared with the IMPORT keyword.
When the RESET operation is specified, the compiler allocates storage containing a copy of the variable's initial value. Whenever the RESET operation is performed, the initial value is copied to the variable.
You should note, however, that the default initial value for a data structure subfield (regardless of type) is blank. Therefore, unlike the CLEAR operation, the RESET operation typically moves blanks into data structure subfields unless those subfields have been explicitly initialized.
A specific initial value can be specified by the INZ keyword or within the *INZSR subroutine. Additional storage is allocated containing a copy of the initialized data structure, its subfields, and their initial values. This causes program sizes to be larger than when RESET is not used.
In Example 5.121, the compiler initializes each data structure subfield in the ITEMS data structure (line 10) based on their data type. An exception is the ITEMCHAR subfield. The ITEMCHAR subfield contains its own INZ keyword and is initialized to '0100' (line 50).
Example 5.121: Resetting a data structure.
The *INZSR subroutine (line 100) is called when the program is started. Indicator 88 is set to *ON, making its status *ON, when the main line calculations are entered.
The EVAL operation (line 80) places 9402 into the ITEMNUM subfield.
The RESET operation (line 90) resets the ITEMS data structure and, therefore, all of its subfields based on their data type. When the RESET operation is performed, the subfield ITEMCHAR (which occupies the same positions within the data structure as ITEMNUM) is set to '0100'.
Under this scenario, even if ITEMNUM had some other explicit initial value, the initial value for ITEMCHAR would supersede it because it appears later in the source code than the ITEMNUM field. The initial value for any field, data structure, data structure subfield, array, array element, or indicator is established (logically speaking) after the *INZSR subroutine is performed for the first time. Because data-structure subfield initialization occurs before the *INZSR subroutine is performed, the initial value of a data structure subfield can be overridden by altering the data-structure subfield's value during the *INZSR subroutine.
The RETURN operation returns control to the caller of the program or procedure in which it is used. For programs, if the halt and LR indicators are off when the RETURN is performed, the program is suspended, but remains resident. For subprocedures, the RETURN operation returns control to the caller and optionally returns a value to the caller. Resulting indicators are not valid for this operation.
Factor 1 | OpCode | Extended Factor 2 |
---|---|---|
RETURN (H M R) | return value or expression |
See also *INLR
For RETURN operations to programs, the operation works as follows:
If any halt indicator (H1 to H9) is on, the program ends abnormally.
Extender | Description |
---|---|
H | HALF ADJUST - Any mathematical result from the expression in the result field is calculated using half-adjust (rounding) routines. |
M | Maximum Digits |
R | Result Value Digits |
If indicator LR is on and the halt indicators are off, the program ends normally and returns to the calling program.
If indicator LR is off and the halt indicators are off, the program remains active in memory, but control returns to the calling program. When this condition occurs, open files remain open; fields, data structures, arrays, and indicators retain their value, and the program remains active, but suspended. The next time the program is called, control is transferred to the program much faster than to an inactive program.
When a subprocedure performs a RETURN operation, the value specified in the extended factor 2 is returned to the caller. The value specified on the subprocedure's prototype and procedure interface control the format of the returned value.
In Example 5.122, the RETURN operation (line 100) is used to return to the caller of the program. Also, note the GETINTEREST function on line 80. Example 5.123 illustrates using the RETURN operation to return a value to the caller.
Example 5.122: Returning to caller from a dynamically called program.
.....H.Functions++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 0010 H DatFmt(*ISO) .....DName+++++++++++EUDS.......To/Len+TDc.Functions++++++++++++++++++++++++++++ * prototype for GetInterest procedure 0030 D GetInterest PR 32A ExtProc 0040 D NumInput 30P 4 Value .....DName+++++++++++EUDS.......Length+TDc.Functions++++++++++++++++++++++++++++ 0060 D InvAmt S 7P 0 0070 D Message S 255A .....CSRn01..............OpCode(ex)Extended-factor2+++++++++++++++++++++++++++++ 0080 C Eval Message = 'Amount Due: ' + GetInterest(InvAmt) C* the program continues... 0090 C Eval *INLR = *ON 0100 C RETURN
Example 5.123: Returning a value to the caller with a procedure interface.
.....PProcname+++++++..B...................Functions++++++++++++++++++++++++++++ 0010 P GetInterest B Export .....DName+++++++++++EUDS.......To/Len+TDc.Functions++++++++++++++++++++++++++++ 0020 D GetInterest PI 32A 0030 D NumInput 30P 4 Value 0040 D Interest S 30P 4 0050 D RATE C Const(.12) 0060 D CharVal S 32A .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0070 C If NumInput = 0 0080 C RETURN '0' 0090 C EndIf 0100 C eval Interest = NumInput * Rate 0110 C evalR CharVal = %Char(Interest + NumInput) 0120 C RETURN CharVal .....PProcname+++++++..B...................Functions++++++++++++++++++++++++++++ 0130 P GetInterest E
In Example 5.123, the procedure GETINTEREST is defined. The procedure interface (line 20) indicates that a 32-byte character value must be returned to the caller of this procedure. Lines 100 and 110 build a value that is returned to the caller by the RETURN operation on line 120. This is the GETINTEREST procedure that is called by the EVAL operation on line 80 in Example 5.122.
The ROLBK operation is a relational database management function. It performs the rollback function of the relation model by abandoning all changes made to files since the prior COMMIT or ROLLBACK operation.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
ROLBK (E) | [error] |
See also COMMIT.
The ROLLBACK and COMMIT operations are performed on all files that are under commitment control for a process (i.e., job), regardless of whether they are actually defined in the program performing the ROLBK or COMMIT operation.
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | N/A | |
73 – 74 | 2 | [error] | An error occurred during the operation. |
75 – 76 | 3 | N/A |
Extender | Description |
---|---|
E | ERROR - Causes the %ERROR and %STATUS built-in functions to be set if an error occurs during the operation. |
In Example 5.124, the COMMIT keyword (line 10) specifies that the CUSTMAST file is under commitment control. Line 20 issues the ROLBK operation, causing all changes made to the CUSTMAST file—since the previous commit or rollback operation—to be abandoned.
Example 5.124: Rolling back a file under commitment control.
.....FFileName++IFEASFRlen+LKeylnKFDevice+.Functions++++++++++++++++++++++++++++ 0010 FCUSTMAST UF E DISK COMMIT('1') .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0020 C 'REGION6' DELETE(E) CUSTMAST 0030 C If NOT %ERROR 0040 C ROLBK(E) 0050 C endif
The SCAN operation scans the character variable or array specified in factor 2 for the argument specified in factor 1. If the argument is found, the position of the first character of the argument is returned to the result field. If a numeric array is specified as the result field, each occurrence of the argument found in factor 2 is returned in a corresponding array element. A successful result of a SCAN operation can be checked using any of the following three techniques:
The result field (if specified) will contain a value greater than zero.
Resulting indicator 3 (if specified) will be equal to *ON.
The %FOUND built-in function will be equal to *ON.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
argument[:length] | SCAN(E) | search var[:start] | [position(s)] | [error] | [found] |
See also LOOKUP, %FOUND, and %SCAN
Factor 1 is required and must contain a field, data structure, data structure subfield, array element, constant, or named constant that contains the search argument.
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | N/A | |
73 – 74 | 2 | [error] | An error occurred during the operation. |
75 – 76 | 3 | [FOUND] | The SCAN operation located the data specified in factor 1 in the variable specified in factor 2. |
Factor 1 has one optional parameter: ARGUMENT-LENGTH. This parameter is separated from the argument in factor 1 by a colon (:). This parameter indicates how many characters of the search argument can be used for the scan. The ARGUMENT-LENGTH parameter can be any valid numeric value. The ARGUMENT-LENGTH must be greater than 0 and less than or equal to the length of the search argument. If the ARGUMENT-LENGTH parameter is omitted, the entire search argument is used.
Extender | Description |
---|---|
E | ERROR - Causes the %ERROR and %STATUS built-in functions to be set if an error occurs during the operation. |
Factor 2 is required and must contain the value to be scanned. Factor 2 can be any valid data type except a figurative constant. Factor 2 has one optional parameter: START-POSITION. Separated from the entry in factor 2 by a colon (:), this parameter indicates the starting position of the scan within the scan data. If the START-POSITION parameter is omitted, the starting position for the scan is 1.
The result field is optional and can contain a numeric variable that receives the position of the left-most character of the search argument within the scan data. If a numeric array is specified, each occurrence of the search argument within the scan data is stored in a corresponding array element.
If the search argument is not found, the result field is set to zero. If the result field contains an array, each array element is set to zero. If the result field is not specified, resulting indicator 3 is required unless the %FOUND built-in function is used. See Example 5.125.
Example 5.125: Finding a search argument in a character variable.
.....FFileName++IFEASFRlen+LKeylnKFDevice+.Functions++++++++++++++++++++++++++++ FQRPGSRC IF F 112 DISK .....DName+++++++++++EUDS.......To/Len+TDc.Functions++++++++++++++++++++++++++++ D Len S 10I 0 D StrPos S 10I 0 Inz(1) D POS S 10I 0 D Counter S 5I 0 .....IName++++++NS1OINPos1+NCVPos2+NCVPos3+NCV IQRPGSRC NS .....I........................Fmt+/TFrom+To+++D+Field+++++++++L1M1FRPLMNZB I 13 112 SRCDTA .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq ** Scan argument. C MOVEL 'DISK' Pattern 45 ** Argument length. C Eval Len = %TRIMR(Pattern) ** Search each record in an RPG source member for the word 'DISK'. C READ QRPGSRC C DOW NOT %EOF * Scan the source record for the argument 'DISK'. C Pattern:Len SCAN SRCDTA:StrPos Pos * Count how many times the work DISK is used in the program. C IF Pos > 0 C Eval StrPos = Pos C ADD 1 Counter C EndIf C READ QRPGSRC C ENDDO
The SELECT operation is used to begin an in-line case group. In-line case groups contain one or more WHENxx operations and an optional OTHER operation. The SELECT and ENDSL operations define the scope of the in-line case group.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
SELECT |
See also WHEN, OTHER, and ENDSL.
The SELECT operation must be followed immediately by one or more WHEN operations. Both forms of WHEN are supported by the SELECT operation. An in-line case group is defined by either the SELECT/WHEN/OTHER/ ENDSL case group or the IF/ELSE/ENDIF operations.
The SELECT/WHEN/OTHER/ENDSL operations require only one ENDSL operation for the entire case group. The IFxx operation requires one ENDIF operation for each IFxx operation. The WHEN operation incorporates an implicit ELSE-like operation. A sequential ELSE and IFxx sequence provides function similar to the WHENxx operation.
The OTHER operation is the functional equivalent of the "catch all" or "final" ELSE operation of an IFxx/ELSE/ENDIF group. If the previous WHEN statement condition is not satisfied, the statements following the OTHER (Otherwise) operation are performed. Any RPG operation, except BEGSR and ENDSR, can be specified within an in-line case group, including another in-line case group.
In Example 5.126, the READ operation on line 1 reads a record from the orders file. Then, the SELECT group is entered. The WHEN operation (line 3) checks for end of file. If the end-of-file indicator is on, subroutine ALLDONE is performed, and then control transfers to the ENDSL operation (line 13).
Example 5.126: Using a SELECT statement to delimit an in-line case group.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0001 C Read ORDERS 0002 C SELECT 0003 C When %EOF 0004 C exsr AllDone 0005 C When Region = MIDWEST 0006 C add Amount MWSALE 0007 C When Region = CENTRAL 0008 C add Amount CTSALE 0009 C When Region = WESTERN 0010 C add Amount WCSALE 0011 C Other 0012 C add Amount HQSALE 0013 C EndSl
If the test performed by the WHEN operation on line 3 is false, control passes to the next WHEN operation to perform its test. This continues until a WHEN test is true. Then the statements associated with the WHEN operation are performed. If none of the tests of the WHEN operations are true, control passes to the default routine associated with the OTHER operation.
The SETGT operation positions the file specified in factor 2 to the record that is greater than the index or relative record number specified in factor 1. The file's data is not returned to the program by this operation.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
key value | SETGT (E) | file name | [n/f] | [error] | ||
key value | SETGT (E) | format name | [n/f] | [error] |
See also SETLL, READ, READE, READP, READPE, CHAIN, and %FOUND
Factor 1 is required and must contain a record index or a record number. The key value or record number is used to position the file so that a subsequent READ operation retrieves records with a key value or relative record number greater than factor 1. A subsequent READP operation retrieves the previous record in the file. Factor 2 is required and must contain a full procedural file name or an externally described file's format name.
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | [n/f] | No records were found matching the index value in factor 1. |
73 – 74 | 2 | [error] | An error occurred during the operation. |
75 – 76 | 3 | N/A |
Extender | Description |
---|---|
E | ERROR - Causes the %ERROR and %STATUS built-in functions to be set if an error occurs during the operation. |
The %FOUND built-in function is set to *ON when the SETGT operation successfully locates a record in the file with an index greater than the value specified in factor 1.
In Example 5.127, the file CUSTMAST is positioned to the index value that is greater than 'C999999'. If the end-of-file indicator is set on, the file is repositioned by the SETLL operation to beginning of file.
Example 5.127: Positioning a file with SETGT.
.....FFileName++IFEASFRlen+LKeylnKFDevice+.Functions++++++++++++++++++++++++++++ 0010 FCUSTMAST IF E DISK .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0020 C 'C999999' SETGT CUSTMAST 0030 C If NOT %FOUND 0040 C *LOVAL Setll CUSTMAST 0050 C EndIf
The SETLL operation positions the full procedural file specified in factor 2 to the record that is greater than or equal to the index or relative record number specified in factor 1. A subsequent READ operation retrieves the next record in the file; a subsequent READP operation retrieves the previous record in the file. The file's data is not returned to the program with this operation.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
key value | SETLL (E) | file name | [n/f] | [error] | [equal] | |
key value | SETLL (E) | format name | [n/f] | [error] | [equal] |
See also SETGT, READ, READE, READP, READPE, CHAIN, %FOUND, and %EQUAL
Factor 1 is required and must contain an index value (field, literal value, figurative constant, or key list) or a relative record number. The value of the index or relative record number is used to position the file so that a subsequent READ operation retrieves the record with an index value or relative record number greater than or equal to factor 1. Factor 2 is required and must contain the name of a full procedural file or externally described, file-record format.
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | [n/f] | The key value in factor 1 is greater than the highest corresponding key value in the file. The file cursor is positioned to end of file. |
73 – 74 | 2 | [error] | An error occurred during the operation. |
75 – 76 | 3 | [equal] | A key exists in the file that equals the key value specified in factor 1. |
The %FOUND built-in function is set to *ON when the SETLL operation successfully locates a record in the file with an index less than or equal to the value specified in factor 1. The %EQUAL built-in function is set to *ON when the SETLL operation successfully locates a record in the file with an index exactly equal to the value specified in factor 1.
In Example 5.128, the file CUSTMAST is positioned to the 22nd relative record number (line 20). If relative record number 22 exists in the file CUSTMAST, resulting indicator 3 (indicator 58) is set on and subroutine GETREC (Get Record) is performed (line 30).
Example 5.128: Positioning a file with SETLL.
.....FFileName++IFEASFRlen+LKeylnKFDevice+.Functions++++++++++++++++++++++++++++ 0010 FCUSTMAST IF E DISK .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0020 C 22 SETLL CUSTMAST 58 0030 C *IN58 CASEQ *ON GetRecord 0040 C EndCS 0050 C*... the program continues...
If relative record number 22 doesn't exist, but relative record number 23 does, the file is positioned to relative record 23 and resulting indicator 3 (indicator 58) is not set on. Graphically, if the file is positioned to relative record number 22 using SETLL, the file cursor is positioned between records 21 and 22. See Figure 5.7.
Cursor Location | Record Number |
---|---|
19 | |
20 | |
21 | |
| |
22 | |
23 | |
24 |
As shown in Figure 5.7, the SETLL operation from Example 5.128 positions the file cursor after record 21 and before record 22. A subsequent READ operation retrieves record 22; a subsequent READP operation retrieves record 21.
The SETOFF operation sets off (i.e., sets to '0') the indicator(s) specified in the resulting indicators. At least one resulting indicator must be specified.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
SETOFF | [ind1] | [ind2] | [ind3] |
See also SETON, MOVE, MOVEL, and EVAL
Resulting indicators 1, 2, and 3 are optional, but at least one must be specified. The resulting indicator(s) specified is set off. The SETOFF operation performs the equivalent of a MOVE '0' or MOVE *OFF operation to a named indicator variable or an EVAL operation that has an indicator variable as its l-value. When indicators are set to one ('1'), they are considered on. When they are set to zero ('0'), they are off. The figurative constant *ON is the same as '1' and the figurative constant *OFF is the same as '0'.
In Example 5.129, line 10 sets off indicators 54, 56, and 58. Line 20 sets off indicators 01 and 02. Because the SETOFF operation is functionally equivalent to a MOVE operation to a named indicator variable, lines 30, 40, and 50 perform the same function as line 10. Line 60 uses the MOVEA operation with the indicator array to set off indicators 01 and 02; this is the equivalent of line 20. Line 70 uses the EVAL operation to set off indicator 33 and line 80 sets indicator LR to the opposite setting of indicator 15.
Example 5.129: Setting off various indicators.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C SETOFF 545658 0020 C SETOFF 01 02 0030 C MOVE '0' *IN54 0040 C MOVE *OFF *IN56 0050 C MOVE '0' *IN,58 0060 C MOVEA '00' *IN,01 0070 C Eval *IN33 = *OFF 0080 C Eval *inlr = NOT *IN15
The SETON operation sets on (i.e., sets to '1') the indicator(s) specified in the resulting indicators. At least one resulting indicator must be specified.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
SETON | [ind1] | [ind2] | [ind3] |
See also SETON, MOVE, MOVEL, and EVAL.
Resulting indicators 1, 2, and 3 are optional, but at least one must be specified. The resulting indicator(s) specified is set on. The SETON operation performs the equivalent of a MOVE '1' or MOVE *ON operation to a named indicator variable or an EVAL operation that has an indicator variable as its l-value. When indicators are set to one ('1'), they are considered on. When they are set to zero ('0'), they are off. The figurative constant *ON is the same as '1' and the figurative constant *OFF is the same as '0'.
In Example 5.130, line 10 sets on indicators 54, 56, and 58. Line 20 sets on indicators 01 and 02. Because the SETON operation is functionally equivalent to a MOVE operation to a named indicator, lines 30, 40, and 50 perform the same function as line 10. Line 60 uses the MOVEA operation to the indicator array to set on indicators 01 and 02; this is the equivalent of line 20. Line 70 uses the EVAL operation to set on indicator 33.
Example 5.130: Setting on various indicators.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C SETON 545658 0020 C SETON 01 02 0030 C MOVE '1' *IN54 0040 C MOVE *ON *IN56 0050 C MOVE '1' *IN,58 0060 C MOVEA '11' *IN,01 0070 C Eval *IN33 = *ON
The SHTDN operation tests for a system shutdown request. This can be any function that requests the program to end, including, but not limited to, system power down and an end-session request. Note: The SHTDN operation is obsolete and should be phased out of existing applications.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
SNTDN | label | true |
See also %SHTDN, RETURN and *INLR
Resulting indicator 1 is required and is set on if the shutdown test is successful. Specifically, it is set on when session shutdown has been requested.
The SHTDN operation will set on resulting indicator 1 when one of the following AS/400 commands have been issued: PWRDWNSYS, ENDJOB, SIGNOFF, or ENDSBS.
In Example 5.131, the program normally ends with the LR indicator off. This would leave the program suspended, but resident. However, when session shutdown has been requested, indicator LR is set on (line 50), causing the program to be removed from memory when it returns to its caller (line 60).
Example 5.131: Testing for a session shutdown request.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C *ENTRY PLIST 0020 C PARM TIME 6 0 0030 C TIME TIME 0040 C ENDPGM TAG 0050 C SHTDN LR 0060 C RETURN
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | True | A shut down request has been detected by the operation. |
73 – 74 | 2 | N/A | |
75 – 76 | 3 | N/A |
The SORTA operation arranges an array in the order specified by the ASCEND or DESCEND keywords on the array's definition specification.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
SORTA | Array name |
See also LOOKUP
Factor 2 is required and must contain the name of the array that is sorted. The indicator array *IN cannot be sorted. If the array being sorted has an associated alternate array, the alternate array is not sorted.
The SORTA operation supports both ascending and descending sorting. Specify the ASCEND keyword for the array (on the definition specification) to sort in ascending order. Specify the DESCEND keyword to sort the array in descending order. If neither ASCEND nor DESCEND is specified, the array is sorted in ascending order.
In Example 5.132, the four-element, compile-time array LETTER (line 10) is initialized to DCAB when the program is started. The SORTA operation (line 20) sorts the array LETTER in ascending order.
Example 5.132: Sorting the array ALPHA in ascending order.
.....DName+++++++++++EUDS.......Length+TDc.Functions++++++++++++++++++++++++++++ 0010 D Letter S 1A Dim(4) CTDATA PerRcd(4) .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0020 C SORTA LETTER 0030 C MOVE *ON *INLR **CTDATA LETTER DCAB
Before SORTA
D,C,A,B
After SORTA
A,B,C,D
The SQRT operation calculates the square root of the value specified in factor 2 and places the result into the result field. The EVAL operation supports the square root function in a much easier format. See the subheading EVAL (Evaluate an Expression) for more information.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
SQRT(H) | numeric value | square root |
See also ADD, SUB, MULT, DIV, and EVAL.
Factor 2 is required and must contain a numeric field, literal value, array, or array element. The square root of the value in factor 2 is placed in the result field. The value specified in factor 2 must be greater than or equal to zero. If factor 2 is less than zero, the exception/error routine is called. If factor 2 is an array, the result field must also be an array because the square root of each element is placed into the corresponding element in the array specified in the result field.
Extender | Description |
---|---|
H | HALF ADJUST - Causes the result value to be rounded. |
The result field is required and must contain the name of a numeric field, array, or array element that receives the square root of the value specified in factor 2.
In Example 5.133, the field VALUE is initialized to 16 (line 10). On line 20, the square root of the field VALUE is calculated (4) and placed into the result field ANSWER. As an alternative, the square root of a number can be calculated using natural expression support (line 30).
Example 5.133: Calculating the square root of a value.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C Z-add 16 Value 3 0 0020 C SQRT Value Answer 7 5 0030 C Eval Answer = Value ** (1/2)
The SUB operation is used to produce the difference of two values. Factor 2 is subtracted from factor 1 (long form); the difference is placed into the result field.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
[minuend] | SUB(H) | subtrahend | difference | [+] | [-] | [0] |
See also ADD, MULT, DIV, SQRT, and EVAL
Factor 1 is optional and, if specified, it is used as the basis for the subtraction. In other words, factor 2 is subtracted from factor 1. This is known as a long-form subtract. If factor 1 is omitted, factor 2 is subtracted from the current value of the result field. The difference replaces the value of the result field. This is known as a short-form subtract.
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | [ + ] | The result field is greater than zero. |
73 – 74 | 2 | [ - ] | The result field is less than zero. |
75 – 76 | 3 | [ 0 ] | The result field is equal to zero. |
Extender | Description |
---|---|
H | HALF ADJUST - Causes the result value to be rounded up to the nearest decimal position. |
Factor 2 is required and is subtracted from factor 1, if specified, or from the current value of the result field if factor 1 is omitted. The result field is required. The result of the SUB operation (the difference) is stored in the result field.
Example 5.134, if written in traditional mathematical expressions, would read as follows:
A - B = C C - 1 = C
Example 5.134: Subtracting factor 2 from factor 1 and then decrementing the result.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C A SUB B C 5 0 0020 C SUB 1 C 545658
In Example 5.134, field B is subtracted from field A (line 10) and the difference is stored in field C. Then field C is decremented by 1 (line 20).
After the second SUB operation (line 20) is performed, if field C is greater than zero (i.e., a positive number), resulting indicator 1 (indicator 54) is set on. If field C is less than zero (i.e., negative), resulting indicator 2 (indicator 56) is set on. If field C equals zero, resulting indicator 3 (indicator 58) is set on.
In Example 5.135, each element of the ARR1 array has 3 subtracted from it (line 40), and it is placed into the corresponding element in the DIFF array. On line 50, each element of ARR2 array is subtracted from the corresponding element of ARR1 array, and the difference is placed into the corresponding elements of DIFF array. On line 60, the constant 5 is subtracted from each element of the DIFF array. On line 70, the 5th element of the ARR2 array is subtracted from the 4th element of the ARR1 array. The difference is placed into the ANSWER field.
Example 5.135: Illustrating array handling with the SUB operation.
.....DName+++++++++++EUDS.......Length+TDc.Functions++++++++++++++++++++++++++++ 0010 D Arr1 3S 0 Dim(5) 0020 D Arr2 3S 0 Dim(5) 0030 D Diff 3S 0 Dim(5) .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0040 C Arr1 SUB 3 Diff 0050 C Arr1 SUB Arr2 Diff 0060 C SUB 5 Diff 0070 C Arr1(4) SUB Arr2(5) Answer 3 0
The SUBDUR operation code can be used to calculate a new date or calculate the period between two dates. SUBDUR has all the function of ADDDUR, plus the capability to calculate a period between two date values.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
date value | SUBDUR (E) | date value | duration : dur code | [error] | [0] | |
[date value] | SUBDUR (E) | duration: :dur code | resulting date | [error] |
See also ADDDUR, EXTRCT, TEST, and MOVE
To calculate the period between two date or time values, specify the starting date or time value in factor 1 and the ending date or time value in factor 2. The result field receives the duration between the two values. Use the duration code parameter in the result field to indicate the type of duration you want. For a list of valid duration codes, see Table 5.4.
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | N/A | |
73 – 74 | 2 | [ error ] | An error occurred during the operation. |
75 – 76 | 3 | N/A |
Extender | Description |
---|---|
E | ERROR - Causes the %ERROR and %STATUS built-in functions to be set if an error occurs during the operation. |
To calculate a new date, specify the starting date in factor 1, and the period to be subtracted from this date (i.e., the duration) in factor 2. Specify the duration code parameter in factor 2 to indicate the type of duration you want to subtract.
Note | The duration can be a negative value, effectively performing the same function as the ADDDUR operation code. |
If factor 1 is not specified, the date value in the result field is used as the starting date. In the result field, specify a date or time variable that receives the result of the operation.
In Example 5.136, today's date is moved into the TODAY field (line 50). The special date format *JOBRUN is used in factor 1 to indicate the format for the *DATE field. Line 70 uses the SUBDUR operation to subtract the DUEDATE value from today's date. The number of days since the due date is stored in PASTDUE. Note the use of the *DAYS duration code.
Example 5.136: Using SUBDUR to calculate past-due invoices.
.....DName+++++++++++EUDSFrom+++To/Len+TDc.Functions++++++++++++++++++++++++++++ 0010 D DueDate S D INZ(D'1996-02-17') 0020 D Today S D .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0040 * Convert today's date to a date data-type field. 0050 C *JOBRUN MOVE *DATE ToDay 0060 * Calculate the number of days past-due. 0070 C ToDay SubDur DueDate PastDue:*DAYS 3 0 0080 C if PastDue > 30 0090 * TODO: insert code for past due invoices here. 0100 C endif
Example 5.137 shows how to use SUBDUR to calculate durations and dates.
Example 5.137: Using SUBDUR to calculate various durations and new dates.
.....DName+++++++++++EUDSFrom+++To/Len+TDc.Functions++++++++++++++++++++++++++++ 0010 D DayOne S D INZ(D'1900-01-01') 0020 D NextCent S D INZ(D'2000-01-01') 0030 D ToDay S D 0040 D ClockIn S T INZ(T'07:00:00') 0050 D ClockOut S T INZ(T'16:30:00') 0060 D LoanDue S D INZ(D'2020-07-04') .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq * Number of days months, weeks, and years since first day of 19th century. 0100 C NextCent SubDur DayOne Days:*Days 5 0 0110 C Days Div 7 Weeks 5 0 0120 C NextCent SubDur DayOne Months:*Months 5 0 0130 C NextCent SubDur DayOne Years:*Years 3 0 * Number hours and minutes worked this week 0150 C ClockIn SubDur ClockOut Hours:*H 3 0 0160 C ClockIn SubDur ClockOut Mins:*MN 5 0 * Set a loan's due date back by 15 years. 0180 C SubDur 15:*Years LoanDue
The SUBST operation copies a portion of the value in factor 2 to the result field.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
[length] | SUBST (P E) | source [:start] | target | [error] |
See also MOVE, MOVEL, CAT, EVAL, and %SUBST
Factor 1 is optional and can contain the length for the substring. Factor 1 can be a numeric field, data structure subfield, array element, or constant. If factor 1 is omitted, the length is automatically calculated by the operation; the length is calculated through the end of the variable specified in factor 2.
Factor 2 is required and must contain a character field, data structure, data-structure subfield, array, array element, or constant that is copied.
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Indy | Usage | Set-On Condition |
71 – 72 | 1 | N/A | |
73 – 74 | 2 | [ error ] | An error occurred during the operation. |
75 – 76 | 3 | N/A |
Extender | Description |
---|---|
P | PAD - Causes the result field to be cleared before the subst operation is performed. |
E | ERROR - Causes the %ERROR and %STATUS built-in functions to be set if an error occurs during the operation. |
Factor 2 has one optional parameter: START-POSITION. This parameter is separated from the entry in factor 2 by a colon (:). START-POSITION indicates the starting position for the substring. If the START-POSITION parameter is omitted, the starting position for the substring is 1. START-POSITION can be a literal value, named constant, numeric field, or numeric data-structure subfield.
The result field is required and must contain a character field, data structure, data structure subfield, array element, or table name. If no operation extender is specified and the substring length is less than that of the result field, the field is moved, left justified, into the result. Any data in the result field that is not overlaid by the substring is unchanged.
The %SUBST built-in function performs the same function as the SUBST operation. However, %SUBST also can be used by the EVAL statement and with conditional expressions.
The SUBST operation is useful when a value needs to be separated from within a field. Traditional RPG programming would dictate moving a value into an array, and then using that array to select the substring value for the field. The SUBST operation eliminates the need for most array-handling techniques for non-array fields, array elements, data structures, and data-structure subfields.
In Example 5.138, the SCAN operation locates the first blank after the first name (line 10). That value is used to calculate the length of the first name (line 30). The SUBST operation is used to extract the first name from NAME (line 40). In addition, the first character of the last name is located (lines 50 to 110) and the last name is extracted. The result of this process is the following:
*...v ...1... v ...2... v FIRST = 'Robert ' LAST = 'Kennedy '
Example 5.138: Using SUBST with SCAN to split a name into first and last names.
.....DName+++++++++++EUDS.......To/Len+TDc.Functions++++++++++++++++++++++++++++ D Name S 30 INZ('Robert Kennedy') D Len S 5P 0 D Pos S 5P 0 .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq * Find the first blank following the first name 0010 C *BLANK:1 SCAN NAME POS 0020 C If POS > 1 * Subtract 1 from the position to compute its length 0030 C Eval Len = Pos - 1 * Pull out the first name 0040 C LEN SUBST(p) NAME:1 FIRST 25 0050 C CLEAR POS * Locate the first non-blank character of the last name 0060 C *BLANK CHECK NAME POS 0070 C If POS > 0 * Compute the remaining length as the (field length of Name) - POS 0080 C eval Len = %Size(Name) - POS * Pull out the last name 0090 C LEN SUBST(p) NAME:Pos Last 25 0100 C EndIf 0110 C EndIf
The TAG operation defines a label. A label can be used as the target of a GOTO or CABxx operation. A TAG can be specified anywhere in the program. Conditioning indicators are not valid for this operation. Resulting indicators are not valid for this operation.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
label | TAG |
See also LABEL, ENDSR, GOTO, and CABxx
Factor 1 is required and must contain a label name of up to six characters. The label must be unique—that is, no other field, array, data structure, data structure subfield, or subroutine can have the same name as a TAG label.
The label is specified in factor 2 of the GOTO operation and in the result field of the CABxx operation. More than one GOTO and CABxx operation can branch to the same label. Factor 1 of an ENDSR operation also can function as a target of a GOTO or CABxx operation, and has restrictions similar to the TAG operation.
In Example 5.139, the CABEQ (Compare and Branch Equal) operation (line 20) branches to the label ENDPGM (line 501) when the end of file is detected (i.e., the READ operation on line 10 sets on the LR indicator).
Example 5.139: Branching to a label when end of file is detected.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C READ CUSTMAST LR 0020 C *INLR CABEQ *ON ENDPGM xxxx C*.... additonal user-code goes here. 0501 C ENDPGM TAG 0502 C RETURN
TEST verifies the contents of the result field. Verification is performed based on the operation extender. A valid date, time, or timestamp value can be tested with the TEST operation.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
l[date format[sep]] | TEST (D E) | date variable | [error] | |||
[time format[sep]] | TEST (T E) | time variable | [error] | |||
[*ISO | *ISO0] | TEST (Z E) | timestamp variable | [error] | |||
TEST (E) | date/time/timestamp | [error] |
See also EXTRCT, SUBDUR, and ADDDUR
Factor 1 is optional and identifies the date or time format of the value in the result field. Factor 1 can be used when the field being tested (the result field) is either a character or numeric field. Factor 1 cannot be specified when the result field contains an actual date, time, or timestamp variable.
The result field can contain a date, time, timestamp, character, or numeric field. When a character or numeric field is specified for the result field, an operation extender must be used to indicate the kind of testing being formed. In addition, an optional format code can be specified in factor 1.
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | N/A | |
73 – 74 | 2 | [ error ] | An error occurred during the TEST operation. The result field's value did not pass the format test for the type of data indicated by the operation extender. |
75 – 76 | 3 | N/A |
Resulting indicator 2 is set on when the TEST operation fails (when the result field contains an invalid date, time, or timestamp value).
There are three operation extenders that control the TEST operation. An operation extender must be specified when the result field contains either a character or numeric variable. The valid operation extenders are described as follows:
Extender | Description |
---|---|
E | ERROR - Causes the %ERROR built-in function to be set on if the result field fails the TEST operation. This operation extender can be used in place of resulting indicator 2, and can be specified along with any one of the other operation extenders. |
D | DATE TEST - Checks the value in the result field for a valid date format. The date format code can be specified in factor 1. If factor 1 is blank, the date format specified for the DATFMT keyword on the header specification is used. If no DATFMT keyword is specified, then *ISO is the default date format code. |
T | TIME TEST - Checks the value in the result field for a valid time format. The time format code can be specified in factor 1. If factor 1 is blank, the time format specified for the TIMFMT keyword on the header specification is used. If no TIMFMT keyword is specified, then *ISO is the default time format code. |
Z | TIMESTAMP TEST - Checks the value in the result field for a valid timestamp format. The timestamp format code can be specified in factor 1 as *ISO or *ISO0. If no timestamp format code is specified, then *ISO is the default timestamp format. |
In Example 5.140, line 10 tests the INVDATE field (which is a DATE variable) for a valid date. If the date is valid, the date is moved into a six-digit numeric field named ORDDTE. ORDDTE is a field used in the database record ORDREC (line 60). To be certain ORDDTE contains a valid date in Month-Day-Year format, a second TEST operation is performed on that field (line 40). If the field is invalid, an error routine is called and the database record is not written out.
Example 5.140: Testing for various date values.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C Test InvDate 0020 C If NOT %ERROR 0030 C *MDY Move InvDate ORDDTE 6 0 0040 C *MDY Test(DE) ORDDTE 56 0050 C If NOT %ERROR 0060 C Write OrdRec 0070 C else 0080 C CallB 'DateError' 0090 C EndIf 0100 C EndIf
The TESTB operation compares the bits specified in factor 2 to the result field. Bits that are not referenced in factor 2 go untested in the result field.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
TESTB | 'bits to test' | 1-byte char variable | [xor] | [mix] | [equal] |
See also TEST, BITON, BITOFF, TESTN, and TESTZ
Factor 2 is required and must contain one of the following: a bit number or numbers, a 1-byte character field, or a 1-byte hexadecimal literal. The bit configuration in factor 2 is compared to the bit configuration of the result field.
The result field is required and must contain a 1-byte character variable. At least one resulting indicator must be specified for this operation. If factor 2 contains only one bit, then resulting indicator 2 cannot be specified.
There are eight bits in an EBCDIC byte. When addressing a bit with a TESTB operation, the bits are numbered from the top down as 0 through 7. Unofficially referred to as nibbles, the bits are grouped into two logical units—the top half and bottom half. Their numeric value is reversed (the value of bit 0 is 8, the value of bit 7 is 1, as follows):
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | [xor] | All the bits specified in factor 2 are off in the result field. |
73 – 74 | 2 | [mixed] | Mixed bit matching between factor 2 and the result field. |
75 – 76 | 3 | [equal] | All the bits specified in factor 2 are on in the result field. |
Bit | Value |
---|---|
0 | 8 |
1 | 7 |
2 | 6 |
3 | 5 |
4 | 4 |
5 | 3 |
6 | 2 |
7 | 1 |
Because RPG is written horizontally, addressing bits vertically would be awkward. Therefore, RPG uses a horizontal method of addressing bits, as follows:
Bit Number 0123 4567
Bit Value 8421 8421
Remember that bits can be either on or off (they are equal to X'1' or X'0' respectively). When a bit is on, it is equal to X'1' and represents the value for its bit number. When a bit is off, it is equal to X'0' and represents a value of zero. For example, if bits 5 and 7 are on and all the other bits are off, the byte is represented as a hex value of X'05', a binary value of B'00000101', and a numeric value of 5.
In Example 5.141, the bit pattern in factor 2 is different than the result field (line 10). Only resulting indicator 2 (indicator 56) is set on. On line 20, bits 1, 2, and 7 are tested, and the bits that are on in FIELDA are on in FIELDB. Therefore, only resulting indicator 3 (indicator 58) is set on. On line 30, all of the bits specified in factor 2 are off in the result field. Therefore, resulting indicator 1 (indicator 54) is set on.
Example 5.141: Testing various field bit values.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C TESTB '127' FIELDA 545658 0020 C TESTB FIELDA FIELDB 545658 0030 C TESTB '026' FIELDA 54 58
Bit Number | 0123 4567 |
---|---|
Bit pattern for FIELDA | 0100 0001 |
Bit pattern for FIELDB | 0101 1101 |
The TESTN operation tests the value of the result field for valid zoned numeric data. At least one resulting indicator must be specified for this operation.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
TESTN | char variable | [num] | [mix] | [blank] |
See also TEST, TESTZ, and TESTB
The result field is required and must be a character variable. The content of the result field is tested for numeric data and resulting indicators are set on accordingly. Except when the result field is blank, no resulting indicators are set on when the result field contains invalid numeric data.
Numeric data in the result field can be positive or negative. If the data is negative, the right-most character of the result field contains the letters J to R.
In Example 5.142, the TESTN operation on line 50 sets on resulting indicator 1. The TESTN operation on line 60 sets on resulting indicator 2. The TESTN operation on line 70 sets on resulting indicator 3. The TESTN operation on line 80 sets on no resulting indicators because FLDD doesn't contain valid numeric data.
Example 5.142: Illustrating the TESTN operation.
.....DName+++++++++++EUDS.......Length+TDc.Functions++++++++++++++++++++++++++++ 0010 D FieldA S 5A INZ('12345') 0020 D FieldB S 5A INZ(' 345') 0030 D FieldC S 5A INZ(*BLANKS) 0040 D FieldD S 7A INZ('400 Q38') .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0050 C TESTN FieldA 545658 0060 C TESTN FieldB 545658 0070 C TESTN FieldC 545658 0080 C TESTN FieldD 545658
Resulting Indicator Legend | |||
---|---|---|---|
Columnsa | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | [num] | All the characters in the result field are numeric. |
73 – 74 | 2 | [mixed] | The result field is numeric with one or more leading blanks. |
75 – 76 | 3 | [blank] | The result field contains blanks. |
The TESTZ operation tests the zone of the left-most character of the result field. At least one resulting indicator must be specified with this operation.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
TESTZ | char variable | [+] | [-] | [other] |
See also TEST, TESTN, and TESTB.
The result field is required and must contain a character variable. The zone of the left-most character of the result field is tested.
In Example 5.143, the TESTZ operation on line 10 sets on resulting indicator 1 (indicator 54). The TESTZ operation on line 20 sets on resulting indicator 2 (indicator 56). The TESTZ operation on line 30 sets on resulting indicator 3 (indicator 58).
Example 5.143: Illustrating the TESTZ operation.
.....DName+++++++++++EUDS.......Length+TDc.Functions++++++++++++++++++++++++++++ 0010 D FieldA S 5A INZ('ABCDE') 0020 D FieldB S 5A INZ('0200J') 0030 D FieldC S 5A INZ(*BLANKS) .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C TESTZ FIELDA 545658 0020 C TESTZ FIELDB 545658 0030 C TESTZ FIELDC 545658
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | [ + ] | The right-most character of the result field contains an ampersand (&), the letter A to I, or any character with the same zone as the letter A. |
73 – 74 | 2 | [ - ] | The right-most character of the result field contains a minus sign (-), the letters J to R, or any character with the same zone as the letter J. |
75 – 76 | 3 | [other] | The right-most character contains a value that is not represented by either resulting indicator 1 or 2. |
The TIME operation retrieves the system time and, optionally, the system date. The retrieved time is stored in the result field. The length of the result field determines whether TIME returns only the system time or the system time and system date.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
TIME | numeric variable | |||||
TIME | date variable | |||||
TIME | time variable | |||||
TIME | timestamp variable |
See also *DATE, *TIME, and TIMESTAMP
The result field is required and must contain either a 6-, 12-, or 14-position numeric field, or a date, time, or timestamp variable. If a 6-position field is specified, the current system time is retrieved. If a 12-position numeric field is specified, the current system time and current system date are retrieved. If a 14-position numeric field is specified, the current system time and current system date (including the century) are retrieved.
When both time and date are retrieved, the time is returned in positions 1 through 6, and the date is returned in positions 7 to 12 or 7 to 14. The time is returned in the format HHMMSS and is based on a 24-hour clock.
If the date is also retrieved, it is returned in the format specified for the job running on the system. If the job's date format is *MDY, the date is returned as MMDDYY for a 12-position result field and MMDDCCYY for a 14-position result field. For Julian dates, the format is YY0DD and CCYY0DDD. The embedded zero is a placeholder because Julian days range from 1 to 366.
The format of the date/time value returned by the TIME operation is based on the length and type of the result field. The format is always HHMMSSdddddddd, where HHMMSS is the time, and dddddddd is the date. The value is truncated as necessary by the TIME operation before it is stored in the result field. Table 5.23 lists the return value for the TIME operation. The date used in this illustration is the 31st of December 1998 at 13:45:00 (1:45 P.M.).
Result Field Type | Time Returns | Format | Example Value Datfmt |
---|---|---|---|
Dec(6,0) | System Time | HHMMSS | 124500 |
Dec(12,0) | System Time, System Date | HHMMSSMMDDYY | 124500123198 |
Dec(14,0) | System Time, System Date | HHMMSSMMDDYYYY | 12450012311998 |
DATE | System Date | Result field's format | 1998-12-31 |
TIME | System Time | Result field's format | 13:45:00 |
TIMESTAMP | System Date, System Time | *ISO | 1998-12-31-13.45.00.000000 |
When the date format is *YMD and the time and date are returned together in a 12-position field, the format is HHMMSSYYMMDD. For a 14-position field, the format is HHMMSSYYYYMMDD. Example 5.141 illustrates the TIME operation. The date used in these examples is the 31st of December 1998 at 13:45:00 (1:45 P.M.). The date format for the session (job) running the program is *MDY. Example 5.144 shows various ways to code the TIME operation.
Example 5.144: Retrieving the system time and the system time and date.
.....DName+++++++++++EUDS.......Length+TDc.Functions++++++++++++++++++++++++++++ 0010 D myTime S 6S 0 0020 D myDate S 12S 0 0030 D myDateTime S 14S 0 0040 D theTime S T TIMFMT(*USA) 0050 D theDate S D DATFMT(*ISO) 0060 D theTimeStamp S Z .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0070 C TIME myTime ** MYTIME = 134500 0080 C TIME myDate ** MYDATE = 123198 0090 C TIME myDateTime ** MYDATETIME = 134500123198 0010 C TIME theTime ** THETIME = T'01:45 PM' 0011 C TIME theDate ** THEDATE = D'1998-12-31' 0012 C TIME theTimeStamp ** THETIMESTAMP = Z'1998-12-31-13.45.00.000000'
The UNLOCK operation releases a lock applied to one or all data areas that are locked by the program. In addition, the UNLOCK operation unlocks a database file record. For the UNLOCK operation to be used on a data area, the *DTAARA DEFINE operation must have been used to assign the data area to a variable within the program. For the UNLOCK operation to be used on a file, the file must have been opened for update processing and a record must be locked.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
UNLOCK | data area name | [error] | ||||
UNLOCK | *DTAARA | [error] | ||||
UNLOCK | database file name | [error] |
See also *DTAARA, IN, OUT, *LOCK, READ, and CHAIN
For data areas, factor 2 is required and must contain the name of the data area that is released. The reserved word *DTAARA can be specified to indicate that all data areas locked by the program are to be released. The local data area (*LDA) cannot be unlocked by this operation.
For database files, factor 2 is required and must contain the name of the file with an unlocked record. The file must have been opened for update processing and a record must be locked.
In Example 5.145, two data areas (CTRLDTA and NEXTCUST) are defined to the program (lines 10 and 20), and then retrieved and locked (line 30). After some data manipulation, the data areas are rewritten (lines 50 and 70). In addition, the data areas are unlocked with the UNLOCK operation (line 80).
Example 5.145: Releasing all data area locks for a program.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C *DTAARA DEFINE CTRLDATA CONTROL 9 0 0020 C *DTAARA DEFINE NextCust 9 0 0030 C *LOCK IN *DTAARA 0040 C ADD 1 NextCust 0050 C OUT NextCust 0060 C Eval Control = NextCust 0070 C OUT Control 0080 C UNLOCK *DTAARA
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | N/A | |
73 – 74 | 2 | [ error ] | An error occurred during the operation. |
75 – 76 | 3 | N/A |
Extender | Description |
---|---|
E | ERROR - Causes the %ERROR and %STATUS built-in functions to be set if an error occurs during the operation. |
Example 5.146 shows how to unlock records that have been previously locked.
Example 5.146: Unlocking a record previously locked.
.....FFileName++IFEASFRlen+LKeylnKFDevice+.Functions++++++++++++++++++++++++++++ FCUSTMAST UF E K DISK INFDS(INFDS) .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq C dou %EOF C READ CUSTOMER 58 * If at EOF, then leave the DO loop C if %EOF C LEAVE C ENDIF * Print an invoice based on the region C SELECT C WHEQ Region = MIDWST or Region = PACIFIC C EXSR INVBLU C When REGION = CENTRAL C EXSR INVRED C OTHER * If we're not printing invoices for this customer's region * then unlock the customer record. C Unlock CUSTMAST C EndSl ** Additional code should go here. C EndDO
The UPDATE operation rewrites the data-file record currently retrieved and locked by the program. The file specified in factor 2 must be opened for update (i.e., the letter U must be specified in position 15 of the file's file specification). In addition, the record must have been previously read and locked by a CHAIN, READ, READE, READP, or READPE operation.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
UPDATE (E) | format name | [error] | ||||
UPDATE (E) | file name | [data structure] | [error] |
See also UNLOCK, EXCEPT, WRITE, READ, and DELETE
Factor 2 is required and must conform to the following rules:
For an externally described file, a record format name must be specified.
For program-described files, a file name is required. The result field is also required for program-described files.
For workstation files, only a subfile record format name can be specified.
The result field is optional for externally described files and is required for program-described files. When the result field is specified, it must contain the name of a data structure from which the file is updated. Resulting indicator 2 is optional and can be used to signal when the UPDATE operation doesn't complete successfully (for example, when the record being rewritten is not the last record retrieved from the file).
Before an UPDATE operation can be issued, a record must have been retrieved for update by the program. The READ, READC, READE, READP, and CHAIN operations can be used to retrieve the record for update. The UPDATE operation can be used on any file opened for update. However, unpredictable results can occur if the operation is issued at total-time calculations.
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | N/A | |
73 – 74 | 2 | [error] | An error occurred during the operation. |
75 – 76 | 3 | N/A |
In Example 5.147, line 20 defines the data file CUSTMAST as an UPDATE file and line 30 defines the workstation file DISPLAY as a COMBINED file. This allows the subfile records in the subfile PANEL02 (line 30) to be written to and updated.
Example 5.147: Updating a master data file and a subfile.
.....FFileName++IFEASFRlen+LKeylnKFDevice+.Functions++++++++++++++++++++++++++++ 0010 FCODETBL IF E K DISK 0020 FCUSTMAST UF E K DISK 0030 FDISPLAY CF E WORKSTN Sfile(Panel02 : rrn) .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0050 C CustID CHAIN CustRec 54 0070 C IF %Found 0080 C EXSR FillSFL 0090 C EXFMT PANEL01 0100 C EXSR RTVFunct 0110 C If FUNCT = 'UPDATE' 0120 C UPDATE CustRec 0130 C EXSR UpdSFL 0140 C endIf 0150 C endIf
Line 50 retrieves the record with the index value stored in CUSTID. If the record is found, the FILL-SUBFILE routine is called. Then the subfile control record (PANEL02 on line 80) is displayed.
The record's data and the subfile are displayed at the workstation by the EXFMT operation on line 90. If the user modifies the data, the file CUSTMAST is rewritten (line 120) and the subfile is updated through a subroutine (line 130).
The WHENxx operation is used to perform the selection within an in-line case group of the SELECT-WHEN-OTHER-ENDSL operations. The WHENxx operation compares the value in factor 1 to the value in factor 2. If the comparison is true, the group of calculations between the WHENxx and the next WHENxx, OTHER, or ENDSL operation is performed. The WHEN operation performs a test in the extended factor 2.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
compare value 1 | WHENxx | compare value 2 | ||||
WHEN (M R) | conditional expression |
See also SELECT, OTHER, ENDSL, DOWxx, DOUxx, and CASxx
The WHENxx operation requires a relationship test xx, where xx may be any one of the Boolean operators (EQ, GE, GT, LE, LT, and NE). See Table 5.9 for details. Factor 1 is compared to factor 2 based on the xx operator. Factor 1 and factor 2 must be similar data types. The natural expression form of WHEN uses the conditional expression specified in the extended factor 2.
The WHENxx test can be extended with the ANDxx or ORxx operations. ANDxx allows compound conditions to be tested; ORxx allows additional, but separate, conditions to be tested. The ANDxx and ORxx operations cannot be used in conjunction with the WHEN form of this operation.
The WHENxx, OTHER, and SELECT operations define an in-line case group. The SELECT operation is used to identify the case group. The WHENxx operation is used to conditionally perform specific blocks of code. An OTHER operation identifies the block of code to be performed when all of the conditions for the WHENxx operations are false. The OTHER operation can be thought of as a "catch all" routine.
In Example 5.148, the WHENxx operation is used to condition various program statements. Also, several levels of nested IF, SELECT/WHENxx, and DOxx loops are featured.
Example 5.148: In-line case group with SELECT/WHENxx/OTHER statements.
The WRITE operation outputs a record to a file. If the file is a data file, then a new record is created in the file. If the file is a device file, the record is sent to the device.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
WRITE (E) | format name | [error] | [full] | |||
WRITE (E) | file name | [data structure] | [error] | |||
Valid when Factor 2 contains the name of a subfile detail record format. |
See also READ, READE, READP, READPE, CHAIN, UPDATE, DELETE, UNLOCK, and EXCEPT
Factor 2 is required and must conform to the following rules:
For an externally described file, a record format name must be specified.
For program described files, a file name is required. The result field is also required and must contain the name of a data structure, from which the file's data is retrieved and written to the file.
Resulting indicator 3 is optional and can be specified when factor 2 contains a subfile record format name. The indicator signals when the subfile is full. In addition, the %EOF built-in function is set on when the subfile is full.
If resulting indicator 3 is omitted for subfile record formats, the following applies:
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | N/A | |
73 – 74 | 2 | [ error ] | An error occurred during the operation. |
75 – 76 | 3 | [full] | The WRITE operation to a subfile detail record did not complete because the subfile is full. The %EOF built-in function is set on when this condition occurs. |
Extender | Description |
---|---|
E | ERROR - Causes the %ERROR and %STATUS built-in functions to be set if an error occurs during the operation. |
For extendible subfiles—those where the subfile page size is less than the total subfile size—the subfile is automatically extended.
For fixed-size subfiles—those where the subfile page equals the subfile size—the program's exception/error routine is called (unless the E operation extender is also specified). If the E operation extender is specified, the %ERROR and %STATUS built-in functions are initialized.
The WRITE operation adds records to database files and outputs formats to WORKSTN device files. Depending on the external attributes of the WORKSTN file, device file formats are sent to the device.
In Example 5.149, a new record is added to the file CUSTMAST (line 120). A record is added to the subfile PANEL02 (line 180) using the WRITE operation. The subfile relative record number is incremented (line 170). It contains the number of the record to be added to the subfile (line 180).
Example 5.149: Writing to a master data file and a subfile.
.....FFileName++IFEASFRlen+LKeylnKFDevice+.Functions++++++++++++++++++++++++++++ 0010 FCODETBL IF E K DISK 0020 FCUSTMAST UF A E K DISK 0030 FDISPLAY CF E WORKSTN SFILE(Panel02 : rrn) .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0050 C CustID CHAIN CustRec 0070 C If %FOUND 0080 C exsr FillSFL 0090 C ExFmt PANEL01 0100 C exsr RTVFunct 0110 C If Funct = 'WRITE' 0120 C WRITE CustRec 0130 C endIf 0140 C endIf 0150 CSR FillSFL BEGSR 0160 C dou %EOF = *ON 0170 C ADD 1 RRN ** Add to the subfile, and ignore the subfile-full message. 0180 C WRITE PANEL02 0190 C Read CODETBL 0210 C endDo 0220 CSR endFillSFL endsr
The XFOOT operation adds all the elements of the numeric array specified in factor 2 and places the sum into the result field.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
XFOOT(H) | numeric array | sum of array | [+] | [-] | [0] |
See also SORTA, SORTD, and %XFOOT
Factor 2 is required and must contain a numeric array name where the elements are added together. The result field is required and must contain a numeric field or array element. An element of the array specified in factor 2 can be used as the result field. The sum of all the elements of the array specified in factor 2 is placed into the result field.
In Example 5.150, the array MONTHSALES (line 10) contains the monthly sales figures. The XFOOT operation (line 30) sums the monthly sales figures and stores the total in the YEARSALES field. Then, on line 40, the %XFOOT built-in function is used to perform the equivalent task.
Example 5.150: Illustrating XFOOT with a numeric array.
.....DName+++++++++++EUDS.......Length+TDc.Functions++++++++++++++++++++++++++++ 0010 D Months S 7P 2 Dim(12) 0020 D YearSales S +2 Like(MonthSales) .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0030 C XFOOT MONTHSALES YearSales 0040 C Eval YearSales = %XFoot(MonthSales)
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | [ + ] | The result field is greater than zero. |
73 – 74 | 2 | [ - ] | The result field is less than zero. |
75 – 76 | 3 | [ 0 ] | The result field is equal to zero. |
Extender | Description |
---|---|
H | HALF ADJUST - Causes the result value to be half-adjusted (rounded) off to the nearest decimal point. |
The XLATE operation translates each character of factor 2 based on the 'from' and 'to' translation values specified in factor 1. The translated value is placed in the result field.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
from value : to value | XLATE (P E) | source [:start pos] | target | [error] |
See also SCAN and IFxx
Factor 1 is required and must contain the 'from' and 'to' values that are used to translate the value specified in factor 2. The from and to values can be a literal value, named constant, field, array element, data structure, or data-structure subfield. For long translation values, it is beneficial to use a named constant or field in factor 1.
Factor 2 is required and must contain a literal value, named constant, field, array element, data structure, or data-structure subfield that is used as the source of the translation. The translated value is placed in the result field.
Factor 2 accepts one optional parameter: START-POSITION. This parameter is used to specify the starting-position in factor 2 where translation begins. If the START-POSITION parameter is omitted, translation begins in position one of factor 2. START-POSITION can be a literal value, named constant, numeric field, or numeric data-structure subfield.
Translation occurs by substituting each character of factor 2 (beginning with the START-POSITION) that matches a character of the 'from' value with the corresponding character of the 'to' value. The result of the translation, including any positions of factor 2 that are bypassed (i.e., through the START-POSITION), are moved and left adjusted to the result field.
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | N/A | |
73 – 74 | 2 | [error] | An error occurred during the operation. |
75 – 76 | 3 | N/A |
Extender | Description |
---|---|
P | PAD - Causes the result field to be cleared before the translate operation is performed. |
E | ERROR - Causes the %ERROR and %STATUS built-in functions to be set if an error occurs during the operation. |
In Example 5.151, the named constants LOWER and UPPER are used to translate lowercase letters in the field NAME to uppercase. Note that any characters of factor 2 that are not represented in the from value go unchanged when moved to the result field. An example of the results from this routine follows:
Before *...v... 1 ...v... 2 ...v... 3 NAME = 'Robert F. Kennedy ' After *...v... 1 ...v... 2 ...v... 3 NAME = 'ROBERT F. KENNEDY '
Example 5.151: Translating lowercase characters to uppercase characters.
.....DName+++++++++++EUDS.......Length+TDc.Functions++++++++++++++++++++++++++++ 0010 D Lower C Const('abcdefghijklmnopqrstuvwxyz') 0020 D Upper C Const('ABCDEFGHIJKLMNOPQRSTUVWXYZ') .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0030 C lower:UPPER XLATE NAME NAME
In the previous example, lowercase characters are translated to uppercase. By reversing the order of these named constants, translation from uppercase to lowercase would be performed. In the following example, all occurrences of blanks are translated to periods. In Example 5.152, blank characters in the field PROMPT are translated to periods.
Example 5.152: Translating blanks to periods.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq C ' ':'.' XLATE PROMPT PROMPT
A before-and-after example of the data used by this example follows:
Before:
*...v... 1 ...v... 2 ...v... 3 PROMPT = 'Customer name '
After:
*...v... 1 ...v... 2 ...v... 3 PROMPT = 'Customer.name.................'
In the preceding example, a period appears between the words 'Customer' and 'name'. If the desired result is to begin substitution after the two words, 'Customer name', the START-POSITION parameter can be used. See Example 5.153.
Example 5.153: Translating with starting position.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq C ' ' CHECKR PROMPT S 5 0 C ADD 1 S C ' ':'.' XLATE PROMPT:S PROMPT
The results of the routine in Example 5.150 are as follows:
Before:
*...v... 1 ...v... 2 ...v... 3 PROMPT = 'Customer name '
After:
*...v... 1 ...v... 2 ...v... 3 PROMPT = 'Customer name.................'
The Z-ADD operation moves the value specified in factor 2 to the result field. Any data in the result field, including the sign, is replaced with the new value.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
Z-ADD(H) | numeric value | numeric variable | [+] | [-] | [0] |
See also Z-SUB, CLEAR, EVAL, RESET, and MOVE
Factor 2 is required and must contain the name of a numeric field, array element, or the constant with the data that replaces the data in the result field. The result field is required and must contain the name of a numeric field or numeric array element that receives the value specified in factor 2.
The Z-ADD operation has traditionally been used to clear the contents of a numeric field. The CLEAR operation accomplishes the same task and is data-type independent.
In Example 5.154, the value 3 replaces the contents of the field FIELDA (line 10). The value of field FIELDA replaces the value of the result field FIELDB (line 20). The value 0 replaces the value of the result field TOTAL (line 30).
Example 5.154: Illustrating the Z-ADD operation.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C Z-ADD 3 FIELDA 0020 C Z-ADD FIELDA FIELDB 0030 C Z-ADD 0 TOTAL
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | [ + ] | The result field is greater than zero. |
73 – 74 | 2 | [ - ] | The result field is less than zero. |
75 – 76 | 3 | [ 0 ] | The result field is equal to zero. |
Extender | Description |
---|---|
H | HALF ADJUST - Causes the result value to be rounded to the nearest decimal position. |
The Z-SUB operation subtracts the value of factor 2 from zero, and then moves the result into the result field. Any data in the result field, including the sign, is replaced with the new value.
Factor 1 | OpCode | Factor 2 | Result Field | Resulting Indicators | ||
---|---|---|---|---|---|---|
Z-SUB(H) | numeric value | numeric variable | [+] | [-] | [0] |
See also Z-ADD, CLEAR, EVAL, RESET, and MOVE
Factor 2 is required and must contain the name of a numeric field, the array element, or the constant where the data is subtracted from zero and is then placed into the result field. The result field is required and must contain the name of a numeric field or numeric array element that receives the result of the subtraction operation.
In Example 5.155, after the Z-SUB operation on line 10 is performed, FIELDA equals -3. After the Z-SUB operation on line 20 is performed, FIELDB equals 2. After the Z-ADD operation on line 30 is performed, TOTAL equals 0. Line 40 illustrates a primary use of the Z-SUB operation. The sign of FIELDC is reversed.
Example 5.155: Illustrating the Z-SUB operation.
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0010 C Z-SUB 3 FIELDA 0020 C Z-SUB -2 FIELDB 0030 C Z-SUB 0 TOTAL 0040 C Z-SUB FIELDC FIELDC
Resulting Indicator Legend | |||
---|---|---|---|
Columns | Ind. | Usage | Set-On Condition |
71 – 72 | 1 | [ + ] | The result field is greater than zero. |
73 – 74 | 2 | [ - ] | The result field is less than zero. |
75 – 76 | 3 | [ 0 ] | The result field is equal to zero. |
Extender | Description |
---|---|
H | HALF ADJUST - Causes the result value to be rounded to the nearest decimal position. |