接受“ESC-CODE FROM ESCAPE KEY”的麻烦

时间:2015-02-15 14:25:44

标签: cobol gnucobol

使用 Microsoft COBOL编译器2.2版,我的代码完全正常。

   IDENTIFICATION DIVISION.
   PROGRAM-ID. COCENTRY.
   ENVIRONMENT DIVISION.
   INPUT-OUTPUT SECTION.
   FILE-CONTROL.
       SELECT COC-FILE
         ASSIGN TO DISK
         ORGANIZATION IS INDEXED
         ACCESS MODE IS RANDOM
         RECORD KEY IS COCNO
           FILE STATUS IS FILE-STATUS.
   DATA DIVISION.
   FILE SECTION.
   FD  COC-FILE LABEL RECORD IS STANDARD
       VALUE OF FILE-ID IS "COC.DAT".
   01  COC-RECORD.
       03  COCNO            PIC 9(5).
       03  COCDESC          PIC X(40).
   WORKING-STORAGE SECTION.
   01  FILE-STATUS  PIC XX.
   01  ESC-CODE PIC 99 VALUE 0.
       88  ESC-KEY  VALUE 1.
       88  F2       VALUE 3.
       88  F10      VALUE 11.
   01  ERRMSG       PIC X(70) VALUE SPACES.
   01  ERR          PIC 9 VALUE 0.
   SCREEN SECTION.
   01  FORM1.
       03 BLANK SCREEN BACKGROUND-COLOR 1.
       03 LINE 1 COLUMN 1 'COCNO'.
       03 LINE 2 COLUMN 1 'COCDESC'.
       03 LINE 24 COLUMN 1 "Esc=Exit  F2=Save  F10=Cancel".
       03 LINE 25 COLUMN 1 PIC X(70) FROM ERRMSG HIGHLIGHT.
   01  FORM2.
       03 LINE 1 COLUMN 14 PIC 9(5)
          USING COCNO REVERSE-VIDEO.
       03 LINE 2 COLUMN 14 PIC X(40)
          USING COCDESC REVERSE-VIDEO.
       03 LINE 24 COLUMN 1 PIC 99
          USING ESC-CODE.
   PROCEDURE DIVISION.
   MAIN.
       OPEN I-O COC-FILE.
       IF FILE-STATUS NOT = '00'
           OPEN OUTPUT COC-FILE
           CLOSE COC-FILE
           OPEN I-O COC-FILE.
       PERFORM ENTRY1 THRU ENTRYX UNTIL ESC-KEY.
       CLOSE COC-FILE.
       STOP RUN.
   ENTRY1.
       MOVE SPACES TO COC-RECORD.
       MOVE ZEROES TO COCNO.
   ENTRY2.
       DISPLAY FORM1 FORM2.
       ACCEPT FORM2.
       ACCEPT ESC-CODE FROM ESCAPE KEY.
       IF F10
           MOVE 'Entries canceled...' TO ERRMSG
           GO ENTRY1
       ELSE IF F2
           GO ENTRY3
       ELSE IF ESC-KEY
           GO ENTRYX
       ELSE
           GO ENTRY2.
   ENTRY3.
       MOVE 0 TO ERR.
       WRITE COC-RECORD INVALID KEY MOVE 1 TO ERR.
       IF ERR = 1
           MOVE 'Duplicate key not allowed...' TO ERRMSG
           GO ENTRY2
       ELSE
           MOVE 'Entries recorded...' TO ERRMSG
           GO ENTRY1.
   ENTRYX.
       EXIT.

现在我正在使用具有GNUCobol版本1.1.0的OpenCobol IDE 4.3.0 ,我被提示使用这行

syntax error, unexpected "Literal", expecting LEADING or TRAILING

 03 LINE 1 COLUMN 1 'COCNO'.
 03 LINE 2 COLUMN 1 'COCDESC'.
 03 LINE 24 COLUMN 1 "Esc=Exit  F2=Save  F10=Cancel".

所以我通过添加 VALUE 关键字来修复它们:

 03 LINE 1 COLUMN 1 VALUE 'COCNO'.
 03 LINE 2 COLUMN 1 VALUE 'COCDESC'.
 03 LINE 24 COLUMN 1 VALUE "Esc=Exit  F2=Save  F10=Cancel".

但是一旦我这样做,我得到另一个提示

'ACCEPT .. FROM ESCAPE KEY' not implemented

在这一行

ACCEPT ESC-CODE FROM ESCAPE KEY.

