我正处于大学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年“)。
答案 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