Cobol code problem

Hi guys,
I’m facing a problem, I have a file contains some information, but when I compiled it I found that the code didn’t work, please help me fixing the problem, Here is the code :
IDENTIFICATION DIVISION.

   PROGRAM-ID.    MONEY.

   AUTHOR.        STUDENT.

  *

   ENVIRONMENT DIVISION.

  *

   INPUT-OUTPUT SECTION.

   FILE-CONTROL.

       SELECT ACC-RECS ASSIGN TO CUSTRECS.

       SELECT PRT-DONE ASSIGN TO TOPACCTS.

   DATA DIVISION.

   FILE SECTION.

   FD  ACC-RECS RECORD CONTAINS 80 CHARACTERS RECORDING MODE F.

   01  PRINT-REC.

       05 FIRST-NAME   PIC X(11).

       05 LAST-NAME    PIC X(22).

       05 FILLER       PIC X(28) VALUE SPACES.

       05 ACC-BAL      PIC X(10).

       05 FILLER       PIC X(9) VALUE SPACES.

   FD  PRT-DONE RECORD CONTAINS 80 CHARACTERS RECORDING MODE F.

   01  PRT-REC.

       05 PRT-FIRST-NAME   PIC X(11) VALUE SPACES.

       05 PRT-LAST-NAME    PIC X(22) VALUE SPACES.

       05 PRT-ACC-BAL      PIC Z,ZZZ,ZZZ.99.

       05 FILLER           PIC X(35) VALUE SPACES.

   WORKING-STORAGE SECTION.

   01  FLAGS.

       05 LASTREC      PIC X VALUE SPACE.

   01  COUNTERS.

       05 REC-COUNTER  PIC 9(2) VALUE 0.

   01  HEADER-1.

       05 FILLER     PIC X(37) VALUE

            'REPORT OF TOP ACCOUNT BALANCE HOLDERS'.

       05 FILLER       PIC X(43) VALUE SPACES.

   01  HEADER-2.

       05 FILLER    PIC X(29) VALUE 'PREPARED FOR PAT STANDARD ON '.

       05 HDR-MO    PIC X(02).

       05 FILLER    PIC X VALUE '.'.

       05 HDR-DAY   PIC X(02).

       05 FILLER    PIC X VALUE '.'.

       05 HDR-YR    PIC 9(04).

       05 FILLER    PIC X(41) VALUE SPACES.

   01  HEADER-3.

       05 FILLER     PIC X(14) VALUE '# OF RECORDS: '.

       05 FILLER     PIC X(66) VALUE SPACES.

   01  HEADER-4.

       05 FILLER     PIC X(38) VALUE

            '======================================'.

       05 FILLER       PIC X(42) 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  ACC-RECS.

       OPEN OUTPUT PRT-DONE.

   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 PRT-REC FROM HEADER-1.

       WRITE PRT-REC FROM HEADER-2.

       WRITE PRT-REC FROM HEADER-3.

       WRITE PRT-REC FROM HEADER-4.

   READ-NEXT-RECORD.

       PERFORM READ-RECORD

        PERFORM UNTIL LASTREC = 'Y'

                COMPUTE PRT-ACC-BAL = FUNCTION NUMVAL-C(ACC-BAL)

        PERFORM IS-EIGHT-FIVE

        PERFORM READ-RECORD

        END-PERFORM.

   CLOSE-STOP.

       CLOSE ACC-RECS.

       CLOSE PRT-DONE.

       STOP RUN.

   READ-RECORD.

       READ ACC-RECS

       AT END MOVE 'Y' TO LASTREC

       NOT AT END COMPUTE REC-COUNTER = REC-COUNTER + 1

       END-READ.

   IS-EIGHT-FIVE.

          IF PRT-ACC-BAL >= 8500000 THEN

            MOVE FIRST-NAME TO PRT-FIRST-NAME

            MOVE LAST-NAME TO PRT-LAST-NAME

            WRITE PRT-REC

          END-IF.

First code I’ve read in years. But what exactly is your question? What happens when you run it? Have you added any debugging code (like extra PRINT commands to show changing data and counts)? And what are the external variables, the data file, system run on, and anything like a command language to run the ‘batch’? Whether JCL or DCL or something else, might help to know.

This isn’t going to print anything. Looks like it will create a sequential file somewhere that has not been defined, but only if the input file is also defined. As Rontry says, no JCL or commands so the program is floating in mid air…

I interpret the code this way:
The first perform READ-RECORD will read all records and set the LASTRREC to Y.
Then PERFORM IS-EIGHT-FIVE
Then READ-RECORD again, ending the inline PERFORM. and reading past end of file
Second issue is that the COMPUTE PRT-ACC-BAL is working on dubious data a you will have read past the end of file, File record status is unknown

Looks to me that you’re not moving anything from the input record to the output record.

Questions
Assuming program compiled correctly and has JCL to execute

  1. do you in fact have any records in your input file with an account balance greater than or equal to 8.5 million
  2. Are you getting any output, that is, are your headings printing?
  3. if both the above are true, suggest adding print or display statements to program to show if it is going through the performed paragraphs. Maybe display record counter, or at least print record counter before closing files.
    Long time COBOL programmer
    Sue Rogers

Not sure that performing numeric functions on a edited field will flow, likely to produce a data erro and crash as there are no declarative to manage run time errors

Hi bbkr192,
A belated welcome.
Apologies for the tardy response, I’ve just seen this problem, but the answer is probably irrelevant to you now.

line: IF PRT-ACC-BAL >= 8500000 THEN

This line will probably cause a SOC7 error as PRT-ACC-BAL will generally contain a formatted value (containing ','s and decimal point) whereas the 8500000 is a numeric value. Because of the numeric operand the IF statement will attempt a packed comparison and hence the SOC7 abend.
One solution would be to replace the statement with:
IF ACC-BAL >= " 8500000" THEN
ACC-BAL is presumed to contain a well formatted numeric value in a character field ie right justified and leading spaces. The " 8500000" ie right justified and leading spaced value would cause the compiler to use a character compare (rather than packed) hence the SOC7 is avoided. The values in ACC-BAL and " 8500000" are comparable and should produce the required result. Being a character comparison there is a risk that extraneous character values eg non-printables could cause unpredictable results - so range checking would be adviseable.

Ideally the character comparison should be using numeric values (ie not characters, but this would entail converting the ACC-BAL field from character to numeric eg move ACC-BAL to a new variable W-ACC-BAL defined as 9(10). This move would remove the leading spaces. The test would then become:
IF W-ACC-BAL >= 8500000 THEN
which is a less cluttered and easier to modify statement.

As someone else has mentioned when the LASTREC value has been set to ‘Y’ there needs to be logic to print the value of REC-COUNTER with suitable text.

There may be some heading data remaining in the PRT-REC line and this would need to be initialised prior to the data lines being created. Ideally re-initilaise before each data line is built, but if the data line data is completely overwritten then this not strictly necessary and makes the code sligthly more efficient.