7.7.2 BEGINCHECK Examples

Structuring Functions for Inline Validation

Structuring Functions to Use a Validation Subroutine

Using the BEGINCHECK/ENDCHECK Commands for Inline Validation

Using the BEGINCHECK/ENDCHECK Commands for Validation with a Subroutine

Structuring Functions to Validate Header Fields and Multiple Details Input Via a Browse List

Example of Validating Header Fields and Multiple Details Input Via a Browse List

Structuring Functions for Inline Validation

Typically functions using validation commands (e.g.: CONDCHECK, DATECHECK, FILECHECK, RANGECHECK and VALUECHECK) are structured for inline validation like this:

BEGIN_LOOP

REQUEST    << INPUT >>

BEGINCHECK

*          << USE CHECK COMMANDS TO VALIDATE INPUT HERE >>

ENDCHECK  

*          << PROCESS THE VALIDATED INPUT HERE >>

END_LOOP

If a validation command inside the BEGINCHECK / ENDCHECK command block detects a validation error control is passed back to the REQUEST command. This happens because of the default IF_ERROR(*LASTDIS) parameter on the ENDCHECK command.  

Structuring Functions to Use a Validation Subroutine

Typically functions using validation commands (e.g.: CONDCHECK, DATECHECK, FILECHECK, RANGECHECK and VALUECHECK) are structured for subroutine validation like this:

DEFINE     FIELD(#ERRORCNT) REFFLD(#STD_NUM)

DEF_COND   NAME(*NOERRORS) COND('#ERRORCNT = 0')

          

BEGIN_LOOP

DOUNTIL    COND(*NOERRORS)

REQUEST    << INPUT >>

EXECUTE    SUBROUTINE(VALIDATE)

ENDUNTIL  

*          << PROCESS THE VALIDATED INPUT HERE >>

END_LOOP  

          

SUBROUTINE NAME(VALIDATE)

CHANGE     FIELD(#ERRORCNT) TO(0)

BEGINCHECK KEEP_COUNT(#ERRORCNT)

*          << USE CHECK COMMANDS TO VALIDATE INPUT HERE >>

ENDCHECK   IF_ERROR(*NEXT)

ENDROUTINE

If a validation command inside the BEGINCHECK / ENDCHECK command block detects a validation error control is returned to the main function loop with #ERRORCNT > 0. 

Using the BEGINCHECK/ENDCHECK Commands for Inline Validation

This example demonstrates how to use the BEGINCHECK/ENDCHECK commands (and the other validation commands) within the main program block to verify a set of input details.

DEFINE     FIELD(#NEWSALARY) REFFLD(#SALARY) LABEL('New Salary') DESC('New Salary for Employee')

DEFINE     FIELD(#TOTSALARY) REFFLD(#SALARY) DESC('Total Salary for Department') DEFAULT(0)

DEFINE     FIELD(#BUDGET) REFFLD(#SALARY) LABEL('Budget') DESC('Budget for Department Salaries')

GROUP_BY   NAME(#XG_DTAILS) FIELDS(#DEPTMENT #EMPNO #SURNAME #GIVENAME #NEWSALARY #STARTDTE)

DEF_LIST   NAME(#EMPBROWSE) FIELDS(#XG_DTAILS)

          

BEGIN_LOOP

REQUEST    FIELDS(#XG_DTAILS #BUDGET) BROWSELIST(#EMPBROWSE)

CHANGE     FIELD(#TOTSALARY) TO(*DEFAULT)

SELECT     FIELDS(#SALARY) FROM_FILE(PSLMST1) WITH_KEY(#DEPTMENT)

CHANGE     FIELD(#TOTSALARY) TO('#TOTSALARY + #SALARY')

ENDSELECT 

          

BEGINCHECK

CALLCHECK  FIELD(#STARTDTE) BY_CALLING(WORKDAY) PROG_TYPE(FUN) MSGTXT('The supplied date is not a working day.')

CONDCHECK  FIELD(#NEWSALARY) COND('(#NEWSALARY + #TOTSALARY) <= #BUDGET') MSGTXT('New salary causes Department budget to be exceeded')

DATECHECK  FIELD(#STARTDTE) IN_FORMAT(*DDMMYY) BEFORE(30) AFTER(0) MSGTXT('Start date is not in the right format or not in the last month')

FILECHECK  FIELD(#EMPNO) USING_FILE(PSLMST) FOUND(*ERROR) NOT_FOUND(*NEXT) MSGTXT('Employee number supplied already exists')

RANGECHECK FIELD(#EMPNO) RANGE((A0000 A9999)) MSGTXT('Employee number has to be in the range A0000 - A9999')

VALUECHECK FIELD(#DEPTMENT) WITH_LIST(ADM AUD FLT GAC) MSGTXT('The department code entered is not valid')

ENDCHECK  

          

ADD_ENTRY  TO_LIST(#EMPBROWSE)

END_LOOP

If any of the input values causes a validation command to give an error the message defined with that command is issued and program control returns to the last screen displayed. In this case the last screen displayed is the REQUEST screen.

Using the BEGINCHECK/ENDCHECK Commands for Validation with a Subroutine

This example demonstrates how to use the BEGINCHECK/ENDCHECK commands inside a subroutine to check that entered details for a new employee conform to a set of validations before being accepted for further processing.

After the user enters the requested details the VALIDATE subroutine is called. It checks that all the values comply with the various validations. If this is not true the message defined in a command that gives an error is given, 1 is added to #ERRORCNT and the DOUNTIL loop executes again. When the error tally is zero the DOUNTIL loop ends and processing of the verified input is done.

DEFINE     FIELD(#ERRORCNT) TYPE(*DEC) LENGTH(3) DECIMALS(0) DEFAULT(0)

DEF_COND   NAME(*NOERRORS) COND('#ERRORCNT = 0')

DEFINE     FIELD(#NEWSALARY) REFFLD(#SALARY) LABEL('New Salary') DESC('New Salary for Employee')

DEFINE     FIELD(#TOTSALARY) REFFLD(#SALARY) DESC('Total Salary for Department') DEFAULT(0)

DEFINE     FIELD(#BUDGET) REFFLD(#SALARY) LABEL('Budget') DESC('Budget for Department Salaries')

GROUP_BY   NAME(#XG_DTAILS) FIELDS(#DEPTMENT #EMPNO #SURNAME #GIVENAME #NEWSALARY #STARTDTE)

DEF_LIST   NAME(#EMPBROWSE) FIELDS(#XG_DTAILS)

          

BEGIN_LOOP

DOUNTIL    COND(*NOERRORS)

REQUEST    FIELDS(#XG_DTAILS #BUDGET) BROWSELIST(#EMPBROWSE)

EXECUTE    SUBROUTINE(VALIDATE)

ENDUNTIL  

ADD_ENTRY  TO_LIST(#EMPBROWSE)

END_LOOP  

          

SUBROUTINE NAME(VALIDATE)

CHANGE     FIELD(#ERRORCNT) TO(0)

CHANGE     FIELD(#TOTSALARY) TO(*DEFAULT)

SELECT     FIELDS(#SALARY) FROM_FILE(PSLMST1) WITH_KEY(#DEPTMENT)

CHANGE     FIELD(#TOTSALARY) TO('#TOTSALARY + #SALARY')

ENDSELECT 

          

BEGINCHECK KEEP_COUNT(#ERRORCNT)

CALLCHECK  FIELD(#STARTDTE) BY_CALLING(WORKDAY) PROG_TYPE(FUN) MSGTXT('The supplied date is not a working day.')

CONDCHECK  FIELD(#NEWSALARY) COND('(#NEWSALARY + #TOTSALARY) <= #BUDGET') MSGTXT('New salary causes Department budget to be exceeded')

DATECHECK  FIELD(#STARTDTE) IN_FORMAT(*DDMMYY) BEFORE(30) AFTER(0) MSGTXT('Start date is not in the right format or not in the last month')

FILECHECK  FIELD(#EMPNO) USING_FILE(PSLMST) FOUND(*ERROR) NOT_FOUND(*NEXT) MSGTXT('Employee number supplied already exists')

RANGECHECK FIELD(#EMPNO) RANGE((A0000 A9999)) MSGTXT('Employee number has to be in the range A0000 - A9999')

VALUECHECK FIELD(#DEPTMENT) WITH_LIST(ADM AUD FLT GAC) MSGTXT('The department code entered is not valid')

ENDCHECK   IF_ERROR(*NEXT)

          

ENDROUTINE

Structuring Functions to Validate Header Fields and Multiple Details Input Via a Browse List

At times there may be a need to validate multiple values for a field or fields. An example of this would be a screen that requires input of several header fields and multiple entries of a set of detail fields. Typically a function required to do this type of validation would be structured like this:

FUNCTION   OPTIONS(*DIRECT)

DEFINE     FIELD(#ERRORCNT) REFFLD(#STD_NUM)

DEF_COND   NAME(*NOERRORS) COND('#ERRORCNT = 0')

GROUP_BY   NAME(#HEADER) FIELDS(.... <FIELDS ON HEADER> ........)

DEF_LIST   NAME(#DETAILS) FIELDS(. <FIELDS IN DETAILS> .......)

          

BEGIN_LOOP

CHANGE     FIELD(#HEADER #DETAILS) TO(*NULL)

INZ_LIST   NAMED(#DETAILS) NUM_ENTRYS(100) WITH_MODE(*ADD)

DOUNTIL    COND(*NOERRORS)

REQUEST    FIELDS(#HEADER) BROWSELIST(#DETAILS)

EXECUTE    SUBROUTINE(VALIDATE)

ENDUNTIL  

END_LOOP  

          

SUBROUTINE NAME(VALIDATE)

CHANGE     FIELD(#ERRORCNT) TO(0)

BEGINCHECK KEEP_COUNT(#ERRORCNT)

*          <<                                             >>

*          <<        VALIDATE HEADER FIELDS HERE          >>

*          <<                                             >>

SELECTLIST NAMED(#DETAILS) GET_ENTRYS(*NOTNULL)

BEGINCHECK KEEP_COUNT(#ERRORCNT)

*          <<                                             >>

*          <<        VALIDATE DETAIL FIELDS HERE          >>

*          <<                                             >>

ENDCHECK   IF_ERROR(*NEXT)

UPD_ENTRY  IN_LIST(#DETAILS) WITH_MODE(*ADD)

ENDSELECT 

ENDCHECK   IF_ERROR(*NEXT)

ENDROUTINE

 

Example of Validating Header Fields and Multiple Details Input Via a Browse List

This example demonstrates how to validate a screen with several header fields and multiple values of a set of detail fields that are input via a browse list.

DEFINE     FIELD(#ERRORCNT) REFFLD(#STD_NUM)

DEF_COND   NAME(*NOERRORS) COND('#ERRORCNT = 0')

GROUP_BY   NAME(#HEADER) FIELDS(#EMPNO #SURNAME #GIVENAME)

DEF_LIST   NAME(#DETAILS) FIELDS(#SKILCODE #DATEACQ)

          

MESSAGE    MSGTXT('Input Employee details, Press Enter.')

BEGIN_LOOP

CHANGE     FIELD(#HEADER #DETAILS) TO(*NULL)

INZ_LIST   NAMED(#DETAILS) NUM_ENTRYS(100) WITH_MODE(*ADD)

DOUNTIL    COND(*NOERRORS)

REQUEST    FIELDS(#HEADER) BROWSELIST(#DETAILS)

EXECUTE    SUBROUTINE(VALIDATE)

ENDUNTIL  

MESSAGE    MSGTXT('Employee details have been accepted. Input next Employee')

END_LOOP  

SUBROUTINE NAME(VALIDATE)

CHANGE     FIELD(#ERRORCNT) TO(0)

          

BEGINCHECK KEEP_COUNT(#ERRORCNT)

RANGECHECK FIELD(#EMPNO) RANGE((A0001 A0090))

VALUECHECK FIELD(#SURNAME) WITH_LIST(*BLANKS) IN_LIST(*ERROR) NOT_INLIST(*NEXT)

VALUECHECK FIELD(#GIVENAME) WITH_LIST(*BLANKS) IN_LIST(*ERROR) NOT_INLIST(*NEXT)

          

SELECTLIST NAMED(#DETAILS) GET_ENTRYS(*NOTNULL)

BEGINCHECK KEEP_COUNT(#ERRORCNT)

FILECHECK  FIELD(#SKILCODE) USING_FILE(SKLTAB) USING_KEY(#SKILCODE)

DATECHECK  FIELD(#DATEACQ)

ENDCHECK   IF_ERROR(*NEXT)

UPD_ENTRY  IN_LIST(#DETAILS) WITH_MODE(*ADD)

ENDSELECT 

          

ENDCHECK   IF_ERROR(*NEXT)

ENDROUTINE