我写过以下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)。但是每次我运行它时都会出现以下错误:警告 - 产品的隐含关闭<“BESTANDEN / PRODUCTEN”>。我没有真正看到问题,WS-FILE-STATUS行甚至让我回到00状态。我100%确定产品在文件中,因此我不打算从不存在的产品或任何东西中减去。
更新:我通过将PRODUCTEN分配给新声明的文件来修复它,因为最后一个(不知何故)变得腐败并且表现得无意中。
答案 0 :(得分:4)
要获取隐式关闭消息,必须在关闭文件之前进行STOP RUN。
在文件关闭之前,FOUTJE段中有一个STOP RUN,因此正在使用段落FOUTJE。
当PRODUCT-NIET-GEVONDEN为真时,您在PERFORM中使用段落FOUTJE。
PRODUCT-NIET-GEVONDEN在READ的INVALID KEY上设置为true。
所以INVALID KEY是真的。
您获得了ZERO的文件状态。意外,但适合你所呈现的。
我没有COBOL-IT,我不知道您使用的操作系统。
我在你的设置中也不知道什么是未明确引用密钥的键控文件的READ。
我不知道在任何设置中,因为我没有这样做。如果我正在进行键控读取,我总是指定键。
我没有将数据放在文件的密钥中。我使用了一个WORKING-STORAGE字段作为密钥。
为什么,依赖于编译器的实现,但除非你的文件是OPEN,除非文件上有当前记录,否则文件记录的内容,甚至地址都是/可以是(依赖于实现) )undefined。
就我而言,SELECT上的KEY是定义文件上是否存在密钥。您用来阅读文件的密钥显然来自其他地方。
所以,我会删除这些:
MOVE ZEROS TO PRODUCT
MOVE WS-PRODUCTID TO PRODUCTID
我将其更改为包含WS-PRODUCTID的KEY
READ PRODUCTEN INVALID KEY SET PRODUCT-NIET-GEVONDEN TO TRUE
我不使用INVALID KEY,我只使用WS-FILE-STATUS的值,对于“未找到”,我希望它是“23”。我用88进行测试。无论如何你不需要你的“旗帜”(FOUT和PRODUCT-NIET-GEVONDEN)。每次IO后检查FILE STATUS字段。这次你正确地拼写了你的文件名,另一次你不会,你可能会浪费更多的时间来追逐你的尾巴。
处理一致的缩进,它将使您的程序更容易阅读,为您和其他任何人。
如果要使用DISPLAY验证逻辑路径,则需要显示用于确定逻辑路径的值(在本例中为FOUT)。
READ语句有两种“格式”。一个是顺序读取,一个是使用密钥读取。当每个都减少到其强制性内容时,它们是相同的。因此,根据编译器,不清楚哪种类型的READ是默认值(何时不显式)或默认值(每个文件)。所以我总是说清楚:
READ PRODUCTEN KEY IS WS-PRODUCTID
然后我会使用FILE STATUS字段来确定是否已读取密钥(状态为00)或未找到密钥(23)或其他内容(其他内容)。
注意:此答案作为您问题的解决方案仅在您所描述的一切都有效时才有效。进一步的信息可能会使本答案无效。
答案确实可以作为一种更清晰(因此更好)的方式来编写COBOL程序。
原来是一个可疑的已损坏文件。此可能导致INVALID KEY和FILE STATUS之间存在差异,但在正常的事件过程中不会发生。它是唯一符合所有证据的东西,但这是一个例外情况,如果没有完全相同的文件损坏并且在一般情况下抓住这根稻草,为什么给定的程序不工作可能无法重现歹徒的第一个避难所。