Created on Feb. 24, 2025, 7:14 p.m. - by Daniel, Perez Ojeda
Hello, I'm starting to study COBOL and everything involved.
I'm practicing with the book COBOL Basic Training (by Robert Wingate) using Hercules and OS/390, and I encountered a problem trying to get the results of one of the programs where it reads the data from one file, saves the same data but in binary format and makes a report. If I don't save the report the output file with the binary data is saved properly, but if the report is saved bot files end up with the same data the one for the report. I'm almost sure the problem is with the JCL, because I can't find any problem with the COBOL logic.
Here's the code and 2 JCL alternatives I tried.
IDENTIFICATION DIVISION.
PROGRAM-ID. COBTRN4A.
****************************************************
* PROGRAM USING FILE INPUT AND OUTPUT *
* TO REFORMAT EMPLOYEE PAY INFORMATION *
* ALSO PRODUCES A REPORT OF THE INFORMATION *
****************************************************
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT EMPLOYEE-IN-FILE ASSIGN TO EMPIFILE.
SELECT EMPLOYEE-OUT-FILE ASSIGN TO EMPOFILE.
SELECT REPORT-OUT-FILE ASSIGN TO EMPREPRT.
DATA DIVISION.
FILE SECTION.
FD EMPLOYEE-IN-FILE
RECORDING MODE IS F
LABEL RECORDS ARE STANDARD
RECORD CONTAINS 80 CHARACTERS
BLOCK CONTAINS 0 RECORDS
DATA RECORD IS EMPLOYEE-RECORD-IN.
01 EMPLOYEE-RECORD-IN.
05 E-ID PIC X(04).
05 FILLER PIC X(76).
FD EMPLOYEE-OUT-FILE
RECORDING MODE IS F
LABEL RECORDS ARE STANDARD
RECORD CONTAINS 80 CHARACTERS
BLOCK CONTAINS 0 RECORDS
DATA RECORD IS EMPLOYEE-RECORD-OUT.
01 EMPLOYEE-RECORD-OUT.
05 EMP-DATA PIC X(80).
FD REPORT-OUT-FILE
RECORDING MODE IS F
LABEL RECORDS ARE STANDARD
RECORD CONTAINS 80 CHARACTERS
BLOCK CONTAINS 0 RECORDS
DATA RECORD IS REPORT-RECORD-OUT.
01 REPORT-RECORD-OUT.
05 RPT-DATA PIC X(80).
WORKING-STORAGE SECTION.
01 WS-FLAGS.
05 SW-END-OF-FILE-SWITCH PIC X(1) VALUE 'N'.
88 SW-END-OF-FILE VALUE 'Y'.
88 SW-NOT-END-OF-FILE VALUE 'N'.
01 IN-EMPLOYEE-RECORD.
05 EMP-ID-IN PIC X(04).
05 FILLER PIC X(05).
05 REG-PAY-IN PIC 99999V99.
05 FILLER PIC X(02).
05 BON-PAY-IN PIC 9999V99.
05 FILLER PIC X(54).
01 OUT-EMPLOYEE-RECORD.
05 EMP-ID-OUT PIC S9(9) USAGE COMP.
05 FILLER PIC X(05).
05 REG-PAY-OUT PIC S9(6)V9(2) USAGE COMP-3.
05 FILLER PIC X(02).
05 BON-PAY-OUT PIC S9(6)V9(2) USAGE COMP-3.
05 FILLER PIC X(59) VALUE SPACES.
01 DISPLAY-EMPLOYEE-PIC.
05 DIS-REG-PAY PIC 99999.99.
05 DIS-BON-PAY PIC 9999.99.
01 HDR-LINE-01.
05 FILLER PIC X(25) VALUE SPACES.
05 FILLER PIC X(30)
VALUE 'EMPLOYEE ANNUAL SALARY REPORT '.
05 FILLER PIC X(25) VALUE SPACES.
01 HDR-LINE-02.
05 FILLER PIC X(25) VALUE SPACES.
05 FILLER PIC X(30)
VALUE '----------------------------- '.
05 FILLER PIC X(25) VALUE SPACES.
01 SPC-LINE PIC X(80) VALUE SPACES.
01 DTL-HDR-01.
05 FILLER PIC X(25) VALUE SPACES.
05 FILLER PIC X(06) VALUE 'EMP-ID'.
05 FILLER PIC X(03) VALUE SPACES.
05 FILLER PIC X(08) VALUE 'REGULAR '.
05 FILLER PIC X(04) VALUE SPACES.
05 FILLER PIC X(08) VALUE 'BONUS '.
05 FILLER PIC X(19) VALUE SPACES.
01 DTL-HDR-02.
05 FILLER PIC X(25) VALUE SPACES.
05 FILLER PIC X(06) VALUE '------'.
05 FILLER PIC X(03) VALUE SPACES.
05 FILLER PIC X(08) VALUE '--------'.
05 FILLER PIC X(04) VALUE SPACES.
05 FILLER PIC X(08) VALUE '--------'.
05 FILLER PIC X(19) VALUE SPACES.
01 DTL-LINE.
05 FILLER PIC X(27) VALUE SPACES.
05 RPT-EMP-ID PIC 9(04).
05 FILLER PIC X(03) VALUE SPACES.
05 RPT-REG-PAY PIC 99999.99.
05 FILLER PIC X(04) VALUE SPACES.
05 RPT-BON-PAY PIC 99999.99.
05 FILLER PIC X(10) VALUE SPACES.
01 TRLR-LINE-01.
05 FILLER PIC X(26) VALUE SPACES.
05 FILLER PIC X(30)
VALUE ' END OF ANNUAL SALARY REPORT '.
05 FILLER PIC X(24) VALUE SPACES.
PROCEDURE DIVISION.
PERFORM P100-INITIALIZATION.
PERFORM P200-MAINLINE.
PERFORM P300-TERMINATION.
GOBACK.
P100-INITIALIZATION.
DISPLAY 'COBTRN4 - SAMPLE COBOL PROGRAM: I/O AND REPORTS'.
OPEN INPUT EMPLOYEE-IN-FILE.
OPEN OUTPUT EMPLOYEE-OUT-FILE.
OPEN OUTPUT REPORT-OUT-FILE.
INITIALIZE IN-EMPLOYEE-RECORD, OUT-EMPLOYEE-RECORD.
WRITE REPORT-RECORD-OUT FROM HDR-LINE-01.
WRITE REPORT-RECORD-OUT FROM HDR-LINE-02.
WRITE REPORT-RECORD-OUT FROM SPC-LINE.
WRITE REPORT-RECORD-OUT FROM DTL-HDR-01.
WRITE REPORT-RECORD-OUT FROM DTL-HDR-02.
P200-MAINLINE.
* MAIN LOOP - READ THE INPUT FILE, LOAD THE OUTPUT
* STRUCTURE AND WRITE THE RECORD TO OUTPUT.
SET SW-NOT-END-OF-FILE TO TRUE.
READ EMPLOYEE-IN-FILE INTO IN-EMPLOYEE-RECORD
AT END SET SW-END-OF-FILE TO TRUE
END-READ
PERFORM UNTIL SW-END-OF-FILE
* MOVE FIELDS
MOVE EMP-ID-IN TO EMP-ID-OUT, RPT-EMP-ID
MOVE REG-PAY-IN TO REG-PAY-OUT, DIS-REG-PAY, RPT-REG-PAY
MOVE BON-PAY-IN TO BON-PAY-OUT, DIS-BON-PAY, RPT-BON-PAY
DISPLAY ' EMP-ID: ' EMP-ID-OUT
DISPLAY ' REG-PAY: ' DIS-REG-PAY
DISPLAY ' BON-PAY: ' DIS-BON-PAY
WRITE EMPLOYEE-RECORD-OUT FROM OUT-EMPLOYEE-RECORD
WRITE REPORT-RECORD-OUT FROM DTL-LINE
READ EMPLOYEE-IN-FILE INTO IN-EMPLOYEE-RECORD
AT END SET SW-END-OF-FILE TO TRUE
END-READ
END-PERFORM.
P300-TERMINATION.
WRITE REPORT-RECORD-OUT FROM SPC-LINE
WRITE REPORT-RECORD-OUT FROM TRLR-LINE-01
CLOSE EMPLOYEE-IN-FILE,
EMPLOYEE-OUT-FILE,
REPORT-OUT-FILE
DISPLAY 'COBTRN4 - SUCCESFULLY ENDED.'.
JCL 1:
//COBTRN4A JOB 'IBMUSER','DANIEL',CLASS=A,MSGLEVEL=(1,1),NOTIFY=$SYSUID
//STEP01 EXEC PGM=COBTRN4A
//STEPLIB DD DSN=DANIELPO.COBOL.LOAD,DISP=SHR
//SYSOUT DD SYSOUT=*
//EMPIFILE DD DSN=DANIELPO.SOURCE.DATA(EMPAY),DISP=SHR
//EMPOFILE DD DSN=DANIELPO.SOURCE.DATA(EMPAYOUT),DISP=(OLD,KEEP,KEEP)
//EMPREPRT DD DSN=DANIELPO.SOURCE.DATA(EMPREPRT),DISP=OLD
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSOUT DD SYSOUT=*
//
JCL 2:
//COBTRN4A JOB 'IBMUSER','DANIEL',CLASS=A,MSGLEVEL=(1,1),NOTIFY=$SYSUID
//STEP01 EXEC PGM=COBTRN4A
//STEPLIB DD DSN=DANIELPO.COBOL.LOAD,DISP=SHR
//SYSOUT DD SYSOUT=*
//EMPIFILE DD DSN=DANIELPO.SOURCE.DATA(EMPAY),DISP=SHR
//EMPOFILE DD DSN=DANIELPO.SOURCE.DATA(EMPAYOUT),DISP=(OLD,KEEP,KEEP)
//EMPRFILE DD DSN=DANIELPO.SOURCE.DATA(EMPREPRT),DISP=OLD
//SYSPRINT DD SYSOUT=*
//SYSOUT DD SYSOUT=*
//
EMPAY File:
1111 8700000 670000
1122 8200000 600000
3217 6500000 550000
4175 5500000 150000
4720 8000000 250000
4836 6200000 220000
6288 7000000 200000
7459 8500000 450000
9134 7500000 250000