COBOL中的数据验证

COBOL中的数据验证,cobol,Cobol,我在大学里学习COBOL的最后一门课程,我必须编写交互程序,用来跟踪企业的库存。我已经达到了我有问题的几个部分。第一个是验证日期是否在2011年和2012年之间,第二个是月数和日数是否分别在1-12和1-31之间。当我运行我的程序时,它总是在错误报告中说这一年是错误的,即使我把它放对了。以下是我对该部分的代码: WORKING-STORAGE SECTION. 05 POLI-DATE-REQUESTED-S. 10 POLI-DATE-REQUEST

我在大学里学习COBOL的最后一门课程,我必须编写交互程序,用来跟踪企业的库存。我已经达到了我有问题的几个部分。第一个是验证日期是否在2011年和2012年之间,第二个是月数和日数是否分别在1-12和1-31之间。当我运行我的程序时,它总是在错误报告中说这一年是错误的,即使我把它放对了。以下是我对该部分的代码:

   WORKING-STORAGE SECTION.
       05  POLI-DATE-REQUESTED-S.
           10 POLI-DATE-REQUESTED-S-1  PIC XX.
           10 POLI-DATE-REQUESTED-S-2  PIC XX.
           10 POLI-DATE-REQUESTED-S-3  PIC XX.
           10 POLI-DATE-REQUESTED-S-4  PIC XX.

   SCREEN SECTION.
   01  SCREEN-IMAGE.
       05  BLANK SCREEN
           BACKGROUND-COLOR 0.
       05  LINE 02  COLUMN 02          PIC X(8)
               FROM TIME-HHMMSSXX-COLONS
               FOREGROUND-COLOR 15.
       05  LINE 02  COLUMN 25
               VALUE 'Purchase Order Line Item Maintenance'
               FOREGROUND-COLOR 14.
       05  LINE 02  COLUMN 70          PIC X(8)
               FROM DATE-MMDDYY-SLASHES
               FOREGROUND-COLOR 15.
       05  LINE 04  COLUMN 02  VALUE 'FUNCTION CODE:'
               FOREGROUND-COLOR 10.
       05  LINE 04  COLUMN 18          PIC X(3)
               USING FUNCTION-CODE-S
               FOREGROUND-COLOR 15 AUTO.
       05  LINE 04  COLUMN 23  VALUE '(ADD, CHG, DEL, INQ, END)'
               FOREGROUND-COLOR 11.
       05  LINE 07  COLUMN 23  VALUE 'NUMBER:'
               FOREGROUND-COLOR 10.
       05  LINE 07  COLUMN 50          PIC X(4)
               USING POLI-VEND-NUMBER-S
               FOREGROUND-COLOR 15 AUTO.
       05  LINE 08  COLUMN 23  VALUE 'ORDER ID:'
               FOREGROUND-COLOR 10.
       05  LINE 08  COLUMN 50          PIC X(8)
               USING POLI-ORDER-ID-S
               FOREGROUND-COLOR 15 AUTO.
       05  LINE 09  COLUMN 23  VALUE 'LINE ITEM:'
               FOREGROUND-COLOR 10.
       05  LINE 09  COLUMN 50          PIC X(4)
               USING POLI-LINE-ITEM-S
               FOREGROUND-COLOR 15 AUTO.
       05  LINE 10  COLUMN 23  VALUE 'ITEM ID:'
               FOREGROUND-COLOR 10.
       05  LINE 10  COLUMN 50          PIC X(10)
               USING POLI-ITEM-ID-S
               FOREGROUND-COLOR 15 AUTO.
       05  LINE 11  COLUMN 23  VALUE 'QUANTITY:'
               FOREGROUND-COLOR 10.
       05  LINE 11  COLUMN 50          PIC X(5)
               USING POLI-QUANTITY-S
               FOREGROUND-COLOR 15 AUTO.
       05  LINE 12  COLUMN 23  VALUE 'DATE REQUESTED (YYYYMMDD):'
               FOREGROUND-COLOR 10.
       05  LINE 12  COLUMN 50          PIC X(8)
               USING POLI-DATE-REQUESTED-S
               FOREGROUND-COLOR 15 AUTO.
       05  LINE 13  COLUMN 23  VALUE 'QUOTED COST:'
               FOREGROUND-COLOR 10.
       05  LINE 13  COLUMN 50          PIC X(7)
               USING POLI-QUOTED-COST-S
               FOREGROUND-COLOR 15 AUTO.
       05  LINE 17  COLUMN 23  VALUE 'DATE ADDED:'
               FOREGROUND-COLOR 10.
       05  LINE 17  COLUMN 40  PIC X(10)
               USING POLI-DATE-ADDED-S
               FOREGROUND-COLOR 15.
       05  LINE 18  COLUMN 23  VALUE 'DATE-CHANGED:'
               FOREGROUND-COLOR 10.
       05  LINE 18  COLUMN 40  PIC X(10)
               USING POLI-DATE-CHANGED-S
               FOREGROUND-COLOR 15.
       05  LINE 23  COLUMN 23  PIC X(55)
               FROM ERROR-MESSAGE-S
               FOREGROUND-COLOR 12.

   PROCEDURE DIVISION.
   900-VALIDATE-THE-FIELDS.
       IF POLI-DATE-REQUESTED-S-1 IS NOT = 20
           MOVE 'Year must be 2011 OR 2012' TO ERROR-MESSAGE-S
           GO TO 999-EXIT
       END-IF
       IF POLI-DATE-REQUESTED-S-2 IS NOT = 11 OR 12
           MOVE 'Year Must Be 2011 Or 2012' TO ERROR-MESSAGE-S
           GO TO 999-EXIT
       END-IF
       IF POLI-DATE-REQUESTED-S-3 IS < 1 OR > 12
           MOVE 'Month Must Be 1 Through 12' TO ERROR-MESSAGE-S
           GO TO 999-EXIT
       END-IF
       IF POLI-DATE-REQUESTED-S-4 IS < 1 OR > 31
           MOVE 'Day Must Be 1 Through 31' TO ERROR-MESSAGE-S
           GO TO 999-EXIT
       END-IF.
