OpenCOBOL can't find my external module to run the program - cobol

I'm trying to create a COBOL program using OpenCobol that has an external module when it does a calculation and then brings the result back into the main program using CALL. But everytime I try to run the program it says it can't find the module. I have already changed my module to Program Type "Module" from executable and I have added the module path as a Library path but nothing is working so far
Here is my main program code:
PROGRAM-ID. Project2 AS "Project2".
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
*****The student input file
SELECT STUDENT-FILE-IN
ASSIGN TO "C:\STUFILE.TXT"
ORGANIZATION IS LINE SEQUENTIAL.
*****The program input file
SELECT PROGRAM-FILE-IN
ASSIGN TO "C:\PROGRAM.TXT"
ORGANIZATION IS LINE SEQUENTIAL.
*****The student report output file
SELECT STUDENT-REPORT-FILE-OUT
ASSIGN TO "C:\REPORT.TXT"
ORGANIZATION IS LINE SEQUENTIAL.
DATA DIVISION.
FILE SECTION.
*Student input file
FD STUDENT-FILE-IN.
01 STUDENT-RECORD.
05 STUDENT-NUMBER PIC 9(6).
05 TUITION-OWED-IN PIC 9(4)V99.
05 STUDENT-NAME-IN PIC X(40).
05 PROGRAM-OF-STUDY PIC X(5).
05 COURSE-CODE-1 PIC X(7).
05 COURSE-AVERAGE-1 PIC 9(3).
05 COURSE-CODE-2 PIC X(7).
05 COURSE-AVERAGE-2 PIC 9(3).
05 COURSE-CODE-3 PIC X(7).
05 COURSE-AVERAGE-3 PIC 9(3).
05 COURSE-CODE-4 PIC X(7).
05 COURSE-AVERAGE-4 PIC 9(3).
05 COURSE-CODE-5 PIC X(7).
05 COURSE-AVERAGE-5 PIC 9(3).
*Program input file
FD PROGRAM-FILE-IN.
01 PROGRAM-RECORD-IN.
05 PROGRAM-CODE-IN PIC X(5).
05 PROGRAM-NAME-IN PIC X(20).
*Student report output file
FD STUDENT-REPORT-FILE-OUT.
01 STUDENT-REPORT-RECORD-OUT PIC x(90).
WORKING-STORAGE SECTION.
*Table to hold program records
01 PROGRAM-RECORD.
05 PROGRAM-TABLE.
10 PROGRAM-CODE PIC X(5) OCCURS 20 TIMES.
10 PROGRAM-NAME PIC X(20) OCCURS 20 TIMES.
*The student report record
01 STUDENT-REPORT-RECORD.
05 STUDENT-NAME PIC X(40).
05 FILLER PIC X(2) VALUE SPACES.
05 PROGRAM-NAME-OUT PIC X(20).
05 FILLER PIC X(4) VALUE SPACES.
05 TUITION-OWED PIC Z,ZZ9.99.
*A line to make the output look good
01 HEADER-LINE.
05 FILLER PIC X(90) VALUE ALL "-".
*The column header
01 COLUMN-HEADER.
05 NAME-COLUMN PIC X(42) VALUE "NAME".
05 AVG-COLUMN PIC X(7) VALUE "AVE".
05 PROG-COLUMN PIC X(24) VALUE "PROGRAM NAME".
05 OWED-COLUMN PIC X(12) VALUE "TUITION OWED".
01 CONTROL-FIELDS.
05 STUFILE-EOF-FLAG PIC A(3).
05 PROG-EOF-FLAG PIC A(3).
05 PROG-SUB PIC 9(2).
05 FOUND-PROG-FLAG PIC A(3).
01 COUNTERS.
05 STUDENT-RECORDS-READ-CTR PIC 9(3).
05 STUDENT-REPORTS-WRITTEN-CTR PIC 9(3).
01 WW-SEND-AREA.
05 STUDENT-AVERAGE PIC 9(3).
01 WW-SUB-PROG PIC X(75)
VALUE 'C:\Users\google\Program3Call'.
PROCEDURE DIVISION.
PERFORM 200-INITIALIZATION-RTN.
*Read and process all student records
PERFORM 200-PROCESS-STUDENT-RECORD-RTN
UNTIL STUFILE-EOF-FLAG = "YES".
PERFORM 200-FINISH-RTN.
STOP RUN.
200-INITIALIZATION-RTN.
PERFORM 300-OPEN-FILES-RTN.
*****Load all program records into the table
PERFORM 300-LOAD-PROGRAM-TABLE-RTN
VARYING PROG-SUB FROM 1 BY 1
UNTIL PROG-SUB > 20 OR PROG-EOF-FLAG = "YES".
PERFORM 300-INITIALIZE-REPORT-FILE-RTN.
PERFORM 300-INITIALIZE-COUNTERS-RTN.
200-PROCESS-STUDENT-RECORD-RTN.
PERFORM 300-READ-STUDENT-RECORD-RTN.
IF STUFILE-EOF-FLAG NOT EQUALS "YES"
*********Get the program name
PERFORM 300-GET-PROGRAM-NAME-RTN
VARYING PROG-SUB FROM 1 BY 1 UNTIL
FOUND-PROG-FLAG = "YES" OR PROG-SUB > 20
PERFORM 300-GET-STUDENT-AVERAGE
PERFORM 300-PRINT-STUDENT-REPORT-RTN
END-IF.
200-FINISH-RTN.
PERFORM 300-PRINT-COUNTERS-RTN.
PERFORM 300-CLOSE-FILES-RTN.
300-OPEN-FILES-RTN.
OPEN INPUT STUDENT-FILE-IN.
OPEN INPUT PROGRAM-FILE-IN.
OPEN OUTPUT STUDENT-REPORT-FILE-OUT.
300-LOAD-PROGRAM-TABLE-RTN.
READ PROGRAM-FILE-IN
AT END MOVE "YES" TO PROG-EOF-FLAG
NOT AT END MOVE PROGRAM-CODE-IN TO PROGRAM-CODE (PROG-SUB)
MOVE PROGRAM-NAME-IN TO PROGRAM-NAME (PROG-SUB).
300-INITIALIZE-REPORT-FILE-RTN.
MOVE COLUMN-HEADER TO STUDENT-REPORT-RECORD-OUT.
WRITE STUDENT-REPORT-RECORD-OUT.
MOVE HEADER-LINE TO STUDENT-REPORT-RECORD-OUT.
WRITE STUDENT-REPORT-RECORD-OUT.
300-INITIALIZE-COUNTERS-RTN.
MOVE 0 TO STUDENT-RECORDS-READ-CTR.
MOVE 0 TO STUDENT-REPORTS-WRITTEN-CTR.
300-READ-STUDENT-RECORD-RTN.
READ STUDENT-FILE-IN
AT END MOVE "YES" TO STUFILE-EOF-FLAG
NOT AT END ADD 1 TO STUDENT-RECORDS-READ-CTR.
300-GET-PROGRAM-NAME-RTN.
IF PROGRAM-CODE (PROG-SUB) = PROGRAM-OF-STUDY
MOVE PROGRAM-NAME (PROG-SUB) TO PROGRAM-NAME-OUT
MOVE "YES" TO FOUND-PROG-FLAG
END-IF.
300-GET-STUDENT-AVERAGE.
CALL WW-SUB-PROG USING WW-SEND-AREA.
300-PRINT-STUDENT-REPORT-RTN.
MOVE "NO" TO FOUND-PROG-FLAG.
MOVE STUDENT-NAME-IN TO STUDENT-NAME.
MOVE TUITION-OWED-IN TO TUITION-OWED.
MOVE STUDENT-REPORT-RECORD TO STUDENT-REPORT-RECORD-OUT.
WRITE STUDENT-REPORT-RECORD-OUT.
ADD 1 TO STUDENT-REPORTS-WRITTEN-CTR.
300-PRINT-COUNTERS-RTN.
DISPLAY "Student records read: ", STUDENT-RECORDS-READ-CTR.
DISPLAY "Student reports written: ",
STUDENT-REPORTS-WRITTEN-CTR.
300-CLOSE-FILES-RTN.
CLOSE STUDENT-FILE-IN, PROGRAM-FILE-IN
STUDENT-REPORT-FILE-OUT.
END PROGRAM Project2.
Here is my Call Program:
******************************************************************
* Author: Desiree Hanuman
* Date: August 14th 2021
* Purpose:Call Section code for project 3
* Tectonics: cobc
******************************************************************
IDENTIFICATION DIVISION.
PROGRAM-ID. Program3Call.
DATA DIVISION.
LINKAGE SECTION.
01 LS-STUDENT-AVERAGE-AREA.
05 COURSE-AVERAGE-1 PIC 9(3).
05 COURSE-AVERAGE-2 PIC 9(3).
05 COURSE-AVERAGE-3 PIC 9(3).
05 COURSE-AVERAGE-4 PIC 9(3).
05 COURSE-AVERAGE-5 PIC 9(3).
05 STUDENT-AVERAGE PIC 9(3).
PROCEDURE DIVISION.
MAIN-PROCEDURE.
100-STUDENT-AVERAGE.
PERFORM 300-CALCULATE-AVERAGE-RTN.
300-CALCULATE-AVERAGE-RTN.
COMPUTE STUDENT-AVERAGE ROUNDED = (COURSE-AVERAGE-1 +
COURSE-AVERAGE-2 + COURSE-AVERAGE-3 + COURSE-AVERAGE-4 +
COURSE-AVERAGE-5) / 5.
GOBACK.

