COBOL中的数据验证

时间:2011-05-21 15:59:44

标签: cobol

我正处于大学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.

此外,我必须确保名为POLI-ITEM-ID的字段中的记录已存在于名为ITEM-MASTER的另一个索引文件中。我不确定如何做到这一点,但我认为它涉及临时打开文件并进行搜索。如果有人能告诉我如何做到这一点,我将不胜感激,因为这两件事似乎是今天阻止我的唯一事情。我提前感谢所有人的帮助。

编辑:输入数据写在作为程序一部分的屏幕图像上。因此,我知道我在入境时输入的内容是正确的。如果它有帮助,我已将SCREEN SELECTION放入代码中,但我认为它与我的日期条目被视为错误的原因有关(即我输入“2011”并且它在屏幕上告诉我“年份必须是2011年或2012年“)。

4 个答案:

答案 0 :(得分:4)

   05  POLI-DATE-REQUESTED-S.
       10 POLI-DATE-REQUESTED-S-1  PIC 9999.
          88 Year-Valid            value 2011 thru 2012.
       10 POLI-DATE-REQUESTED-S-2  PIC 99.
          88 Month-Valid           value 01 thru 12.
       10 POLI-DATE-REQUESTED-S-4  PIC 99.              
          88 Day-Valid             value 01 thru 31.

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

  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

答案 1 :(得分:2)

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

   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.  

课程:始终使用IS NUMERIC测试验证数字字段,然后进行范围测试。

此外,除非输入数据已经过预编辑以确保有效性, 将外部数据直接读入数字并不是一个好主意 数据类型。读一个'1b' 将文件直接输入到PIC 9(2)数据项中,得到值12(基于ebcdic 环境)。现在,这将通过IS NUMERIC测试以及范围测试 实际输入数据不是数字。 “自动”转换的原因是 有点超出了这个讨论 - 我们只想说COBOL中的数据移动规则 比大多数人欣赏要复杂得多。

答案 2 :(得分:1)

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

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

IF POLI-DATE-REQUESTED-S-1 IS NOT = '20'

或者更好地将您的数据值定义为数字:

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

答案 3 :(得分:0)

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