工作存储部分。
05 POLI-DATE-REQUESTED-S。
10 POLI-DATE-REQUESTED-S-1图XX。
10 POLI-DATE-REQUESTED-S-2图XX。
10 POLI-DATE-REQUESTED-S-3图XX。
10 POLI-DATE-REQUESTED-S-4图XX。
屏幕部分。
01屏幕图像。
05空白屏幕
背景色0。
05第02行第02列图X(8)
从TIME-HHMSSXX-COLONS
前景色15。
05第02行第25列
值“采购订单行项目维护”
前景色14。
05第02行第70列图X(8)
从DATE-MMDDYY-SLASHES开始
前景色15。
05第04行第02列值“功能代码:”
前景色10。
05第04行第18列图X(3)
使用FUNCTION-CODE-S
前景色15自动。
05第04行第23列值“(添加、更改、删除、输入、结束)”
前景色11。
05第07行第23列值“编号:”
前景色10。
05第07行第50列图X(4)
使用POLI-VEND-NUMBER-S
前景色15自动。
05第08行第23列值“订单ID:”
前景色10。
05第08行第50列图X(8)
使用POLI-ORDER-ID-S
前景色15自动。
05第09行第23列值“行项目:”
前景色10。
05第09行第50列图X(4)
使用POLI-LINE-ITEM-S
前景色15自动。
05第10行第23列值“项目ID:”
前景色10。
05第10行第50列图X(10)
使用POLI-ITEM-ID-S
前景色15自动。
05第11行第23列值“数量:”
前景色10。
05第11行第50列图X(5)
使用POLI-QUANTITY-S
前景色15自动。
05第12行第23列值“请求的日期(YYYYMMDD):”
前景色10。
05第12行第50列图X(8)
使用POLI-DATE-REQUESTED-S
前景色15自动。
05第13行第23列“报价成本:”
前景色10。
05第13行第50列图X(7)
使用POLI-QUOTED-COST-S
前景色15自动。
05第17行第23列“添加日期:”
前景色10。
05第17行第40列图X(10)
使用POLI-DATE-ADDED-S
前景色15。
05第18行第23列值“更改日期:”
前景色10。
05第18行第40列图X(10)
使用POLI-DATE-CHANGED-S
前景色15。
05第23行第23列图X(55)
来自错误消息-S
前景色12。
程序司。
900-VALIDATE-THE-FIELDS。
如果POLI-DATE-REQUESTED-S-1不等于20
将“年份必须为2011年或2012年”移至错误消息-S
去999出口
端到端IF
如果POLI-DATE-REQUESTED-S-2不等于11或12
将“年份必须为2011年或2012年”移至错误消息-S
去999出口
端到端IF
如果POLI-DATE-REQUESTED-S-3小于1或大于12
将“月份必须为1到12”移动到错误消息-S
去999出口
端到端IF
如果POLI-DATE-REQUESTED-S-4小于1或大于31
将“日期必须为1到31”移动到错误消息-S
去999出口
结束-如果。
此外,我必须确保名为POLI-ITEM-ID的字段中的记录已经存在于另一个名为ITEM-MASTER的索引文件中。我不太清楚如何做到这一点,但我认为这涉及到临时打开文件并搜索它。如果有人能告诉我如何做到这一点,我将不胜感激,因为这两件事似乎是今天阻碍我前进的唯一原因。我提前感谢大家的帮助

编辑:输入数据写入作为程序一部分的屏幕图像。因此,我知道我输入的内容在输入时是正确的。如果有帮助,我已经在代码中输入了屏幕选择,但我认为这与为什么我的日期输入被视为错误没有任何关系(即,我输入了“2011”,屏幕上告诉我“年份必须是2011年或2012年”)

尝试像这样重新定义字段。然后,您可以使用以下工具对字段进行简单测试:

  IF not Year-Valid
       MOVE 'Year must be 2011 OR 2012' TO ERROR-MESSAGE-S
  Else
       IF not Month-Valid
          MOVE 'Month Must Be 1 Through 12' TO ERROR-MESSAGE-S
       Else
          IF not Day-Valid
              MOVE 'Day Must Be 1 Through 31' TO ERROR-MESSAGE-S
          END-IF
       END-IF
  END-IF