The normal way to CALL in most COBOL implementations is to just specify the module name - without a path or extension.
Then you either do "static linking" (as in Scott's answer below for OpenCOBOL/GnuCOBOL just specify all sources on the command line and use either -x [fat executable] or -b [fat module, then callable for example with cobcrun], commonly with -static); or do "dynamic linking" (separate compilation of all modules) and specify the module path in a configuration file or by environment variable. For OpenCOBOL/GnuCOBOL this is COB_LIBRARY_PATH.

I am not a user of OpenCobol, but, according to their manual in section 7, there are many ways to accomplish what you want.
But the simplest would be to statically compile and link the main and sub programs in one command line:
cobc -x Project2.cbl Program3Call.cbl

This example work´s for me.
Please keep in mind that the name of the dll file routine module must be same as the routine name.
It is not necessary reconfigure OpenCobol path library.
I use OpenCobol 4.7.6.
The Code:
Main program (file build "MAINPROG.exe")
IDENTIFICATION DIVISION.
PROGRAM-ID. "MAINPROG".
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 X PIC X(1).
01 INPUTS.
05 PRM-LENGTH PIC S9(4) COMP.
05 INPUT1 PIC 9(2).
05 INPUT2 PIC 9(2).
PROCEDURE DIVISION.
MAIN-PARA.
MOVE 12 TO INPUT1.
MOVE 13 TO INPUT2.
CALL 'MFPROG1' USING PRM-LENGTH, INPUT1, INPUT2.
ACCEPT X.
STOP RUN.
END PROGRAM "MAINPROG".
Rutine program (file build module "MFPROG1.dll")
IDENTIFICATION DIVISION.
PROGRAM-ID. "MFPROG1".
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 OUTPUT-DATA PIC 9(4).
LINKAGE SECTION.
01 PARM-BUFFER.
05 PARM-LENGTH PIC S9(4) COMP.
05 PARM-INPUT1 PIC 9(2).
05 PARM-INPUT2 PIC 9(2).
PROCEDURE DIVISION USING PARM-BUFFER.
MAIN-PARA.
COMPUTE OUTPUT-DATA = PARM-INPUT1 + PARM-INPUT2.
DISPLAY 'PARM-INPUT1: ' PARM-INPUT1.
DISPLAY 'PARM-INPUT2: ' PARM-INPUT2.
DISPLAY 'SUM VALUE : ' OUTPUT-DATA.
GOBACK.
END PROGRAM "MFPROG1".

Related

COBOL CAN'T WRITE RECORDS IN MY NOTEPAD FILES

I just want to know why i can't see my records on my Notepad files, is there something wrong in my code? I created my Notepad files into this path: "C:\Users\jamal.eclipse\MicroFocus\Student-Record.txt". When I run the code, it asks me the student number, the student tuition owed and the student name but can't see it in my Notepad files. Here's my code:
program-id. Project as "Project".
environment division.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT STUDENT-FILE-IN
ASSIGN TO
"C:\Users\jamal\.eclipse\MicroFocus\Student-Record.txt"
ORGANIZATION IS LINE SEQUENTIAL.
configuration section.
data division.
FILE Section.
FD STUDENT-FILE-IN.
01 STUDENT-RECORD-OUT PIC X(52).
working-storage section.
01 STUDENT-RECORD-IN.
05 STUDENT-NUMBER PIC 9(6).
05 TUITION-OWED PIC 9(6).
05 STUDENT-NAME PIC X(40).
01 PROMPT-MESSAGES-RESPONSES.
05 RECORD-Y-N PIC X(41) VALUE
"Do you have record ? Y or N: ".
05 RESPONSE PIC X(1).
05 STUDENT-NUMBER-OUT PIC X(24) VALUE
"Enter the Student Number: ".
05 TUITION-OWED-OUT PIC X(22) VALUE
"Enter the tuition owed: ".
05 STUDENT-NAME-OUT PIC X(22) VALUE
"Enter your Student Name: ".
procedure division.
CREATE-STUDENT-RECORD-FILE.
PERFORM STUDENT-RECORD-FILE.
PERFORM CREATE-STUDENT-RECORD
UNTIL RESPONSE="N" or "n".
PERFORM T-CREATE-STUDENT-RECORD-FILE.
STOP RUN.
STUDENT-RECORD-FILE.
PERFORM OPEN-RECORD.
PERFORM PROMPT-USER.
CREATE-STUDENT-RECORD.
PERFORM ENTER-STUDENT-DATA.
PERFORM WRITE-STUDENT-RECORD.
PERFORM PROMPT-USER.
T-CREATE-STUDENT-RECORD-FILE.
PERFORM CLS-CREATE-STUDENT-RECORD.
OPEN-RECORD.
OPEN OUTPUT STUDENT-FILE-IN.
PROMPT-USER.
DISPLAY RECORD-Y-N.
ACCEPT RESPONSE.
ENTER-STUDENT-DATA.
DISPLAY STUDENT-NUMBER-OUT.
ACCEPT STUDENT-NUMBER.
DISPLAY TUITION-OWED-OUT.
ACCEPT TUITION-OWED.
DISPLAY STUDENT-NAME-OUT
ACCEPT STUDENT-NAME.
WRITE-STUDENT-RECORD.
MOVE STUDENT-RECORD-IN TO STUDENT-RECORD-OUT.
WRITE STUDENT-RECORD-OUT.
CLS-CREATE-STUDENT-RECORD.
CLOSE STUDENT-FILE-IN.
end program Project.
I'm a beginner to Cobol, thank you in advance for the help.
Here is your program, i made some changes , i hope that will help you
IDENTIFICATION DIVISION.
PROGRAM-ID. project.
environment division.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT STUDENT-FILE-IN
ASSIGN TO "C:\Users\jamal\.eclipse\MicroFocus\Student-Record.txt"
ORGANIZATION IS LINE SEQUENTIAL.
configuration section.
data division.
FILE Section.
FD STUDENT-FILE-IN.
01 STUDENT-RECORD-OUT PIC X(52).
working-storage section.
01 STUDENT-RECORD-IN.
05 STUDENT-NUMBER PIC 9(6).
05 TUITION-OWED PIC 9(6).
05 STUDENT-NAME PIC X(40).
01 PROMPT-MESSAGES-RESPONSES.
05 RECORD-Y-N PIC X(41) VALUE
"Do you have record ? Y or N: ".
05 RESPONSE PIC X(1).
05 STUDENT-NUMBER-OUT PIC X(20) VALUE "Enter Student Number".
05 TUITION-OWED-OUT PIC X(20) VALUE "Enter tuition owed:".
05 STUDENT-NAME-OUT PIC X(20) VALUE "Enter Student Name:".
procedure division.
OPEN OUTPUT STUDENT-FILE-IN.
PERFORM PROMPT-USER.
PERFORM CREATE-STUDENT-RECORD
UNTIL RESPONSE="N" or "n".
PERFORM T-CREATE-STUDENT-RECORD-FILE.
CREATE-STUDENT-RECORD.
PERFORM ENTER-STUDENT-DATA.
PERFORM WRITE-STUDENT-RECORD.
PERFORM PROMPT-USER.
T-CREATE-STUDENT-RECORD-FILE.
PERFORM CLS-CREATE-STUDENT-RECORD.
PROMPT-USER.
DISPLAY RECORD-Y-N.
ACCEPT RESPONSE.
ENTER-STUDENT-DATA.
DISPLAY STUDENT-NUMBER-OUT.
ACCEPT STUDENT-NUMBER.
DISPLAY TUITION-OWED-OUT.
ACCEPT TUITION-OWED.
DISPLAY STUDENT-NAME-OUT
ACCEPT STUDENT-NAME.
WRITE-STUDENT-RECORD.
MOVE STUDENT-RECORD-IN TO STUDENT-RECORD-OUT.
WRITE STUDENT-RECORD-OUT.
CLS-CREATE-STUDENT-RECORD.
CLOSE STUDENT-FILE-IN
STOP RUN.

IGZ0201W and IGZ0035S errors in COBOL

*-----------------------
IDENTIFICATION DIVISION.
*-----------------------
PROGRAM-ID. TOPACCTS
AUTHOR. Sohan Kundu.
*--------------------
ENVIRONMENT DIVISION.
*--------------------
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT PRINT-LINE ASSIGN TO PRTLINE.
SELECT ACCT-REC ASSIGN TO ACCTREC.
*-------------
DATA DIVISION.
*-------------
FILE SECTION.
FD PRINT-LINE RECORD CONTAINS 80 CHARACTERS RECORDING MODE F.
01 PRINT-REC.
05 FILLER PIC X(01) VALUE SPACES.
05 FIRST-NAME-O PIC X(11).
05 FILLER PIC X(02) VALUE SPACES.
05 LAST-NAME-O PIC X(22).
05 FILLER PIC X(02) VALUE SPACES.
05 ACCT-BALANCE-O PIC X(12).
05 FILLER PIC X(30) VALUE SPACES.
*
FD ACCT-REC RECORD CONTAINS 80 CHARACTERS RECORDING MODE F.
01 ACCT-FIELDS.
05 FIRST-NAME PIC X(11).
05 LAST-NAME PIC X(22).
05 FILLER PIC X(28).
05 ACCT-BALANCE PIC X(12).
05 FILLER PIC X(7).
*
WORKING-STORAGE SECTION.
01 FLAGS.
05 LASTREC PIC X VALUE SPACE.
*
01 TOTAL-CLIENTS.
05 FILLER PIC X(14) VALUE
'# OF RECORDS: '.
05 CLIENTS PIC 9(3) VALUE ZERO.
05 FILLER PIC X(63) VALUE SPACES.
*
01 HEADER-1.
05 FILLER PIC X(30) VALUE 'REPORT FOR TOP ACCOUNT HOLDERS'.
05 FILLER PIC X(50) VALUE SPACES.
*
01 HEADER-2.
05 FILLER PIC X(05) VALUE 'Year '.
05 HDR-YR PIC 9(04).
05 FILLER PIC X(02) VALUE SPACES.
05 FILLER PIC X(06) VALUE 'Month '.
05 HDR-MO PIC X(02).
05 FILLER PIC X(02) VALUE SPACES.
05 FILLER PIC X(04) VALUE 'Day '.
05 HDR-DAY PIC X(02).
05 FILLER PIC X(53) VALUE SPACES.
*
01 HEADER-3.
05 FILLER PIC X(11) VALUE 'First Name '.
05 FILLER PIC X(02) VALUE SPACES.
05 FILLER PIC X(10) VALUE 'Last Name '.
05 FILLER PIC X(14) VALUE SPACES.
05 FILLER PIC X(08) VALUE 'Balance '.
05 FILLER PIC X(35) VALUE SPACES.
*
01 HEADER-4.
05 FILLER PIC X(11) VALUE '-----------'.
05 FILLER PIC X(02) VALUE SPACES.
05 FILLER PIC X(10) VALUE '----------'.
05 FILLER PIC X(14) VALUE SPACES.
05 FILLER PIC X(08) VALUE '--------'.
05 FILLER PIC X(35) VALUE SPACES.
*
01 WS-CURRENT-DATE-DATA.
05 WS-CURRENT-DATE.
10 WS-CURRENT-YEAR PIC 9(04).
10 WS-CURRENT-MONTH PIC 9(02).
10 WS-CURRENT-DAY PIC 9(02).
05 WS-CURRENT-TIME.
10 WS-CURRENT-HOURS PIC 9(02).
10 WS-CURRENT-MINUTE PIC 9(02).
10 WS-CURRENT-SECOND PIC 9(02).
10 WS-CURRENT-MILLISECONDS PIC 9(02).
*
*------------------
PROCEDURE DIVISION.
*------------------
OPEN-FILES.
OPEN INPUT ACCT-REC.
OPEN OUTPUT PRINT-LINE.
*
WRITE-HEADERS.
MOVE FUNCTION CURRENT-DATE TO WS-CURRENT-DATE-DATA.
MOVE WS-CURRENT-YEAR TO HDR-YR.
MOVE WS-CURRENT-MONTH TO HDR-MO.
MOVE WS-CURRENT-DAY TO HDR-DAY.
WRITE PRINT-REC FROM HEADER-1.
WRITE PRINT-REC FROM HEADER-2.
MOVE SPACES TO PRINT-REC.
WRITE PRINT-REC AFTER ADVANCING 1 LINES.
WRITE PRINT-REC FROM HEADER-3.
WRITE PRINT-REC FROM HEADER-4.
MOVE SPACES TO PRINT-REC.
*
READ-NEXT-RECORD.
PERFORM READ-RECORD
PERFORM UNTIL LASTREC = 'Y'
PERFORM IS-BALANCE-HIGH
PERFORM READ-RECORD
END-PERFORM
.
*
CLOSE-STOP.
WRITE PRINT-REC FROM TOTAL-CLIENTS.
CLOSE ACCT-REC.
CLOSE PRINT-LINE.
STOP RUN.
*
READ-RECORD.
READ ACCT-REC
AT END MOVE 'Y' TO LASTREC
END-READ.
*
IS-BALANCE-HIGH.
IF FUNCTION NUMVAL-C(ACCT-BALANCE) > 8500000 THEN
ADD 1 TO CLIENTS
PERFORM WRITE-RECORD
END-IF.
*
WRITE-RECORD.
MOVE FIRST-NAME TO FIRST-NAME-O.
MOVE LAST-NAME TO LAST-NAME-O.
MOVE ACCT-BALANCE TO ACCT-BALANCE-O.
WRITE PRINT-REC.
*
I want to read the account details from an input file and print if the balance is more than 8500000.
The code is showing the following error:
IGZ0201W A file attribute mismatch was detected. File PRINT-LINE in program TOPACCTS had a record length of 81 and
the file specified in the ASSIGN clause had a record length of 80.
IGZ0035S There was an unsuccessful OPEN or CLOSE of file PRTLINE in program TOPACCTS at relative location X'1E8'.
Neither FILE STATUS nor an ERROR declarative were specified. The status code was 39.
From compile unit TOPACCTS at entry point TOPACCTS at compile unit offset +000001E8 at entry offset +000001E8
at address 1B8001E8.
In the JCL that you are using to execute this program (as a batchjob), within the step with EXEC PGM=TOPACCTS, make sure that you use a DD-card for your output file PRTLINE which looks similar to this:
//PRTLINE DD DISP=(NEW,CATLG),DSN=YOUR.DSN.GOES.HERE,
// UNIT=SYSDA,SPACE=(CYL,(5,5)),
// RECFM=FB,LRECL=80
That way you'll avoid the status code '39', which indicates that there is a mismatch between your record length of 80 (as shown in your program with CONTAINS 80 CHARACTERS), and whatever you specified in your JCL's DD-card.

'WRITE not allowed' error received when file is open

When running the code below, which outputs a report of all those who get bonuses based on input files, I get the error, 'WRITE not allowed, file not open for output (status = 48)' on ln 159.
I have tried opening the file in the 500-HEADING module but receive an error saying 'file already open (status = 41)' and receive the original error with moving the OPEN statement around to the 100-MAIN module. Using I-O, INPUT-OUTPUT, and EXTEND return a syntax error.
IDENTIFICATION DIVISION.
PROGRAM-ID. ASSIGNMENT9_1_SORT.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT PAYROLL-MASTER ASSIGN TO 'CH0901-UNSORTED.DAT'
ORGANIZATION IS LINE SEQUENTIAL.
SELECT WORK-FILE ASSIGN TO 'TEMP.DAT'
ORGANIZATION IS LINE SEQUENTIAL.
SELECT BONUS-REPORT ASSIGN TO 'BONUS REPORT SORTED.LST'
ORGANIZATION IS LINE SEQUENTIAL.
DATA DIVISION.
FILE SECTION.
FD PAYROLL-MASTER.
01 PAYROLL-REC.
05 EMP-NO-IN PIC X(5).
05 NAME-IN PIC X(20).
05 TERRITORY-NO-IN PIC XX.
05 OFFICE-NO-IN PIC XX.
05 ANNUAL-SALARY-IN PIC 9(6).
05 PIC X(29).
05 DATE-HIRED-IN.
10 MONTH-IN PIC 99.
10 DAY-IN PIC 99.
10 YEAR-IN PIC 9999.
05 PIC X(10).
FD BONUS-REPORT.
01 BONUS-PRINT PIC X(80).
SD WORK-FILE.
01 SORT-REC.
05 EMP-NO PIC X(5).
05 S-NAME PIC X(20).
05 TERR PIC XX.
05 OFFICE PIC XX.
05 ANNUAL-SALARY PIC 9(6).
05 PIC X(29).
05 DATE-HIRED.
10 S-MONTH PIC 99.
10 S-DAY PIC 99.
10 S-YEAR PIC 9999.
05 PIC X(10).
WORKING-STORAGE SECTION.
01 BONUS-REC.
05 EMP-NO-OUT PIC X(5).
05 NAME-OUT PIC X(20).
05 TERRITORY-NO-OUT PIC XX.
05 OFFICE-NO-OUT PIC XX.
05 ANNUAL-SALARY-OUT PIC 9(6).
05 PIC X(29).
05 DATE-HIRED-OUT.
10 MONTH-OUT PIC 99.
10 DAY-OUT PIC 99.
10 YEAR-OUT PIC 9999.
05 PIC X(10).
01 WS-DATE.
05 WS-YEAR PIC 9999.
05 WS-MONTH PIC 99.
05 WS-DAY PIC 99.
01 HEADER1.
05 PIC X(40) VALUE SPACES.
05 PIC X(15) VALUE 'BONUS REPORT'.
05 PIC X(5) VALUE SPACES.
05 PIC X(5) VALUE 'PAGE '.
05 PAGE-NO PIC 99 VALUE 1.
05 PIC XXX.
05 TODAYS-DATE.
10 MONTH-FIELD PIC 99.
10 PIC X VALUE '/'.
10 DAY-FIELD PIC XX.
10 PIC X VALUE '/'.
10 YEAR-FIELD PIC 9999.
01 BLANK-LINE PIC X(80).
01 FIRST-RECORD PIC X VALUE 'Y'.
01 HEADER2.
05 PIC X(10) VALUE SPACES.
05 PIC X(13) VALUE 'TERRITORY --'.
05 TERRITORY-NO PIC 99.
01 HEADER3.
05 PIC X(20) VALUE SPACES.
05 PIC X(10) VALUE 'OFFICE --'.
05 OFFICE-NO PIC 99.
01 HEADER4.
05 PIC X(10) VALUE SPACES.
05 PIC X(15) VALUE 'EMPLOYEE NAME'.
05 PIC X(5) VALUE SPACES.
05 PIC X(5) VALUE 'BONUS'.
01 DATA1.
05 PIC X(6) VALUE SPACES.
05 NAME PIC X(20).
05 PIC XXXX.
05 BONUS PIC $ZZ,ZZZ.99 VALUE ZEROES.
01 ARE-THERE-MORE-RECORDS PIC X VALUE 'Y'.
01 LINE-COUNT PIC 99 VALUE 1.
PROCEDURE DIVISION.
100-MAIN.
SORT WORK-FILE
ON ASCENDING KEY TERR
ON ASCENDING KEY OFFICE
USING PAYROLL-MASTER
GIVING BONUS-REPORT
PERFORM 200-INPUT
STOP RUN.
200-INPUT.
OPEN INPUT BONUS-REPORT
MOVE FUNCTION CURRENT-DATE TO WS-DATE
MOVE WS-YEAR TO YEAR-FIELD
MOVE WS-MONTH TO MONTH-FIELD
MOVE WS-DAY TO DAY-FIELD
PERFORM UNTIL ARE-THERE-MORE-RECORDS = 'N'
READ BONUS-REPORT NEXT RECORD
AT END
MOVE 'N' TO ARE-THERE-MORE-RECORDS
NOT AT END
PERFORM 300-MOVE
PERFORM 400-CALC
END-READ
CLOSE BONUS-REPORT
END-PERFORM.
300-MOVE.
MOVE EMP-NO-IN TO EMP-NO-OUT
MOVE NAME-IN TO NAME-OUT
MOVE TERRITORY-NO-IN TO TERRITORY-NO-OUT
MOVE OFFICE-NO-IN TO OFFICE-NO-OUT
MOVE ANNUAL-SALARY-IN TO ANNUAL-SALARY-OUT
MOVE DATE-HIRED-IN TO DATE-HIRED-OUT.
400-CALC.
MOVE ZEROES TO BONUS
IF YEAR-OUT IS LESS THAN 1994
COMPUTE BONUS = ANNUAL-SALARY-OUT * 0.10
END-IF
EVALUATE TRUE
WHEN FIRST-RECORD = 'Y'
MOVE TERRITORY-NO-OUT TO TERRITORY-NO
MOVE OFFICE-NO-OUT TO OFFICE-NO
PERFORM 500-HEADING
MOVE NAME-OUT TO NAME
WRITE BONUS-PRINT FROM DATA1
ADD 1 TO LINE-COUNT
MOVE 'N' TO FIRST-RECORD
WHEN FIRST-RECORD = 'N'
MOVE TERRITORY-NO-OUT TO TERRITORY-NO
MOVE OFFICE-NO-OUT TO OFFICE-NO
MOVE NAME-OUT TO NAME
IF LINE-COUNT > 10
MOVE 1 TO LINE-COUNT
ADD 1 TO PAGE-NO
PERFORM 500-HEADING
END-IF
WRITE BONUS-PRINT FROM DATA1
ADD 1 TO LINE-COUNT
END-EVALUATE.
500-HEADING.
WRITE BONUS-PRINT FROM BLANK-LINE
WRITE BONUS-PRINT FROM HEADER1
WRITE BONUS-PRINT FROM BLANK-LINE
WRITE BONUS-PRINT FROM HEADER2
WRITE BONUS-PRINT FROM BLANK-LINE
WRITE BONUS-PRINT FROM HEADER3
WRITE BONUS-PRINT FROM BLANK-LINE
WRITE BONUS-PRINT FROM BLANK-LINE
WRITE BONUS-PRINT FROM HEADER4.
`
Change
OPEN INPUT BONUS-REPORT
To
OPEN OUTPUT BONUS-REPORT
Upon further examination addition errors were found.
The SORT statement should have created different file to use as input, rather than the file that you intended to use for output. Or, as #Jim Castro implies in another answer, use the OUTPUT PROCEDURE to access the records. The differences below show the additional file and the OPEN and CLOSE statements for that file.
Also,the CLOSE statement needed to removed from the PERFORM. also noted by #Jim Castro.
Finally, the END-EVALUATE need to be placed before the WRITE statement.
The following is the output of a difference utility that identifies the changes.
OLD being the program you posted, NEW being the program after the changes I applied.
* Text File Comparison
*-------------------------------------------------------------------------------
* 000008/000008: mis-matched records
* OLD :-
SELECT WORK-FILE ASSIGN TO 'TEMP.DAT'
ORGANIZATION IS LINE SEQUENTIAL.
* NEW :-
SELECT WORK-FILE ASSIGN TO 'TEMP.DAT'.
SELECT TEMP-BONUS-FILE ASSIGN TO "TEMP-BONUS.DAT"
ORGANIZATION LINE SEQUENTIAL.
*-------------------------------------------------------------------------------
* 000027/000028: extra NEW records :-
FD TEMP-BONUS-FILE.
01 TEMP-BONUS-REC.
05 T-EMP-NO PIC X(5).
05 T-NAME PIC X(20).
05 T-TERR PIC XX.
05 T-OFFICE PIC XX.
05 T-ANNUAL-SALARY PIC 9(6).
05 PIC X(29).
05 T-DATE-HIRED.
10 T-MONTH PIC 99.
10 T-DAY PIC 99.
10 T-YEAR PIC 9999.
05 PIC X(10).
*-------------------------------------------------------------------------------
* 000102/000116: mis-matched records
* OLD :-
GIVING BONUS-REPORT
* NEW :-
GIVING TEMP-BONUS-FILE
*-------------------------------------------------------------------------------
* 000107/000121: mis-matched records
* OLD :-
OPEN INPUT BONUS-REPORT
* NEW :-
OPEN INPUT TEMP-BONUS-FILE
OUTPUT BONUS-REPORT
*-------------------------------------------------------------------------------
* 000113/000128: mis-matched records
* OLD :-
READ BONUS-REPORT NEXT RECORD
* NEW :-
READ TEMP-BONUS-FILE NEXT RECORD
*-------------------------------------------------------------------------------
* 000120/000135: mis-matched records
* OLD :-
CLOSE BONUS-REPORT
END-PERFORM.
300-MOVE.
MOVE EMP-NO-IN TO EMP-NO-OUT
MOVE NAME-IN TO NAME-OUT
MOVE TERRITORY-NO-IN TO TERRITORY-NO-OUT
MOVE OFFICE-NO-IN TO OFFICE-NO-OUT
MOVE ANNUAL-SALARY-IN TO ANNUAL-SALARY-OUT
MOVE DATE-HIRED-IN TO DATE-HIRED-OUT.
* NEW :-
END-PERFORM
CLOSE BONUS-REPORT TEMP-BONUS-FILE.
300-MOVE.
MOVE T-EMP-NO TO EMP-NO-OUT
MOVE T-NAME TO NAME-OUT
MOVE T-TERR TO TERRITORY-NO-OUT
MOVE T-OFFICE TO OFFICE-NO-OUT
MOVE T-ANNUAL-SALARY TO ANNUAL-SALARY-OUT
MOVE T-DATE-HIRED TO DATE-HIRED-OUT.
*-------------------------------------------------------------------------------
* 000154/000169: mis-matched records
* OLD :-
WRITE BONUS-PRINT FROM DATA1
ADD 1 TO LINE-COUNT
END-EVALUATE.
* NEW :-
END-EVALUATE
WRITE BONUS-PRINT FROM DATA1
ADD 1 TO LINE-COUNT.
*-------------------------------------------------------------------------------
I should add that the 300-MOVE paragraph could be replaced by using INTO BONUS-REC on either a READ or RETURN statement; as in,
READ TEMP-BONUS-FILE NEXT RECORD INTO BONUS-REC
or
RETURN SORT-REC INTO BONUS-REC
Nice first attempt but you are doing many things wrong. You cannot open BONUS-REPORT as input if its the final formatted output of your program. Some files are I-O but this isn't the case here.
I would suggest using the SORT verb with USING with OUTPUT PROCEDURE IS version of the statement instead. RETURN the SORT-REC then format and WRITE the bonus report. You'll have to change your 300 and 400 paragraphs to move the right fields but it should work out for you in the end.
PROCEDURE DIVISION.
100-MAIN.
SORT WORK-FILE
ON ASCENDING KEY TERR
ON ASCENDING KEY OFFICE
USING PAYROLL-MASTER
OUTPUT PROCEDURE IS PERFORM 200-OUTPUT
GOBACK.
200-OUTPUT.
OPEN OUTPUT BONUS-REPORT
MOVE FUNCTION CURRENT-DATE TO WS-DATE
MOVE WS-YEAR TO YEAR-FIELD
MOVE WS-MONTH TO MONTH-FIELD
MOVE WS-DAY TO DAY-FIELD
PERFORM UNTIL ARE-THERE-MORE-RECORDS = 'N'
RETURN SORT-REC INTO BONUS-REC
AT END
MOVE 'N' TO ARE-THERE-MORE-RECORDS
NOT AT END
PERFORM 400-CALC
END-RETURN
END-PERFORM.
CLOSE BONUS-REPORT.
Please note: move the close of BONUS-REPORT out of the PERFORM loop.

Not a uniquely defined Name?

I keep getting the error
"LOWMID-COMMISSION-CTR" was not a uniquely defined name. The definition
to be used could not be determined from the context.
And similar on all of my counters. I have no idea where I'm going wrong here, how is it not a uniquely defined name when it is clearly in the WORKING-STORAGE SECTION? Do I put it somewhere else so that it's a uniquely defined name? Below I have showed where I defined my counters, and where the counters are used.
IDENTIFICATION DIVISION.
PROGRAM-ID. LAB3.
AUTHOR.
******************************************************************
ENVIRONMENT DIVISION.
* defines the external files - an input file and output file
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT SALES-FILE ASSIGN TO DATAIN
FILE STATUS IS EF-STATUS.
SELECT REPORT-FILE ASSIGN TO DATAOUT
FILE STATUS IS PF-STATUS.
DATA DIVISION.
* has two sections - the file section that describes the files
* and the working storage section - where output lines and
* processing variables are defined
FILE SECTION.
FD SALES-FILE.
01 SALES-RECORD.
05 EMPLOYEE-NAME-IN PIC X(24).
05 SALES-IN PIC 99999.
05 FILLER PIC X(51).
FD REPORT-FILE.
01 REPORT-RECORD PIC X(80).
WORKING-STORAGE SECTION.
01 FLAGS-AND-ACCUMLATORS.
05 LOW-COMMISSION-CTR PIC 99999 VALUE ZERO.
05 LOWMID-COMMISSION-CTR PIC 99999 VALUE ZERO.
05 HIGHMID-COMMISSION-CTR PIC 99999 VALUE ZERO.
05 HIGH-COMMISSION-CTR PIC 99999 VALUE ZERO.
05 TOTAL-SALES PIC $$$,$$9.99 VALUE ZERO.
05 TOTAL-COMMISSION PIC $$$,$$9.99 VALUE ZERO.
05 END-OF-FILE PIC XXX VALUE "NO".
05 EF-STATUS PIC 99 VALUE 0.
05 PF-STATUS PIC 99 VALUE 0.
05 COMMISSION PIC 99999V99.
01 REPORT-BLANK-LINE.
05 PIC X(80).
01 HEADING-LINE-1.
05 PIC X(30) VALUE SPACES.
05 PIC X(19) VALUE
"COMPANY OF AARON".
01 HEADING-LINE-2.
05 PIC X(30) VALUE SPACES.
05 PIC X(19) VALUE
"KEARNEY, MISSOURI".
01 HEADING-LINE-3.
05 PIC X(03) VALUE SPACES.
05 PIC X(48) VALUE
"Number of employees with up to 10,000 in sales: ".
05 LOW-COMMISSION-CTR PIC 99999.
01 HEADING-LINE-4.
05 PIC X(03) VALUE SPACES.
05 PIC X(52) VALUE
"Number of employees from 10,001 to 20,000 in sales: ".
05 LOWMID-COMMISSION-CTR PIC 99999.
01 HEADING-LINE-5.
05 PIC X(03) VALUE SPACES.
05 PIC X(52) VALUE
"Number of employees from 20,001 to 30,000 in sales: ".
05 HIGHMID-COMMISSION-CTR PIC 99999.
01 HEADING-LINE-6.
05 PIC X(03) VALUE SPACES.
05 PIC X(42) VALUE
"Number of employees over 30,000 in sales: ".
05 HIGH-COMMISSION-CTR PIC 99999.
01 HEADING-LINE-7.
05 PIC X(03) VALUE SPACES.
05 PIC X(13) VALUE
"Total Sales: ".
05 TOTAL-SALES PIC $$$,$$9.99.
01 HEADING-LINE-8.
05 PIC X(03) VALUE SPACES.
05 PIC X(18) VALUE
"TOTAL COMMISSION: ".
05 TOTAL-COMMISSION PIC $$$,$$9.99.
01 COLUMN-HEADING-1.
05 PIC X(03) VALUE SPACES.
05 PIC X(24) VALUE "SALESPERSON".
05 PIC X(15) VALUE "SALES".
05 PIC X(10) VALUE "COMMISSION".
01 COLUMN-HEADING-2.
05 PIC X(14) VALUE "SUMMARY REPORT".
01 DETAIL-LINE.
05 PIC X(03) VALUE SPACES.
05 EMPLOYEE-NAME-OUT PIC X(24).
05 SALES-OUT PIC $$$,$$9.
05 PIC X(05) VALUE SPACES.
05 COMMISSION-OUT PIC $$$,$$9.99.
PROCEDURE DIVISION.
1000-MAIN-CONTROL.
PERFORM 2000-INITIALIZE.
PERFORM UNTIL END-OF-FILE = "YES"
READ SALES-FILE
AT END
MOVE "YES" TO END-OF-FILE
NOT AT END
PERFORM 3000-PROCESS
END-PERFORM
PERFORM 4000-PROCESS.
STOP RUN.
2000-INITIALIZE.
OPEN INPUT SALES-FILE
OUTPUT REPORT-FILE.
WRITE REPORT-RECORD FROM HEADING-LINE-1.
WRITE REPORT-RECORD FROM HEADING-LINE-2.
WRITE REPORT-RECORD FROM REPORT-BLANK-LINE.
WRITE REPORT-RECORD FROM COLUMN-HEADING-1.
WRITE REPORT-RECORD FROM REPORT-BLANK-LINE.
3000-PROCESS.
IF SALES-IN < 10001
MULTIPLY SALES-IN BY .04 GIVING COMMISSION
ADD 1 TO LOW-COMMISSION-CTR
ADD COMMISSION TO TOTAL-COMMISSION
END-IF.
IF SALES-IN > 10000 AND < 20001
MULTIPLY SALES-IN BY .055 GIVING COMMISSION
ADD 1 TO LOWMID-COMMISSION-CTR
ADD COMMISSION TO TOTAL-COMMISSION
END-IF.
IF SALES-IN > 20000 AND < 30000
MULTIPLY SALES-IN BY .065 GIVING COMMISSION
ADD 1 TO HIGHMID-COMMISSION-CTR
ADD COMMISSION TO TOTAL-COMMISSION
END-IF.
IF SALES-IN > 30000
MULTIPLY SALES-IN BY .075 GIVING COMMISSION
ADD 1 TO HIGH-COMMISSION-CTR
ADD COMMISSION TO TOTAL-COMMISSION
END-IF.
MOVE EMPLOYEE-NAME-IN TO EMPLOYEE-NAME-OUT.
MOVE SALES-IN TO SALES-OUT.
MOVE COMMISSION TO COMMISSION-OUT.
WRITE REPORT-RECORD FROM DETAIL-LINE.
4000-PROCESS.
WRITE REPORT-RECORD FROM REPORT-BLANK-LINE.
WRITE REPORT-RECORD FROM COLUMN-HEADING-2.
WRITE REPORT-RECORD FROM HEADING-LINE-3.
WRITE REPORT-RECORD FROM HEADING-LINE-4.
WRITE REPORT-RECORD FROM HEADING-LINE-5.
WRITE REPORT-RECORD FROM HEADING-LINE-6.
WRITE REPORT-RECORD FROM HEADING-LINE-7.
WRITE REPORT-RECORD FROM HEADING-LINE-8.
4000-TERMINATE.
CLOSE SALES-FILE, REPORT-FILE.
Thje variable LOWMID-COMMISSION-CTR is defined twice.
once in FLAGS-AND-ACCUMLATORS
01 FLAGS-AND-ACCUMLATORS.
05 LOW-COMMISSION-CTR PIC 99999 VALUE ZERO.
05 LOWMID-COMMISSION-CTR PIC 99999 VALUE ZERO.
once in HEADING-LINE-4
01 HEADING-LINE-4.
05 PIC X(03) VALUE SPACES.
05 PIC X(52) VALUE
"Number of employees from 10,001 to 20,000 in sales: ".
05 LOWMID-COMMISSION-CTR PIC 99999.
So either
rename one of the LOWMID-COMMISSION-CTR to some thing else
01 HEADING-LINE-4.
05 PIC X(03) VALUE SPACES.
05 PIC X(52) VALUE
"Number of employees from 10,001 to 20,000 in sales: ".
05 HEADER-LOWMID-COMMISSION-CTR PIC 99999.
fully qualify the field.
Add 1
to LOWMID-COMMISSION-CTR
of FLAGS-AND-ACCUMLATORS
Same applies to other FLAGS-AND-ACCUMLATORS fields

COBOL Program to read a flat file sequentially and write it to an output file, not able to read at all loop is going infinite

I'm trying to write COBOL Program to read a flat file sequentially and write it to an output file, I'm able to read only one record at a time, not able to read next record what should I do?
Here is my code:
PROCEDURE DIVISION.
OPEN INPUT FILEX.
PERFORM READ-PARA THRU END-PARA UNTIL END-OF-FILE = 'Y'.
CLOSE FILEX.
STOP RUN.
READ-PARA.
READ FILEX
AT END
MOVE 'Y' TO END-OF-FILE
DISPLAY OFFCODE1
DISPLAY AGCODE1
DISPLAY POLNO1
DISPLAY EFFDATE1
DISPLAY EXPDATE
DISPLAY REPCODE
DISPLAY POLHOLDER1
DISPLAY LOCATION1
GO TO END-PARA.
END-PARA.
i, ve tried using the scope terminator, still not able to loop 'm getting S001 ABEND here is my code :
IDENTIFICATION DIVISION.
PROGRAM-ID. SIMPLE.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT FILEX ASSIGN TO SYSUT1
FILE STATUS IS FS.
DATA DIVISION.
FILE SECTION.
FD FILEX.
01 FILEXREC.
02 OFFCODE1 PIC X(3).
02 FILLER PIC X.
02 AGCODE1 PIC X(3).
02 FILLER PIC X.
02 POLNO1 PIC X(6).
02 FILLER PIC X.
02 EFFDATE1 PIC X(8).
02 FILLER PIC X.
02 EXPDATE PIC X(8).
02 FILLER PIC X.
02 REPCODE PIC X(1)
02 FILLER PIC X.
02 POLHOLDER1 PIC X(8).
02 FILLER PIC X.
02 LOCATION1 PIC X(9).
02 FILLER PIC X(87).
WORKING-STORAGE SECTION.
77 FS PIC 9(2).
01 WS-INDICATORS.
10 WS-EOF-IND PIC X(01) VALUE 'N'.
88 WS-END-OF-FILE VALUE 'Y'.
PROCEDURE DIVISION.
OPEN INPUT FILEX.
PERFORM READ-PARA THRU END-PARA UNTIL WS-END-OF-FILE.
CLOSE FILEX.
STOP RUN.
READ-PARA.
READ FILEX
AT END
MOVE 'Y' TO WS-EOF-IND.
DISPLAY OFFCODE1
DISPLAY AGCODE1
DISPLAY POLNO1
DISPLAY EFFDATE1
DISPLAY EXPDATE
DISPLAY REPCODE
DISPLAY POLHOLDER1
DISPLAY LOCATION1
IF WS-END-OF-FILE
GO TO END-PARA.
END-PARA.
EXIT.
one more method i tried even in this works for only one record, again getting S001 ABEND while running the code. Here is the code:
IDENTIFICATION DIVISION.
PROGRAM-ID. ASSIGNMENT.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT FILEX ASSIGN TO SYSUT1
DATA DIVISION.
FILE SECTION.
FD FILEX.
LABEL RECORDS ARE STANDARD
RECORD CONTAINS 140 CHARACTERS
BLOCK CONTAINS 00 RECORDS.
01 FILEXREC.
02 OFFCODE1 PIC 9(3).
02 FILLER PIC X.
02 AGCODE1 PIC X(3).
02 FILLER PIC X.
02 POLNO1 PIC X(6).
02 FILLER PIC X.
02 EFFDATE1 PIC X(8).
02 FILLER PIC X.
02 EXPDATE1 PIC X(8).
02 FILLER PIC X.
02 REPCODE1 PIC X(1).
02 FILLER PIC X.
02 POLHOLDER1 PIC X(8).
02 FILLER PIC X.
02 LOCATION1 PIC X(9).
02 FILLER PIC X(26).
WORKING-STORAGE SECTION.
01 WS-INDICATORS.
10 WS-EOF-IND PIC X(01) VALUE 'N'.
88 WS-END-OF-FILE VALUE 'Y'.
01 TEMP1.
02 OFFCODE2 PIC 9(3).
02 FILLER PIC X.
02 AGCODE2 PIC X(3).
02 FILLER PIC X.
02 POLNO2 PIC X(6).
02 FILLER PIC X.
02 EFFDATE2 PIC X(8).
02 FILLER PIC X.
02 EXPDATE2 PIC X(8).
02 FILLER PIC X.
02 REPCODE2 PIC X(1).
02 FILLER PIC X.
02 POLHOLDER2 PIC X(8).
02 FILLER PIC X.
02 LOCATION2 PIC X(9).
02 FILLER PIC X(26).
PROCEDURE DIVISION.
OPEN INPUT FILEX.
PERFORM READ-PARA THRU END-PARA UNTIL WS-END-OF-FILE.
CLOSE FILEX.
STOP RUN.
READ-PARA.
READ FILEX
INTO TEMP1
AT END
MOVE 'Y' TO WS-EOF-IND.
DISPLAY OFFCODE1
DISPLAY AGCODE1
DISPLAY POLNO1
DISPLAY EFFDATE1
DISPLAY EXPDATE1
DISPLAY REPCODE1
DISPLAY POLHOLDER1
DISPLAY LOCATION1
IF WS-END-OF-FILE
GO TO END-PARA.
END-PARA.
EXIT.
You really should use your END- terminators... END-PERFORM, END-IF, END-READ, etc.
As for you problem, if I were to guess, I'd say you're not reading only the first record, you're reading all records and displaying only the last one. Your READ statement has an AT END, where everything is done, but it doesn't have a NOT AT END to tell it what to do with records it's read successfully. I generally code my READ statements thusly:
READ FILE
AT END
SET FILE-EOF TO TRUE
NOT AT END
PERFORM PROCESS-RECORD
END-READ
Wrap that in a perform like this and it works pretty well:
SET FILE-NOT-EOF TO TRUE
PERFORM UNTIL FILE-EOF
READ FILE
AT END
SET FILE-EOF TO TRUE
NOT AT END
PERFORM PROCESS-RECORD
END-READ
END-PERFORM
Good luck, hope it works out for you. Writing solid COBOL can be very tough.
I guess you're not still waiting :-)
In one place file is 140, but definition is only 79.
You use file status, but don't check it. Your file probably does not open successfully, which you would have discovered if you checked the FS field (cunning name, but copied form IBM example maybe).
When you READ and get end-of-file, you set the flag, but still process as though you had got a record. Depending on "things" this gets you the wrong data, or gets you an abend.
There's no point in the GO TO END-PARA because END-PARA is immediately afterwards anyway.
Hopefully you went back and looked at the code NealB provided and got the thing going a few months ago...

Resources