5.3.7 Adding Records to a File (Many At a Time)
Files Involved
Physical file TARGET (sales targets file) that has the following fields:
Field |
Type |
Length |
Description |
YEAR |
S |
2,0 |
Year |
MONTH |
S |
2,0 |
Month |
BRAND |
A |
5 |
Brand number / identity |
QUANTITY |
P |
9,0 |
Target sales quantity |
DOLLARS |
P |
11,2 |
Target sales dollar value |
RDML Program
<< Define work fields for this function >>
DEFINE FIELD(#ERRCOUNT) TYPE(*DEC) LENGTH(7)
DECIMALS(0)
<< Define group to appear on top of screen >>
GROUP_BY NAME(#TIME) FIELDS(#YEAR #MONTH)
<< Define group that contains all fields to be inserted >>
GROUP_BY NAME(#TARGET) FIELDS(#YEAR #MONTH #BRAND
#QUANTITY #DOLLARS)
<< Define list to be used for data entry >>
DEF_LIST NAME(#VALUES) FIELDS(#BRAND #QUANTITY #DOLLARS)
<< Loop until EXIT or MENU function key used >>
BEGIN_LOOP
<< Clear screen and initialize list with 20 entries >>
CHANGE FIELD(#TARGET) TO(*NULL)
SET_MODE TO(*ADD)
INZ_LIST NAMED(#VALUES) NUM_ENTRYS(20)
<< Accept input until no errors exist in data >>
DOUNTIL COND('#ERRCOUNT = 0')
SET_MODE TO(*ADD)
DISPLAY FIELDS(#TIME) BROWSELIST(#VALUES)
<< Process all not "null" and not "accepted" records >>
CHANGE FIELD(#ERRCOUNT) TO(0)
SELECTLIST NAMED(#VALUES) GET_ENTRYS(*NOTNULL *ADD)
INSERT FIELDS(#TARGET) TO_FILE(TARGET)
VAL_ERROR(L10)
L10 IF_STATUS IS_NOT(*OKAY)
CHANGE FIELD(#ERRCOUNT)
TO('#ERRCOUNT + 1')
SET_MODE TO(*ADD)
ELSE
SET_MODE TO(*DISPLAY)
ENDIF
UPD_ENTRY IN_LIST(#VALUES)
ENDIF
ENDSELECT
ENDUNTIL
END_LOOP
Points to Note:
- Program keeps adding records until the EXIT or MENU function key is used (BEGIN_LOOP and END_LOOP commands).
- The EXIT and MENU function keys are enabled on the DISPLAY screen. If either key is used the function will end.
- Although the fields #YEAR and #MONTH are in every file record the user only has to specify them once .... at the top of the screen. Thus the user is entering "batches" of values for a particular year and month. The actual "values" are specified in the list displayed at the bottom of the screen. Up to 20 may be entered at one time.
- Note how the screen "mode" is set before the list is initialized with 20 "null" records. Since the mode is set to *ADD these can be used for data entry.
- The SELECTLIST / ENDSELECT processing loop only selects list entries that are not "null" (parameter *NOTNULL) and that are also in "add" mode (parameter *ADD). Thus only entries from the list that the user has actually entered data into, and have not already been inserted into the file, are processed.
- The VAL_ERROR parameter of the INSERT command causes control to be passed to the next command if a validation error is detected. The next command then examines the I/O "status". If any error occurred the error count is incremented and the mode set to "add". If no error occurred the mode is set to "display".
- After the mode has been set to *ADD or *DISPLAY (by the commands associated with the preceding point) the list entry is updated. If the mode is *DISPLAY when the update occurs the list entry will no longer be input capable and can no longer be changed by the user (because it has been inserted into the file). If the mode is *ADD then the fields in error will be reverse imaged by the update command and the user will be requested to correct the error.
The fact that a record has been "accepted" or "rejected" by the INSERT command can be indicated to the user by making the following modifications to the RDML commands:
<< Define work fields for this function >>
DEFINE FIELD(#ERRCOUNT) TYPE(*DEC) LENGTH(7) DECIMALS(0)
DEFINE FIELD(#ACCEPTED) TYPE(*CHAR) LENGTH(3)
COLHDG('Target' 'has been' 'Accepted')
<< Define group to appear on top of screen >>
GROUP_BY NAME(#TIME) FIELDS(#YEAR #MONTH)
<< Define group that contains all fields to be inserted >>
GROUP_BY NAME(#TARGET) FIELDS(#YEAR #MONTH #BRAND
#QUANTITY #DOLLARS)
<< Define list to be used for data entry >>
DEF_LIST NAME(#VALUES) FIELDS(#BRAND #QUANTITY
#DOLLARS (#ACCEPTED *OUTPUT))
<< Loop until EXIT or MENU function key used >>
BEGIN_LOOP
<< Clear screen and initialize list with 20 entries >>
CHANGE FIELD(#TIME) TO(*NULL)
CHANGE FIELD(#VALUES) TO(*NULL)
SET_MODE TO(*ADD)
INZ_LIST NAMED(#VALUES) NUM_ENTRYS(20)
<< Accept input until no errors exist in data >>
DOUNTIL COND('#ERRCOUNT = 0')
SET_MODE TO(*ADD)
DISPLAY FIELDS(#TIME) BROWSELIST(#VALUES)
<< Process all not "null" and not "accepted" records >>
CHANGE FIELD(#ERRCOUNT) TO(0)
SELECTLIST NAMED(#VALUES) GET_ENTRYS(*NOTNULL *ADD)
INSERT FIELDS(#TARGET) TO_FILE(TARGET)
VAL_ERROR(L10)
L10 IF_STATUS IS_NOT(*OKAY)
CHANGE FIELD(#ERRCOUNT) TO('#ERRCOUNT + 1')
SET_MODE TO(*ADD)
ELSE
SET_MODE TO(*DISPLAY)
CHANGE FIELD(#ACCEPTED) TO(YES)
ENDIF
UPD_ENTRY IN_LIST(#VALUES)
ENDIF
ENDSELECT
ENDUNTIL
END_LOOP
The main processing loop of the program could be modified to allow updates to "accepted" records like this:
<< Define work fields for this function >>
DEFINE FIELD(#ERRCOUNT) TYPE(*DEC) LENGTH(7) DECIMALS(0)
DEFINE FIELD(#ADD_RRN) TYPE(*DEC) LENGTH(15) DECIMALS(0)
DEFINE FIELD(#ACCEPTED) TYPE(*CHAR) LENGTH(3)
COLHDG('Target' 'has been' 'Accepted')
<< Define group to appear on top of screen >>
GROUP_BY NAME(#TIME) FIELDS(#YEAR #MONTH)
<< Define group that contains all fields to be inserted >>
GROUP_BY NAME(#TARGET) FIELDS(#YEAR #MONTH #BRAND
#QUANTITY #DOLLARS)
<< Define list to be used for data entry >>
DEF_LIST NAME(#VALUES) FIELDS(#BRAND #QUANTITY #DOLLARS
(#ACCEPTED *OUTPUT)(#ADD_RRN *HIDDEN))
<< Loop until EXIT or MENU function key used >>
BEGIN_LOOP
<< Clear screen and initialize list with 20 entries >>
CHANGE FIELD(#TIME) TO(*NULL)
CHANGE FIELD(#VALUES) TO(*NULL)
SET_MODE TO(*ADD)
INZ_LIST NAMED(#VALUES) NUM_ENTRYS(20)
DOUNTIL COND('#ERRCOUNT = 0')
SET_MODE TO(*ADD)
DISPLAY FIELDS(#TIME) BROWSELIST(#VALUES)
<< Process all not "null" records >>
CHANGE FIELD(#ERRCOUNT) TO(0)
SELECTLIST NAMED(#VALUES) GET_ENTRYS(*NOTNULL)
IF COND('#ACCEPTED = YES')
UPDATE FIELDS(#TARGET) IN_FILE(TARGET) VAL_ERROR(L10)
WITH_RRN(#ADD_RRN)
ELSE
INSERT FIELDS(#TARGET) TO_FILE(TARGET)
VAL_ERROR(L10) RETURN_RRN(#ADD_RRN)
ENDIF
L10 IF_STATUS IS_NOT(*OKAY)
CHANGE FIELD(#ERRCOUNT) TO('#ERRCOUNT + 1')
ELSE
CHANGE FIELD(#ACCEPTED) TO(YES)
ENDIF
SET_MODE TO(*ADD)
UPD_ENTRY IN_LIST(#VALUES)
ENDIF
ENDSELECT
ENDUNTIL
END_LOOP