Executing a DOUNTIL . . . ENDUNTIL Routine
Executing DOUNTIL . . . ENDUNTIL to enter "n" records to a file
Using DEF_COND Values as DOUNTIL parameters to make code easier to read and maintain
Comparing DOUNTIL . . . ENDUNTIL to the use of IF . . . GOTO . . . ENDIF
Executing DOUNTIL . . . ENDUNTIL routine with an Array Index
Executing a DOUNTIL . . . ENDUNTIL Routine
This is an example of the simple use of DOUNTIL and ENDUNTIL to count to 10 in a loop:
DEFINE FIELD(#COUNT) REFFLD(#STD_NUM)
CHANGE FIELD(#COUNT) TO(1)
DOUNTIL COND('#COUNT > 10')
DISPLAY FIELDS(#COUNT)
CHANGE FIELD(#COUNT) TO('#COUNT + 1')
ENDUNTIL
The DOUNTIL command is similar in structure to the DOWHILE command. However, there is one important difference. In the DOUNTIL command, the condition is not checked BEFORE doing the first iteration. This is an example:
DEFINE FIELD(#COUNT) REFFLD(#STD_NUM)
CHANGE FIELD(#COUNT) TO(5)
DOUNTIL COND('#COUNT > 1')
DISPLAY FIELDS(#COUNT)
ENDUNTIL
Although #COUNT is greater than 1, the loop is still executed one time.
Executing DOUNTIL . . . ENDUNTIL to enter "n" records to a file
In this example, the details of 10 employees are inserted into a file:
GROUP_BY NAME(#EMPDET) FIELDS(#EMPNO #SURNAME #SALARY)
DEFINE FIELD(#COUNT) REFFLD(#STD_NUM)
DEF_LIST NAME(#WORKER) FIELDS(#EMPNO #SURNAME #SALARY)
CHANGE FIELD(#COUNT) TO(1)
DOUNTIL COND('#COUNT > 10')
DISPLAY FIELDS(#COUNT)
proREQUEST FIELDS(#EMPNO #SURNAME #SALARY)
ADD_ENTRY TO_LIST(#WORKER)
CHANGE FIELD(#COUNT) TO('#COUNT + 1')
ENDUNTIL
DISPLAY BROWSELIST(#WORKER)
Using DEF_COND Values as DOUNTIL parameters to make code easier to read and maintain
In this example, the COND parameter for the DOUNTIL command is set by the DEF_COND command before DOUNTIL is executed.
DEFINE FIELD(#COUNT) REFFLD(#STD_NUM)
DEF_COND NAME(*COUNT_TEN) COND('#COUNT > 10')
CHANGE FIELD(#COUNT) TO(1)
DOUNTIL COND(*COUNT_TEN)
DISPLAY FIELDS(#COUNT)
CHANGE FIELD(#COUNT) TO('#COUNT + 1')
ENDUNTIL
The use of DEF_COND allows the programmer to give a complex condition a meaningful label that expresses the reason behind the test of the condition. When subsequent programmers read the DOWHILE statement, the meaningful label will help them to understand the purpose of the statement.
The use of DEF_COND also helps in situations where the same condition is referred to multiple times in the function. In this case it reduces the quantity of code and makes maintenance of the condition easier. . For further reference, refer to the << link to DEF_COND >> command.
Comparing DOUNTIL . . . ENDUNTIL to the use of IF . . . GOTO . . . ENDIF
This example, shows the simple use of the DOUNTIL .... ENDUNTIL routine:
DOUNTIL COND('#A >= B')
<< logic >>
<< logic >>
<< logic >>
ENDUNTIL
Now compare this to the use of the IF .... GOTO .... ENDIF routine:
L01: IF COND('#A < B')
<< logic >>
<< logic >>
<< logic >>
GOTO LABEL(L01)
ENDIF
When compared, the use of the DOUNTIL .... ENDUNTIL routine is simpler and easier to read than when the IF .... GOTO .... ENDIF routine is used for a simple loop.
Executing DOUNTIL . . . ENDUNTIL routine with an Array Index
This example demonstrates the use of the DOUNTIL .... ENDUNTIL routine with an Array Index that groups 3 field values into an array, increments each one by 10%, then adds the resulting values up to display:
DEFINE FIELD(#VAL1) REFFLD(#STD_NUM)
DEFINE FIELD(#VAL2) REFFLD(#STD_NUM)
DEFINE FIELD(#VAL3) REFFLD(#STD_NUM)
DEFINE FIELD(#I1) REFFLD(#STD_NUM)
DEFINE FIELD(#TOTAL) TYPE(*DEC) LENGTH(6) DECIMALS(2) LABEL(TOTAL) EDIT_CODE(3)
DEF_ARRAY NAME(#ARR) INDEXES(#I1) OF_FIELDS(#VAL1 #VAL2 #VAL3)
CHANGE FIELD(#TOTAL) TO(1)
CHANGE FIELD(#I1) TO(1)
REQUEST FIELDS(#VAL1 #VAL2 #VAL3)
DOUNTIL COND('#I1 > 3')
CHANGE FIELD(#ARR#I1) TO('#ARR#I1 * 1.1')
CHANGE FIELD(#TOTAL) TO('#TOTAL + #ARR#I1')
CHANGE FIELD(#I1) TO('#I1 + 1')
ENDUNTIL
DISPLAY FIELDS(#TOTAL)
Refer to the 7.39 DOUNTIL command for further reference to the array index.