I have written the following COBOL program:

*************************************************************
* VERKOOP  
*************************************************************
       IDENTIFICATION DIVISION.
       PROGRAM-ID. VERKOOP.

       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
       SELECT PRODUCTEN ASSIGN TO "BESTANDEN/PRODUCTEN"
           ACCESS MODE IS RANDOM
           ORGANIZATION IS INDEXED
           RECORD KEY IS PRODUCTID
           FILE STATUS IS WS-FILE-STATUS.

       DATA DIVISION.
       FILE SECTION.
       FD  PRODUCTEN BLOCK CONTAINS 10 RECORDS.
       01  PRODUCT.
           02 PRODUCTID PIC X(6).
           02 LEVERANCIERID PIC X(6).
           02 AANTAL PIC 9(6).
       WORKING-STORAGE SECTION.
       77  FOUT PIC X.
           88 PRODUCT-NIET-GEVONDEN VALUE 1.
       77 WS-PRODUCTID PIC X(6).
       77 WS-AANTAL PIC 9(6).
       77 WS-FILE-STATUS PIC XX.
       LINKAGE SECTION.
       01 LS-PRODUCTID PIC X(6).
       01 LS-AANTAL PIC 9(6).
       PROCEDURE DIVISION. 
*      USING LS-PRODUCTID, LS-AANTAL.

       MAIN.
           PERFORM INITIALISEER
           PERFORM LEES-PRODUCT-IN
           PERFORM LEES-BESTAND
           PERFORM SLUIT-BESTAND
           STOP RUN.

       INITIALISEER.
           MOVE ZEROS TO PRODUCT
           OPEN I-O PRODUCTEN.
*          DISPLAY WS-FILE-STATUS..

       LEES-PRODUCT-IN.
*          MOVE LS-PRODUCTID TO WS-PRODUCTID
*          MOVE LS-AANTAL TO WS-AANTAL.
           DISPLAY "GEEF PRODUCTID OP: "
           ACCEPT WS-PRODUCTID
           DISPLAY "GEEF AANTAL OP: "
           ACCEPT WS-AANTAL.

       LEES-BESTAND.
*      DISPLAY "LEES-BESTAND"
       MOVE WS-PRODUCTID TO PRODUCTID
*      DISPLAY PRODUCTID
       READ PRODUCTEN INVALID KEY SET PRODUCT-NIET-GEVONDEN TO TRUE
       END-READ   
       DISPLAY "END-READ" WS-FILE-STATUS    
       IF PRODUCT-NIET-GEVONDEN PERFORM FOUTJE    
       ELSE 
       MOVE WS-PRODUCTID TO PRODUCTID
       SUBTRACT WS-AANTAL FROM AANTAL   
       PERFORM UPDATE-PRODUCT
       END-IF.


      UPDATE-PRODUCT.
        REWRITE PRODUCT INVALID KEY PERFORM FOUTJE.

        SLUIT-BESTAND.
*       DISPLAY "SLUIT-BESTAND"
           CLOSE PRODUCTEN.

        FOUTJE.
           DISPLAY "ER IS EEN FOUT OPGETREDEN"
*          DISPLAY WS-FILE-STATUS
           STOP RUN.

The idea is that I find a product by its productid in the file PRODUCTEN.dat and subtract the amount (aantal) by a given number. However everytime I run it I get the following error: WARNING - Implicit CLOSE of PRODUCTEN <"BESTANDEN/PRODUCTEN">. I don't really see the problem, the WS-FILE-STATUS line even gives me back a 00 status. I am 100% sure the product is in the file so I'm not trying to subtract from a non-existing product or anything.

UPDATE: I fixed it by assign PRODUCTEN to a newly declared file as the last one (somehow) got corrupt and was behaving in an unintended way.

有帮助吗?

解决方案

To get that Implicit Close message, you must have a STOP RUN before you close the file.

You have a STOP RUN in paragraph FOUTJE, before the file is closed, so paragraph FOUTJE is being used.

You use paragraph FOUTJE in a PERFORM when PRODUCT-NIET-GEVONDEN is true.

PRODUCT-NIET-GEVONDEN is set to true on the INVALID KEY of the READ.

So INVALID KEY is true.

You get a FILE STATUS of ZERO. Unexpected, but fits what you have presented.

I don't have COBOL-IT and I don't know what OS you are using.

I also don't know in your set-up what a READ of a keyed file which does not explicitly reference a key does.

I don't know in any set-up, because I don't do it. If I'm doing a keyed read, I always specify the key.

I don't put data in the key on the file. I use a WORKING-STORAGE field for the key.

Why, well, implementation-dependent for the compiler, but unless your file is OPEN and unless there is a current record on the file, then the content, even the address, of a file record is/can be (implementation dependent) undefined.

As far as I am concerned, the KEY on the SELECT is to define the presence of the key on the file. The key you are using to READ the file obviously comes from elsewhere.

So, I would remove these:

       MOVE ZEROS TO PRODUCT

   MOVE WS-PRODUCTID TO PRODUCTID

I'd change this to include the KEY of WS-PRODUCTID

   READ PRODUCTEN INVALID KEY SET PRODUCT-NIET-GEVONDEN TO TRUE

I'd not use INVALID KEY, I'd just use the value of WS-FILE-STATUS, which I'd expect to be "23" for "not found". I'd do the test with an 88. You then don't need your "flag" (FOUT and PRODUCT-NIET-GEVONDEN) anyway. Check the FILE STATUS field after each IO. This time you spelled your filename correctly, another time you won't and you may waste more time chasing your tail.

Work on consistent indentation, it will make your program easier to read, for you, and anyone else.

If you want to use DISPLAY to verify the logical path, you need to DISPLAY the value which is used to determine the logical path (FOUT in this case).

There are two "formats" of the READ statement. One is for sequential reads, one is for reads using a key. When each is reduced to its mandatory-only content, they are identical. Therefore it is not clear, per compiler, which type of READ is the default (when not explicit) or when it is the default (per file). So I always make it explicit:

READ PRODUCTEN KEY IS WS-PRODUCTID

I would then use the FILE STATUS field to determine whether the key was read (00 in the status) or not found (23) or something else (something else).

NOTE: This Answer as a resolution to your problem only works if everything is as you have described. Further information may invalidate this Answer as a Resolution.

The Answer does work as a generally clearer (therefore better) way to code your COBOL program.

Turns out to have been a suspected corrupted file. This may have caused a disparity between INVALID KEY and FILE STATUS, but in the normal course of events that is not going to happen. It is the only thing which fits all the evidence, but this is an exceptional case, perhaps not able to reproduce without the exact-same file corruption and clutching at this straw in a general case for why a given program is not working is probably the first refuge of a scoundrel.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top