The SUBPROGRAM statement marks the start of a Jazz subprogram, and describes its environment. A subprogram is a program that is invoked via CALL, LINK or TRANSFER from a program or another subprogram, possibly with parameters. You may have only one SUBPROGRAM statement in a subprogram.
Its format is: -
SUBPROGRAM subprogram-name [Options]…
A SUBPROGRAM statement should be preceded by the subprogram’s interface definition, i.e. a DEFINE statement describing its parameters. For example before SUBPROGRAM SubPR; there should be
which brings in code like this: -
DEFINE SubPR PARAMETERS DATA(
If the SUBPROGRAM is passed no arguments then the DEFINE should specify an empty DATA option, e.g.
DEFINE SubPR PARAMETERS DATA();
You’ll also include COPY Subpr; in programs with CALL SubPR so that Jazz can guarantee that the CALL is passing correctly-formatted data as arguments.
Note that COPY, SUBPROGRAM, and DEFINE all use the same name, SubPR in this example.
If the interface definition includes TYPE(PARAMETERS CICS) then the subprogram may only be used within the CICS on-line environment. The subprogram may not use physical-sequential files (types F, FB, V, VB, and U), or PRINT or REPORT statements.
If the interface definition includes TYPE(PARAMETERS BATCH) then the subprogram may only be used within the batch environment. It can process physical-sequential files (types F, FB, V, VB, and U) as well as VSAM and SQL that can also be processed by CICS. The program cannot use CICS options like INSCREEN, nor statements like SEND and ACCEPT that deal with screens, nor deal with CICS-only file types like TS (temporary storage)
If neither BATCH nor CICS is specified then the subprogram may be used in either environment, but it may not use any batch-specific statements (PRINT or REPORT), nor CICS-specific statements(SEND, ACCEPT), nor use any I/O statements (PROCESS, GET, WRITE, DELETE) as these generate different code in different environments.
It must follow the rules for external names: i.e. be 8 characters or less, and not contain hyphens or special characters like “$”. It must be unique: it cannot be the same as any other “Level 1 name” (file names etc).
Specifies that the SubProgram may be used only from Batch programs (including CALL from subprograms). The associated interface definition must not specify CICS with TYPE(PARAMETERS CICS), but must either specify BATCH or leave both BATCH and CICS out.
If BATCH is specified then the Subprogram may not contain any CICS-Specific statements (SEND, ACCEPT, LINK, TRANSFER). It may contain I/O statements (PROCESS, GET, WRITE, DELETE, PRINT), but if so you will have to manage the opening and closing of the relevant files yourself. Refer to the notes below.
Specifies that the SubProgram may be used only from CICS programs (including CALL from subprograms). It may contain CICS-specific statements like SEND, ACCEPT, LINK, TRANSFER, but may not contain batch-specific statements (e.g. PRINT).
If neither BATCH nor CICS is specified then the subprogram may be used from either environment, but it must not use either CICS-Specific or Batch-specific statements, not use any I/O statements (as these generate different code in the different environments).
Specifies that the subprogram will be invoked with CALL statements. CALL is assumed if neither CALL nor LINK are specified.
Specifies that the program will be invoked by LINK or TRANSFER statements. This implies that the subprogram will be used in the CICS environment: CICS will be assumed if it is not specified, and SUBPROGRAM xxx BATCH LINK; will result in an error message.
If your batch subprogram uses I/O statements (PROCESS, GET, WRITE, DELETE, PRINT) then you need to understand a few things about files that Jazz can normally hide from you.
PROCESS InFile1 WHERE (….);
END PROCESS InFile1;
This program will print every record from InFile1. At the beginning of the program COBOL executes a statement “OPEN INPUT InFile1.” so that the file InFile1 is opened, making it ready for following READ statements. The first READ will get the first record, the next the second, and so on. To go back and read from the beginning again, a COBOL program could execute “CLOSE InFile.” and then re-execute “OPEN INPUT InFile1.”. You’d try to avoid logic like this because OPEN is a relatively costly statement and you wouldn’t want to be executing CLOSE and OPEN within a loop as your program.
Since you’re writing Jazz you don’t normally need to concern yourself with OPEN and CLOSE statements as Jazz generates them for you, putting and OPEN statement within the first-time execution code, and leaving it to the system to close the file when the job step terminates. However if you were to write similar logic within a subprogram then
· As with a program, the file will be left open when the subprogram exits. If you re-enter the subprogram (e.g., it is called more than once) processing will resume where you left off. This is no problem for a GET statement, but PROCESS is likely to already be at the end of the file and no more records will be read.
· File names are common throughout the whole program, so that if (for example) InFile1 is referenced in both the main program and the subprogram, or two different subprograms, then all references are to the same file and the actions in one subprogram/program can affect the behaviour in others. There won’t be problems with direct access, but don’t use sequential logic.
· This commonality applies to reports as well: if the subprogram also prints to Report(1), then it will also be using file Report1. Printing will be messed up, as each object will have its own print routine that counts lines and decides when to print headings. Avoid this by ensuring that each subprogram uses a different report.