要处理查找,请直接读取ITEM-MASTER文件。这将涉及如下内容:

   SELECT ITEM-MASTER ASSIGN TO "fname.txt"
      ORGANIZATION IS INDEXED
      ACCESS MODE IS DYNAMIC
      RECORD KEY IS ITEM-MASTER-KEY.
然后直接阅读:

  READ ITEM-MASTER
     KEY IS POLI-ITEM-ID
     INVALID KEY  DISPLAY "error or something"
  END-READ

Joe Zitzelberger的帖子是推荐的“干净”方式

我只想指出,您原始代码中的错误是将XX和数字类型混淆了。您应该在测试中使用字符文字:

IF POLI-DATE-REQUESTED-S-1 IS NOT = '20'
或者,最好将数据值定义为数字:

 10 POLI-DATE-REQUESTED-S-1  PIC 99.

小心-接受的解决方案不能保证数值。 以下程序说明了这一点:

   PROGRAM-ID. EXAMPLE.                       
   DATA DIVISION.                             
   WORKING-STORAGE SECTION.                   
   01  TXT-VALUE        PIC X(4).             
   01  NUM-VALUE        PIC 9(4).             
       88 WS-VALID-NUM  VALUE  2000 THRU 2999.
   PROCEDURE DIVISION.                        
       MOVE '21b1' TO TXT-VALUE               
       MOVE TXT-VALUE TO NUM-VALUE            
       DISPLAY 'NUM-VALUE: ' NUM-VALUE        
       IF WS-VALID-NUM                        
          DISPLAY 'passed the range test.'    
       END-IF                                 
       IF NUM-VALUE IS NUMERIC                
          DISPLAY 'passed numeric test.'      
       ELSE                                   
          DISPLAY 'failed numeric test.'      
       END-IF                                 
这将导致以下输出:

NUM-VALUE: 21b1       
passed the range test.
failed numeric test.  
经验教训:始终使用
是数字测试和范围测试验证数字字段

此外,除非输入数据已为有效性进行了预编辑, 这不是一个问题
NUM-VALUE: 21b1       
passed the range test.
failed numeric test.  
01  FILLER. 
05  POLI-DATE-REQUESTED-S. 
    10  POLI-DATE-REQUESTED-S-1  PIC XXXX. 
        88  YEAR-VALID            VALUE "2011" THRU "2012". 
    10  POLI-DATE-REQUESTED-S-2  PIC XX. 
        88  MONTH-VALID           VALUE "01" THRU "12". 
        88  MONTH-IS-FEB          VALUE "02". 
        88  MONTH-IS-30-DAYS      VALUE "04" "06" "09" "11".
    10  POLI-DATE-REQUESTED-S-4  PIC XX. 
        88  DAY-MAY-BE-VALID      VALUE "01" THRU "31". 
        88  VALID-FEB-DAYS        VALUE "01" THRU "28". 
        88  VALID-30-DAYS         VALUE "01" THRU "30". 
MOVE SPACE                   TO ERROR-MESSAGE-S
EVALUATE TRUE 
  WHEN NOT POLI-DATE-REQUESTED-S NUMERIC 
      MOVE 'DATE MUST ONLY BE NUMBERS' 
                             TO ERROR-MESSAGE-S
  WHEN NOT YEAR-VALID 
    MOVE 'YEAR MUST BE 2011 OR 2012' 
                             TO ERROR-MESSAGE-S
  WHEN NOT MONTH-VALID 
    MOVE 'MONTH MUST BE 01 THROUGH 12' 
                             TO ERROR-MESSAGE-S
  WHEN NOT DAY-MAY-BE-VALID 
    MOVE "DAY IS ZERO OR MORE THAN 31" 
                             TO ERROR-MESSAGE-S
END-EVALUATE 
MOVE SPACE                   TO ERROR-MESSAGE-S
EVALUATE TRUE 
  WHEN NOT POLI-DATE-REQUESTED-S NUMERIC 
      MOVE 'DATE MUST ONLY BE NUMBERS' 
                             TO ERROR-MESSAGE-S
  WHEN NOT YEAR-VALID 
    MOVE 'YEAR MUST BE 2011 OR 2012' 
                             TO ERROR-MESSAGE-S
  WHEN NOT MONTH-VALID 
    MOVE 'MONTH MUST BE 01 THROUGH 12' 
                             TO ERROR-MESSAGE-S
  WHEN NOT DAY-MAY-BE-VALID 
    MOVE "DAY IS ZERO OR MORE THAN 31" 
                             TO ERROR-MESSAGE-S
  WHEN ( MONTH-IS-FEB 
       AND NOT VALID-FEB-DAYS ) 
   MOVE 'TOO MANY DAYS FOR FEBRUARY' 
                             TO ERROR-MESSAGE-S
  WHEN ( MONTH-IS-30-DAYS 
       AND NOT VALID-30-DAYS ) 
   MOVE 'NO 31ST THIS MONTH' 
                             TO ERROR-MESSAGE-S
END-EVALUATE