Cobol 隐式关闭文件

Cobol 隐式关闭文件,cobol,Cobol,我编写了以下COBOL程序: ************************************************************* * VERKOOP ************************************************************* IDENTIFICATION DIVISION. PROGRAM-ID. VERKOOP. ENVIRONMENT DIVISION. IN

我编写了以下COBOL程序:

*************************************************************
* 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.
我的想法是通过PRODUCTEN.dat文件中的productid找到一个产品,然后用给定的数字减去数量(aantal)。但是,每次运行它时,我都会收到以下错误:警告-PRODUCTEN的隐式关闭。我真的看不出问题所在,WS-FILE-STATUS行甚至还给我一个00状态。我100%确定该产品在文件中,所以我不会试图从一个不存在的产品或任何东西中减去


更新:我通过将PRODUCTEN分配给一个新声明的文件修复了它,因为最后一个文件(不知何故)已损坏,并以非预期方式运行。

要获取隐式关闭消息,必须在关闭文件之前停止运行

在文件关闭之前,在FOUTJE段中有一个停止运行,因此正在使用FOUTJE段

当PRODUCT-NIET-GEVONDEN为真时,在表演中使用第FOUTJE段

读取的无效密钥上将PRODUCT-NIET-GEVONDEN设置为true

所以无效密钥为true

您的文件状态为零。出乎意料,但符合您所展示的内容

我没有COBOL-IT,也不知道你在用什么操作系统

在您的设置中,我也不知道读取未显式引用密钥的密钥文件会做什么

我不知道在任何情况下,因为我不这样做。如果我正在进行键控读取,我总是指定键

我没有把数据放在文件的密钥中。我使用工作存储字段作为密钥

为什么,编译器依赖于实现,但是除非您的文件是打开的,并且文件上有当前记录,否则文件记录的内容,甚至地址都是/可能是(依赖于实现的)未定义的

就我而言,SELECT上的键用于定义文件中是否存在该键。您用来读取文件的密钥显然来自其他地方

因此,我要删除这些:

       MOVE ZEROS TO PRODUCT

   MOVE WS-PRODUCTID TO PRODUCTID
我会将其更改为包含WS-PRODUCTID的密钥

   READ PRODUCTEN INVALID KEY SET PRODUCT-NIET-GEVONDEN TO TRUE
我不会使用无效密钥,我只会使用WS-FILE-STATUS的值,对于“未找到”,我希望它是“23”。我会用88号做测试。然后你就不需要你的“旗帜”(FOUT和PRODUCT-NIET-GEVONDEN)了。检查每个IO后的文件状态字段。这一次你拼写的文件名正确,另一次你不会,你可能会浪费更多的时间追你的尾巴

使用一致的缩进,这将使您的程序更易于阅读,无论是对您还是对其他人

如果要使用DISPLAY验证逻辑路径,则需要显示用于确定逻辑路径的值(本例中为FOUT)

READ语句有两种“格式”。一个用于顺序读取,一个用于使用键进行读取。当每一个都减少到其仅强制的内容时,它们是相同的。因此,对于每个编译器,不清楚哪种读取类型是默认读取类型(不明确时)还是默认读取类型(每个文件)。所以我总是说得很清楚:

READ PRODUCTEN KEY IS WS-PRODUCTID
然后,我将使用文件状态字段来确定密钥是否已读取(状态为00)或未找到(23)或其他内容(其他内容)

注意:只有当一切都如您所描述的那样时,这个答案才是您问题的解决方案。进一步的信息可能会使此答案无效

答案确实可以作为编写COBOL程序的更清晰(因此更好)的方法


原来是一个可疑的损坏文件。这可能会导致无效密钥和文件状态之间的差异,但在正常的事件过程中不会发生这种情况。这是唯一符合所有证据的东西,但这是一个例外情况,如果没有完全相同的文件损坏,可能无法复制。在一般情况下,抓住这根稻草来解释给定程序为什么不工作可能是恶棍的第一个避难所。

您使用的是哪种COBOL编译器?请将程序的输出添加到问题中。请在“我已编辑您的标题”中查看我的答案。请参见“”,其中的共识是“不,他们不应该”。除此之外,当您的程序以
标识部门开始时,您真的不需要说两次“COBOL”
:-)更新我的ws-productid?为了什么?你能给我解释这一点的代码行吗?我是COBOL的新手,所以我不知道你在说什么mean@RobinHellemans您还可以删除您对该问题的评论,因为它们不再需要。我已经这样做了,当你杀了你的时候,我也会这样做。谢谢