可能的原因是什么?什么可以解决这个问题?

3 个答案:

答案 0 :(得分:4)

你的实际答案就在这里,https://sourceforge.net/p/open-cobol/discussion/help/thread/26a01c5f/,在SourceForge的GnuCOBOL部分。通过微小的更改,您的代码将完全正常工作"您已经做出的更改包括VALUE子句,以及您是否使用GnuCOBOL编译器的2.0或更高版本。

您的代码可以完全正常工作"但它是意大利面条代码。

该术语来自过去,涉及在程序中使用许多分支,这是当时的常见做法,但是它试图遵循逻辑过程,例如尝试遵循一串煮熟的意大利面条。一堆熟意大利面的一部分。

如果你改变了这个:

PERFORM ENTRY1 THRU ENTRYX UNTIL ESC-KEY.

对此:

PERFORM ENTRY1 THRU ENTRYX.

您的计划仍然有效。困惑?是的,因为你有意大利面。您的程序流程只会转到ENTRYX一次。当它到达ENTRYX时的值是ESC-KEY,但这是多余的,因为当它是ESC-KEY时它只能到达那里一次。明确?没有?因为你有意大利面。

这是你的逻辑,重写:

   PROCEDURE DIVISION.
       OPEN I-O COC-FILE
       IF FILE-STATUS NOT = '00'
           [the following code is a horror. Deal with this outside the 
           program. Crash for an unexpected FILE STATUS on OPEN]
           OPEN OUTPUT COC-FILE
           CLOSE COC-FILE
           OPEN I-O COC-FILE
       END-IF
       PERFORM PROCESS-USER-INPUT
         UNTIL ESC-KEY
       CLOSE COC-FILE
       IF FILE-STATUS NOT = '00'
           [something bad has happened, so don't go quietly]
       END-IF
       GOBACK
       .
   PROCESS-USER-INPUT.
       PERFORM BLANK-OUTPUT-RECORD
       PERFORM PROCESS-COC
         UNTIL ESC-KEY
       .
   PROCESS-COC.

       DISPLAY FORM1 FORM2
       ACCEPT FORM2
       ACCEPT ESC-CODE FROM ESCAPE KEY
       EVALUATE TRUE
         WHEN F10
           MOVE 'Entries canceled...' TO ERRMSG
         WHEN F2
           PERFORM CREATE-OUTPUT
       END-EVALUATE
       .
   CREATE-OUTPUT.
       WRITE COC-RECORD 
       IF ATTEMPT-TO-WRITE-DUPLICATE [22 on the FILE STATUS field]
           MOVE 'Duplicate key not allowed...' TO ERRMSG
       ELSE
           MOVE 'Entries recorded...' TO ERRMSG
           PERFORM BLANK-OUTPUT-RECORD
       END-IF
       .
   BLANK-OUTPUT-RECORD.
       MOVE SPACES TO COC-RECORD
       MOVE ZEROES TO COCNO
       .

这会让您的程序看起来更简单吗?更容易理解,改变,理解当别人看到它时(或者你在两周内做的时候)它会做什么?

还有其他的东西,比如为什么将COC-RECORD设置为空格,然后将COCNO设置为零?将空格移动到COCDESC。

使您的数据/程序名称更好且更具描述性。文件状态具有良好的名称(不要将其称为FILE-STATUS),如果您有多个文件,则每个文件一个。仅在必要时使用完全停止/句点,并对您使用的所有条件结构使用范围分隔符。对所有IO使用FILE STATUS检查,不要在IO上使用曲折的AT。

如果您现在看起来程序中的第一个代码很长,只执行一次,并且(应该)与您的程序的业务功能无关。所以坚持段落中的所有内容,然后执行。收盘也一样。然后,您可以在启动和关闭时获得所需的代码,而不会使您的程序更难以遵循。

答案 1 :(得分:3)

屏幕和键盘I / O是MicroSoft Cobol特有的风格。您可能需要稍微调整一下才能使其与OpenCobol一起使用。

答案 2 :(得分:0)

PROCEDURE DIVISION.
           SET ENVIRONMENT 'COB_SCREEN_EXCEPTIONS' TO 'Y'.
           SET ENVIRONMENT 'COB_SCREEN_ESC'        TO 'Y'.
  • 逃脱:IF cob-crt-status = 2005 ......
  • 输入:IF cob-crt-status = 0 ........
  • F1:IF cob-crt-status = 1001 ......
  • F2:IF cob-crt-status = 1002 ......