The ACCEPT
statement validates and moves data, typically from an input message or
3270-type input screen.
Situation
1 – Using ACCEPT with Local Data.
Situation
2: Getting data from a 3270-type screen
Situation
3: Getting Data from a Web Service
Message
MESSAGE (field name) | NOMESSAGE
[EPRINT
[(data list)] [REPORT nbr]]
1. Is there any data to validate and
assign?
2. Can the data be assigned to the
target field?
This section gives you a quick introduction to the ACCEPT statement and the way that it might be used, in preparation for the more formal and complete language rules starting at Statement Options.
A normal assignment statement like
Wrk.A = Wrk.B;
moves data from B to A. So does
ACCEPT (Wrk.A = Wrk.B) MESSAGE(Wrk.Message);
Now imagine that we’ve defined the fields: -
DEFINE
Wrk DATA(
A CHAR(2) CODES(AK:
…
WI:
B
CHAR(2),
Message CHAR(40));
The assignment statement Wrk.A = Wrk.B; moves the data as efficiently as possible, but does not check that the data is valid. If Wrk.B is not a valid US State Code then Wrk.A will receive an invalid value but there will be no warning and only when A is displayed as “*********” (perhaps by another program) will the error be detected.
In contrast, ACCEPT (Wrk.A = Wrk.B); checks that the value is valid. If it is not then the error is detected: you can test for this with
IF $Error = True THEN;
and (with appropriate options) error messages will be set for display.
You should always use ACCEPT when you cannot be sure whether the data is valid, particularly when you’re processing input messages from Web Services or Screens.
ACCEPT is particularly powerful when used with input messages from Web Services Messages or 3270 screens. Suppose that we have created a 3270-type screen such as CICS2S by dragging fields known to the program into the screen: -
Here is the first part of our program: -
PROGRAM
CICS2 CICS INSCREEN(CICS2S) TRANSID(TRN2) COMMAREA(CICS2C) EXIT(menu1);
ACCEPT
(CICS2S.Function);
The field CICS2S.Function was dragged on to the screen from CICS2C, where it was defined: -
COPY
custf;
DEFINE
CICS2C COMMAREA
DATA(
Function CHAR(1) CODES (E:Enquiry,U:Update,A:Add,D:Delete)
VALUE Enquiry,
SAVE LIKE custf.*,
JZ-XCTL LIKE Jazz.Flag);
When ACCEPT refers to input from a 3270 screen: -
1. The screen definition has recorded the relationship between CICS2S.Function and CICS2C.Function. You don’t need to write
ACCEPT (CICS2C.Function = CICS2S.Function);
you simply name the screen field, and the name of the other field is implied.
2.
Fields in the screen are defined with a
terminating field that can be set to “*” if there is an error. Also there is a field called “Error” which
can carry a longer message. For example,
notice the “*” after Region, and the message on the 2nd-to-last line: -
3. If any errors are found then the program will be terminated and control returned to the user for correction, unless the CONTINUE option is used.
With a 3270 screen the relationship between the input field and a corresponding program field is built into the screen definition, and the Jazz screen editor creates a standard field called “Error” for messages such as “Region: not numeric”. This doesn’t apply to a web service message, so you have to give ACCEPT some help, telling it where to assign data, and perhaps where to put error messages.
One way of telling ACCEPT where the data goes it to use assignment-form items. For individual fields: =
ACCEPT
(Wk2.f2 = InputMessage.F2);
and for several fields
ACCEPT
(Custf.* = InputMessage.*);
Another is to use ASSIGN in the message definitions, defining the relationship between the input record and some other record. ASSIGN is used automatically by MANASYS Jazz with SCREEN and SERVICE messages, but it can be written explicitly in any kind of record. For example, here is a part of a container definition: -
COPY Custf;
COPY TYPES;
…
DEFINE IWSPG1 SERVICE INPUT DATA(
Function CHAR(1) CAPS CODES(E:Enquiry,U:Update,A:Add,D:Delete)
VALUE Enquiry,
JZ-Custf-Skip SMALLINT VALUE 0,
Custf GROUP,
Account CHAR(6) ASSIGN CustF.Account,
Region CHAR(4) ASSIGN CustF.Region,
District CHAR(4) ASSIGN CustF.District,
Name CHAR(30) ASSIGN CustF.Name,
SalesThisMonth CHAR(12) ASSIGN CustF.SalesThisMonth,
SalesYTD CHAR(12) ASSIGN CustF.SalesYTD,
Billingcycle CHAR(3) ASSIGN CustF.Billingcycle,
DateCommenced CHAR(9) ASSIGN CustF.DateCommenced,
END GROUP,
ViewState GROUP, [Must not be changed
CheckSum-Custf CHAR(40),
END GROUP);
…
With this
definition you can write a statement like this: -
ACCEPT (IWSPG1.Custf.*) EXCEPT(CustF.Account) MESSAGE OWSPG1.ERROR;
#207 I
Custf.Region,Custf.District,Custf.Name,Custf.SalesThisMonth,Custf.SalesYTD,Custf.Billingcycle,Custf.DateCommenced,
included in generic assignment
Each of the
CHAR fields (except Account) in IWSPG1.Custf is validated and assigned to the corresponding
field defined by the ASSIGN property.
If there is no MESSAGE option Jazz will look for a field named “Error”. The normal search rules for an unqualified field mean that this will usually be the field defined in the INSCREEN or CONTAINER definition. If it can’t find any such field then NOMESSAGE is assumed.
ACCEPT
[FROM(record name)] [DATA](data list)
[EXCEPT(data list)]
[SETMDT]
{[CONTINUE] | [EXIT]} [UPDATE] [MESSAGE(field name) | NOMESSAGE]
[EPRINT
[(data list)] [REPORT nbr]]
With the Introductory Background you’ll now be able
to understand how to use these options.
This option
identifies the input record from which data is examined for validity and
assigned if valid.
If present, the FROM option must precede the DATA option. Normally statement options may be given in any order: this is one of the rare exceptions to this general syntax rule. The reason for this exception is to enable unqualified references in DATA to be correctly qualified.
If omitted,
the input record is determined as follows: -
1. For
classical CICS programs in which INSCREEN identifies a 3270 input screen, the
input record name is the INSCREEN name. For example in the ACCEPT statement in
PROGRAM
MENU1 CICS INSCREEN(MENU1S) … ;
ACCEPT
(…);
FROM(MENU1S) is assumed.
2. For
a Web Service provider program the default input record name is the input
record defined by the service.
For a web service communicating through COMMAREA, the COMMAREA
option gives the input message name.
Thus
PROGRAM
GetTime WEBSERVICE MySvc COMMAREA(GetTimeC);
ACCEPT
(…);
FROM(GetTimeC) is assumed.
With a web service using a container, the input message name is the program name prefixed with “I”. thus with
PROGRAM
GetTime WEBSERVICE MySvc CONTAINER(GetTimeContainer);
FROM(IGetTime) is assumed.
If no FROM option is present and no value is implied (i.e. the PROGRAM statement has neither INSCREEN nor WEBSERVICE options), then the FROM option value is taken from the first assignment within the ACCEPT statement’s DATA option.
The keyword “DATA” is normally
omitted, and the data list is written immediately after the statement keyword ACCEPT. Thus you’d write
ACCEPT
(MENU1S.Function);
rather than its equivalent,
ACCEPT FROM MENU1S DATA (MENU1S.Function);
You may
name one or several items, each item being separated by a comma or OR from the
following item. If the record contains ASSIGN properties then the correspondence
between input fields and target fields is pre-specified and items may be single
field references, generic references, or assignment statements. For other types items must either be
assignment statements, or will be validated in place without assignment.
For
example,
ACCEPT (CICS2S.*);
ACCEPT (CICS2S.Function, CICS2S.Region, Wrk.Month = CICS2S.Billingcycle);
For the
assignment form, the target field must exist outside the FROM
record, while the source field must exist within it. The source field must be an INPUT or INOUT field:
for 3270 fields this is determined individually when the screen was created,
for web service COMMAREA messages
the INPUT or INOUT properties
may be specified within the definition, while for container messages the input
and output records are separately defined.
The target field determines the validation rules.
Normally
items in the data list are separated by commas: ACCEPT
(F1, F2, ….); However you can separate
them by OR, like
this: -
ACCEPT
(CICS4S.Function, CICS4S.Keyfield
OR CICS4S.Name);
OR, which
is especially designed to handle multiple keys (KEY, DKEY, and UKEY options) suppresses the normal
required-field check, but checks that at least one of the fields is
present. Key fields, and other fields
defined as REQUIRED,
must be entered, and if they are not then the ACCEPT’s validation
logic will produce a message “field:Value
Absent”. By default both Keyfield and Name
are required (because they’re keys), but in their use as alternate keys the
user will probably enter one or the other.
If you’d written
ACCEPT
(CICS4S.Function, CICS4S.Keyfield, CICS4S.Name);
Then user
would have to put a value into both.
OR and Default Values
When OR is used
the ACCEPT
statement will cause the
target fields to be initialised if they are not given a value. For example, with
ACCEPT
(CICS4S.Function, CICS4S.Account
OR CICS4S.Name);
the fields
that are related to CICS4S.Account
and CICS4S.Name, (for example CustF.Account
and Custf.Name) are set to their initial value at the start of the ACCEPT logic. Thus if no value for CICS4S.Account is entered the value of CustF.Account will remain as zero. (This is essential to make a following
statement like
GET
custf KEY(CustF.Account OR CustF.Name);
work correctly).
A generic
reference in an ACCEPT statement means “All the input
fields for which the corresponding fields exist”. Constant and output-only fields will be
ignored, as will fields that don’t have corresponding fields defined within
this program. For Classical CICS (3270)
programs you’ll write single references, like
ACCEPT (CICS2S.*);
With web
services you’ll either write generic assignment statements such as
ACCEPT
(CustF.* = IWSPG3.Custf.*);
or you’ll have defined the relationship with ASSIGN properties, as shown above, allowing you to write
ACCEPT
(IWSPG3.Custf.*);
With either form you can use EXCEPT to exclude some fields from the ACCEPT logic.
This is used with a generic reference to exclude some of the fields that might otherwise be changed. For example, here is Update logic from a Web Service: -
WHEN
(Update);
ACCEPT
(EMPLOYEE.EMPNO=IJSPG2.EMPNO) MESSAGE OJSPG2.ERROR;
GET
Employee KEY(EMPLOYEE.EMPNO) UPDATE CHECKSUM IJSPG2.CheckSum-Employee;
ACCEPT
(IJSPG2.JZ-Employee.*) EXCEPT(EMPLOYEE.EMPNO) MESSAGE OJSPG2.ERROR;
#207 I
JZ-Employee.FIRSTNME,JZ-Employee.MIDINIT,JZ-Employee.LASTNAME,JZ-Employee.WORKDEPT,JZ-Employee.PHONENO,JZ-Employee.HIREDATE,JZ-Employee.JOB,JZ-Employee.EDLEVEL,JZ-Employee.SEX,JZ-Employee.BIRTHDATE,JZ-Employee.SALARY,JZ-Employee.BONUS,JZ-Employee.COMM,JZ-Employee.CURRENCY,
included in generic assignment
END
GET Employee UPDATE RESPOND OJSPG2;
First we ACCEPT the value of the key of the record that we want to update with
ACCEPT
(EMPLOYEE.EMPNO=IJSPG2.EMPNO) MESSAGE OJSPG2.ERROR;
Then GET
Employee KEY(EMPLOYEE.EMPNO) UPDATE CHECKSUM IJSPG2.CheckSum-Employee;
ACCEPT
(IJSPG2.JZ-Employee.*) EXCEPT(EMPLOYEE.EMPNO) MESSAGE OJSPG2.ERROR;
reads the other fields from the input, and updates the Employee record, ready for the final
END
GET Employee UPDATE RESPOND OJSPG2;
which will update the record and respond. If errors are discovered by the ACCEPT, GET, or ACCEPT statement then the transaction is terminated and an error message returned.
Here you might argue that EXCEPT is unnecessary as the value of EMPLOYEE.EMPNO can’t be changed between ACCEPT and GET. True, although EXCEPT does make the program slightly more efficient. Also, Jazz can’t guarantee that you didn’t write some logic between these statements that changed the key value, which would definitely have been invalid. You should never change a record’s primary key: if you need to do this you should delete the old record and add a new one.
If you write unqualified EXCEPT references, as here
ACCEPT
(Orders.* =
IWSPG4.orders.*)
EXCEPT(OrdNbr, ORDCustid) MESSAGE OWSPG4.ERROR;
hopefully they’re resolved to the source or target record. If they’re resolved to another record then change the reference to refer to either the source (IWSPG4) or target (Orders) records, otherwise they’ll be ignored.
ACCEPT
(Orders.* =
IWSPG4.orders.*)
EXCEPT(Orders.OrdNbr, Orders.ORDCustid)
This option
is only valid when ACCEPT is used with 3270 input data.
If SETMDT is present then if ACCEPT finds one or more data errors then the Modified Data Tag is set for all
fields named in the data list. This has
the effect of ensuring that valid data that has been already entered does not
need to be re-entered as the system will automatically treat these fields as
“modified” and return them to the program on the next response when the
operator corrects the errors. This is particularly useful when data is being
added. Imagine that the user enters
values for all 6 fields, but makes an error with field E: -
ACCEPT (A,
B, C, D, E, F);
The system
responds, displaying the values of all 6 fields and an error message. The user corrects field E and clicks
[Enter]. Only field E is returned with
the message, and there may be errors because values were missing for the other
fields. However, with
ACCEPT (A,
B, C, D, E, F) SETMDT;
the
previously entered values are re-sent along with the correction for E.
Logic
resulting from
ACCEPT (CUSTNQY.Account) EXIT;
is: -
·
Check
that CUSTNQY.Account is valid for assignment to the
corresponding field CUSTF.Account;
·
IF
it is valid *, then copy the value from CUSTNQY.Account into CUSTF.Account, converting it from the CHAR format of the screen to whatever
format CUSTF.Account
requires
·
ELSE Set error messages, redisplay the screen, and
exit from the program
* Invalid values MAY be assigned. If a field passes initial checks (something
present, numeric if required) then it is assigned to the target field before
remaining checks such as RANGE are done.
See below.
Thus with
this logic statements following the ACCEPT won’t be executed.
On the
other hand,
ACCEPT (CUSTNQY.Account) CONTINUE;
does not
exit from the program, but instead execution continues with the next Jazz
statement.
Usually
neither CONTINUE nor EXIT is specified, and Jazz determines
which rule to assume based on the Error Message Field. See MESSAGE
(field name) I NOMESSAGE below for details.
·
If
there is no Error Message Field, or the field is in a record whose type is
neither SCREEN nor SERVICE, then CONTINUE is
used. Thus in situation 1 where ACCEPT is used with internal data: -
ACCEPT (Wrk.A = Wrk.B);
Jazz assumes CONTINUE.
·
Where ErrorField is in a definition that has type SCREEN or SERVICE then EXIT will be used.
MESSAGE allows you to name a field to receive the
messages. For web services and 3270
screens there will be a warning message if this field is not in the output
message.
NOMESSAGE specifies that there is no validation-message
field.
If neither
of MESSAGE nor NOMESSAGE are
given ACCEPT
will look for a field called “Error” in the output message.
If there is
no validation-message field, either because NOMESSAGE is
specified or because “Error” couldn’t be found, the ACCEPT
will still validate the data and you can test whether errors were found using
the BOOLEAN field $Error (which will be qualified to JZ.$Error): -
ACCEPT (data list)
IF JZ.$Error
THEN;
… errors were found
END
IF
Or alternatively
IF JZ.$Error
= false THEN;
… no errors were found
END
IF
Use this
option when you want an error message to be produced if none of the fields in
the ACCEPT
list have data. For example: -
WHEN (Update, Add);
GET
custf WHERE(CustF.Account=CICS2C.Save.Account) UPDATE CHECKCOPY(CICS2C.SAVE);
ACCEPT
(CICS2S.Region,CICS2S.District,CICS2S.Name,CICS2S.SalesThisMonth,
CICS2S.SalesYTD,CICS2S.Billingcycle,CICS2S.DateCommenced) UPDATE;
UPDATE
custf;
CICS2S.error
= 'Update/Addition
successful. Get next record or exit';
CICS2C.Function
= Enquiry;
If none of
the screen fields in the data list have been changed then an error message: -
“No data entered”
is
displayed, and (unless you add CONTINUE) the ACCEPT program
terminates the program with the screen re-displayed.
EPRINT, meaning “Error
Print”, is only valid when ACCEPT is used in a batch program. For
example: -
PROCESS custf INDEX JZ.IX1;
ACCEPT(CustF.*) EPRINT;
END PROCESS custf;
Here ACCEPT(CustF.*) validates that all the fields of CustF conform
to their definition. If there is an
error, then EPRINT causes a report
line to be written: -
*COUNT* Account
*------------------------------------------------------EPrint------------------------------------------------------*
50 000050 Billingcycle:Outside
Code Range
…
291 000291 Billingcycle:Outside
Code Range
* * * END OF RepNbr1 * * *
The line
identifies the field name (Billingcycle) and the
error (Outside Code Range), but this would be little help without identifying
which record contains this invalid CustF.Billingcycle value. EPRINT therefore
defaults to printing the counter calculated by the INDEX option of the PROCESS statement, and the primary key of
the CustF record.
When this data is not available, or not
suitable, you can explicitly specify which fields you want to be printed to the
left of the error message: -
ACCEPT(CustF.*) EPRINT(CustF.Account, CustF.Region);
Account Region *------------------------------------------------------EPrint------------------------------------------------------
000050 0000 Billingcycle:Outside Code Range
As with a PRINT statement, you can specify the report number if you wish to keep this
printing separate from other printed output from your program: -
ACCEPT(CustF.*) EPRINT(CustF.Account, CustF.Region) REPORT 2;
ACCEPT
checks data based on the definition of the target
field. For example, with
ACCEPT
(Wk2.f2 = InputMessage.F2);
Validation
is controlled by the definition of Wk2.f2 not InputMessage.F2.
Any options such as RANGE, CODES etc associated with InputMessage.F2 are ignored.
For each
field named (directly or implied by a generic reference) in the data list, ACCEPT
applies the following logic.
Particularly
with generic ACCEPT
statements one or several of the input fields may be missing. For example, here we’ve defined a Web Service
with an input message like this: -
DEFINE IJSPG2 SERVICE INPUT DATA(
Function CHAR(1) CAPS CODES(E:Enquiry,U:Update,A:Add,D:Delete)
VALUE Enquiry,
JZ-employee-Skip SMALLINT
VALUE 0,
JZ-employee GROUP,
EMPNO LIKE EMPLOYEE.EMPNO ASSIGN
EMPLOYEE.EMPNO,
FIRSTNME LIKE EMPLOYEE.FIRSTNME ASSIGN
EMPLOYEE.FIRSTNME,
MIDINIT LIKE EMPLOYEE.MIDINIT ASSIGN
EMPLOYEE.MIDINIT,
LASTNAME LIKE EMPLOYEE.LASTNAME ASSIGN
EMPLOYEE.LASTNAME,
…
END GROUP,
ViewState GROUP, [Must not be changed
CheckSum-employee CHAR(40),
END GROUP);
We’re using this SOAPUI test: -
To test
this ACCEPT statement
ACCEPT (IJSPG2.JZ-employee.*)
EXCEPT(EMPLOYEE.EMPNO) MESSAGE OJSPG2.ERROR;
In IJSPG2.JZ-Employee the only fields given values are EMPNO and FIRSTNME, all other fields are absent. The program has read the EMPLOYEE record for EMPNO=90, and it’s now executing ACCEPT (IJSPG2.JZ-employee.*) … Obviously the intention is to update FULLNME, and we want MIDINIT and other absent fields to remain unchanged, so ACCEPT is designed to ignore absent fields. It detects absent fields by one of three rules: -
1. INSCREEN input, i.e. from a 3270 screen. The program checks the MDT (modified data tag), which means that the operator has keyed something into the field. This value might be a blank or zero.
For other input types, fields are considered absent if they have their default value. If their definition contains VALUE this gives their default value, in the absence of VALUE numbers have default value 0, and CHAR fields have default value blank.
2.
Web Service Input Data (like IJSPG2). Data is read in format CHAR, so initial value (blank) or
binary zero (COBOL: LOW-VALUE) field means “absent”. All the values in the test above given as
"LASTNAME"
: "",
are received as a blank value in the corresponding Jazz (=COBOL) field. However if this highlighted line of JSON were
removed it would be received as LOW-VALUE.
3. Other input. If the input field has a VALUE clause, this gives its initial value, otherwise its initial value is zero or blank.
Note that
you may still get error messages relating to absent fields. SEX has been
defined with
SEX CHAR(1) CAPS CODES(M:Male, F:Female),
Imagine that the record for EMPNO=150 has an invalid SEX value. You may still get messages about an invalid SEX value, because this ACCEPT test hasn’t changed the previous, invalid, value.
We’ve just updated FIRSTNME, but how do we set it back to blanks. If IJSPG2.FIRSTNME has a blank value it will be regarded as “Absent”, so an ACCEPT statement like
ACCEPT
(EMPLOYEE.FIRSTNME = IJSPG2.FIRSTNME);
will leave the value of EMPLOYEE.FIRSTNME unchanged.
To clear EMPLOYEE.FIRSTNME, setting it to blanks, IJSPG2.FIRSTNME can have one of three special values, NULL, VALUE, or SPACE.
·
NULL
sets the target value to blank or zero.
If the target has format VARCHAR then its
length will be set to zero. If the
target is a field with a null indicator (definition type SQL, not REQUIRED) then
the null indicator is set to -1 meaning “Null”.
·
VALUE
sets the target value to that defined explicitly or by default in the field’s VALUE property.
This is usually the same as NULL.
·
SPACE
sets the target value to blanks (if CHAR or VARCHAR), or zero (if numeric).
NULL, VALUE,
and SPACE are only recognised by ACCEPT as
special values if they are written in upper case. Null is simply a 4-character value.
If there is
an explicit or implied assignment then the input field must be able to be
assigned to the target. For example, an
input character field with value ‘ABC’ can’t be assigned to a number. However if the field is validated in place,
as in
ACCEPT (IJSPG2.Function) MESSAGE OJSPG2.ERROR;
#052 W Item IJSPG2.Function will be validated, but not moved from the
input record
then this
section is skipped, but further validity
checks are still applied.
Field Type |
Checks |
CHAR |
Value too long for the target field (1) |
VARCHAR |
Value too long for the target field (1) |
Any Number(2) |
Value must be numeric. If the input field is not already numeric, then Jazz checks that the character-format input field can be converted to a number. Jazz will trim the character string dropping leading and trailing blanks to a minimum length of 1 character. If the numeric check succeeds then the value is assigned to the target field, where further checks (RANGE etc) may occur. |
DATE fields |
A DATE is an eight-digit number representing year, month, and day, for example 25th January 2018 would have numeric value 20180125. ACCEPT (DateField=SourceField) validates that SourceField can be converted to a valid date: - · If SourceField is a numeric field or DATE then its value must be from 10000101 to 99991231, digits 5-6 must be 01 to 12, and digits 7-8 must be 01 to the month’s limit. · If SourceField is a string (CHAR or VARCHAR), the value is interpreted according to DateField’s DPIC. Click JazzUGDate.htm for more information. |
Other field types |
The value will be checked for
its format (e.g. a TIME value must be a valid time in format hh:mm:ss:mmm – hours, minutes, seconds, milliseconds), |
Notes
1.
This
should be impossible if the screen was generated by Jazz by dragging the field
on to it, and neither the screen definition nor the record definition has
subsequently been modified. The input
value will be truncated.
2.
“Any
Number” means types TINYINT, SMALLINT, INTEGER, BIGINT, DECIMAL, MONEY, FLOAT, LONG, PIC, plus implied numbers such as the indexes of CODES fields.
If the data
passes this initial check, then it is assigned to the target field. It is checked further if the Jazz definition
requires further validation.
Note that this
means data CAN be invalid after an ACCEPT, although you will have been
informed through the MESSAGE field and/or $Error. For example, with this program
PROGRAM
LogicV2C BATCH;
DEFINE
W DATA(Message VARCHAR(80));
DEFINE
In DATA
(Region DECIMAL(3),
State CHAR(2));
COPY
Types;
DEFINE
Out DATA
(Region DECIMAL(3) RANGE(1:10),
State LIKE Types.US-State);
In.Region
= 123;
In.State
= 'xx';
ACCEPT(Out.*= In.*) MESSAGE W.Message;
#207 I Region,State, included in generic
assignment
PRINT(Out.*, W.Message)
FIELDTABLE;
both Region
and State have compatible formats, and so are moved to Out, even though ACCEPT
reports errors because Out.Region is defined with RANGE(1:10) and so 123 is outside this range, and Types.US-State is defined with a table of valid state codes. However neither is valid, and the PRINT
statement reports
Field Name
PR-LTH VALUE
Out.Region: 4: 123
Out.State
: 17:xx/**************
W.Message
: 46:Region outside valid range;
State Invalid Code*
If the field has passed its initial format checks it is
assigned to the target field, which is then checked according to any optional
attributes like CHECKR, CODES, RANGE, VALUES, WHERE etc. Refer to JazzLRM_Data.htm for
descriptions of these options.
If the
field is not valid, then
A. ACCEPT from 3270 screen
1.
Its
associated “Error Indicator” character is set to “*”.
2.
Its
length is set to -1 so that the cursor will be positioned at the start of the
field. If there are several invalid fields then the cursor will be positioned
at the first of them.
B. All ACCEPT statements with a message field
being explicitly or implicitly defined
3.
An
error message such as “Account NOT NUMERIC” is written to the message
field. If there are several incorrect
fields then each error is added to the message field: if there is insufficient
room then later errors will be lost.
C. All ACCEPT statements
4.
An
error flag is set that can be tested with
IF
JZ.$Error THEN;
When all
fields in the list have been checked, then if there are any errors and also the
CONTINUE option is not used then program exits. With 3270 input, the screen is sent back to
the terminal with an alarm.
If you use CONTINUE with 3270 input then the screen will be set up
with the error-indicator and error message, and you can send it later. You can
test whether there was an error with a condition using $Error. You’ll write “$Error”, but this will be
qualified to JZ.$Error. For example: -
ACCEPT (CUSTNQY.Account) CONTINUE;
…
If JZ.$Error = ‘Y’ THEN
…
However this
field refers to the most recent ACCEPT statement. If you write
ACCEPT (CUSTNQY.A) CONTINUE;
ACCEPT (CUSTNQY.B) CONTINUE;
ACCEPT
(CUSTNQY.C);
If JZ.$Error THEN
…
this will
refer ONLY to ACCEPT
(CUSTNQY.C);, and so the condition will be false if A and/or B are
invalid but C is OK. You should define your own BOOLEAN
field and save the value of $Error after each ACCEPT: -
DEFINE
T DATA(EFlag BOOLEAN);
ACCEPT
(CUSTNQY.A) CONTINUE;
IF
JZ.$Error THEN;
T.EFlag
= True;
END
IF;
ACCEPT
(CUSTNQY.B) CONTINUE;
IF
JZ.$Error THEN;
T.EFlag
= True;
END
IF;
ACCEPT
(CUSTNQY.C);
IF
JZ.$Error THEN;
T.EFlag
= True;
END
IF;
IF
T.EFlag THEN;
…
In the absence of appropriate logic a record can be updated with invalid data. For example
GET EMPLOYUP … UPDATE …;
ACCEPT … CONTINUE …;
END
GET EMPLOYUP UPDATE …;
If the
ACCEPT found with data that has the correct format then the EMPLOYUP field in
memory will have been updated. 2nd-stage
validity checks may then have discovered and reported an error, but because of CONTINUE processing continues with END GET EMPLOYUP UPDATE …, updating the record.