The END Statement

END closes a “block”, i.e. a group of logically-related statements. 

Format:

END statement-keyword [File-Name] {[UPDATE] | [ADD] | [REWRITE]} [RESETFUNCTION]

      [UNTIL (condition)];

 

The File-Name is not given if the END closes IF, CASE, or another statement that is not associated with a particular file. It is required when END closes a PROCESS or GET block.

 

UNTIL is only valid with END FOR statements. Refer to the FOR Statement to find out about this option.

 

UPDATE, ADD, or REWRITE may be given when the END statement closes a GET block, and the GET statement has an UPDATE option. Refer to the GET statement for a description of how these options work.

 

UPDATE is also valid with an END PROCESS statement, but only when the input file has type VSAM.

 

For example: -

PROCESS File1 WHERE (File1.Balance > 1000);

    PRINT (File1.Name, File1.Balance);

END PROCESS File1;

 

Jazz checks that the END is correctly matched: for example END IF must follow an unclosed IF statement. Code like this is incorrect and will produce error messages: -

PROCESS File1 WHERE (File1.Balance > 1000);

    PRINT (File1.Name, File1.Balance);

    IF File1.Previous-Balance > File1.Balance THEN;

        PRINT (‘Customer is loosing money’);

END PROCESS File1;

RESETFUNCTION

(Classical CICS programs only).  Here is part of an update program.  Following the GET for enquiry the program sets the next function and a message to tell the user what do to.  There is similar code setting the next function and a message for the Update, Add, and Delete cases.

PROGRAM CICS2 CICS INSCREEN(CICS2S) TRANSID(TRN2) COMMAREA(CICS2C) EXIT(menu1);

ACCEPT (CICS2S.Function);

CASE (CICS2C.Function);

    WHEN (Enquiry);

        ACCEPT (CICS2S.Account OR CICS2S.Name);

        DEFINE TS1 TYPE(TS) DATA(

            Account LIKE CustF.Account);

        GET custf KEY(CustF.Account OR CustF.Name) SAVECOPY CICS2C.SAVE TS(1);

        #373 I GET statement returns one record at a time for Name

        IF  custf.$Found = 'Y' THEN;

            CICS2S.error = 'Record Found. Use Update to change it';

        ELSE;

            CICS2S.error = 'Record not found. Use Add to create it';

        END IF;

    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;

        END GET custf UPDATE;

        CICS2S.error = 'Update/Addition successful. Get next record or exit';

        CICS2C.Function = Enquiry;

    WHEN (Delete);

        DELETE custf WHERE(CustF.Account=CICS2C.Save.Account) CHECKCOPY(CICS2C.SAVE);

        CICS2S.error = 'Deletion successful. Get next record or exit';

        CICS2C.Function = Enquiry;

END CASE;

SEND Inscreen;

 

RESETFUNCTION generates this code automatically for you.  Thus you can shorten the above program like this: -

PROGRAM CICS2 CICS INSCREEN(CICS2S) TRANSID(TRN2) COMMAREA(CICS2C) EXIT(menu1);

ACCEPT (CICS2S.Function);

CASE (CICS2C.Function);

    WHEN (Enquiry);

        ACCEPT (CICS2S.Account OR CICS2S.Name);

        DEFINE TS1 TYPE(TS) DATA(

            Account LIKE CustF.Account);

        GET custf KEY(CustF.Account OR CustF.Name) SAVECOPY CICS2C.SAVE TS(1) RESETFUNCTION;

        #373 I GET statement returns one record at a time for Name

    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 RESETFUNCTION;

    WHEN (Delete);

        DELETE custf WHERE(CustF.Account=CICS2C.Save.Account) CHECKCOPY(CICS2C.SAVE) RESETFUNCTION;

END CASE;

SEND Inscreen;

Not only is your program more concise, it is more correct as the same enquiry messages are provided when you move through a set of records with PF7/8 or PF10/11.  Its disadvantage is that you have to accept the built-in messages and function transitions.

 

The RESETFUNCTION option is only valid in classical CICS programs. The PROGRAM statement must name the input screen with INSCREEN, and this screen must contain a message field called “Error” and a Function field defined from a Commarea field that has been defined like this: -

DEFINE CICS2C TYPE(COMMAREA) DATA(

    Function CHAR(1) CODES (E:Enquiry,U:Update,A:Add,D:Delete) VALUE 'E',