一个奇怪的错误(COBOL)
嘿,大家,这里有一大堆问题。我已经完成了一个我必须为大学作业做的程序,但是当我运行它时,输出几乎没有显示它应该做的任何事情。这只会在我运行它时发生。如果我按住F11键,一步一步地完成整个过程,它会显示预期的结果。通常我不会问这么大的问题,但我被难住了。这是我的密码:一个奇怪的错误(COBOL),cobol,Cobol,嘿,大家,这里有一大堆问题。我已经完成了一个我必须为大学作业做的程序,但是当我运行它时,输出几乎没有显示它应该做的任何事情。这只会在我运行它时发生。如果我按住F11键,一步一步地完成整个过程,它会显示预期的结果。通常我不会问这么大的问题,但我被难住了。这是我的密码: ENVIRONMENT DIVISION. INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT SALESAMT-FILE-IN ASSIGN
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT SALESAMT-FILE-IN
ASSIGN TO 'SALESAMT.SEQ'
ORGANIZATION IS LINE SEQUENTIAL.
SELECT SALESMAN-FILE-IN
ASSIGN TO 'SALESMAN.SEQ'
ORGANIZATION IS LINE SEQUENTIAL.
SELECT SALESQTR-FILE-IN
ASSIGN TO 'SALESQTR.SEQ'
ORGANIZATION IS LINE SEQUENTIAL.
SELECT SALESAMT-FILE-OUT
ASSIGN TO 'SALESAMT.RPT'
ORGANIZATION IS LINE SEQUENTIAL.
DATA DIVISION.
FILE SECTION.
FD SALESMAN-FILE-IN.
01 SALESMAN-RECORD-IN.
05 SM-NUMBER-IN PIC 99.
05 SM-NAME-IN PIC X(20).
FD SALESQTR-FILE-IN.
01 SALESQTR-RECORD-IN.
05 QUARTER-YEAR PIC X.
FD SALESAMT-FILE-IN.
01 SALESAMT-RECORD-IN.
05 SM-NUMBER PIC 99.
05 PIC X.
05 MONTH-NUMBER PIC 9.
05 PIC X.
05 SALES-AMOUNT PIC 9(5).
FD SALESAMT-FILE-OUT.
01 SALESAMT-RECORD-OUT PIC X(80).
WORKING-STORAGE SECTION.
01 ARE-THERE-MORE-RECORDS PIC X(3) VALUE 'YES'.
01 REPORT-START PIC X VALUE 'Y'.
01 LINE-COUNT PIC 99 VALUE ZEROS.
01 LINE-JUMP PIC X VALUE 'Y'.
01 PAGE-NUMBER PIC 99 VALUE ZEROS.
01 QUARTER-CHECK PIC X.
01 ROUTINE-CHECK PIC 99 VALUE ZEROS.
01 SALESMAN-MATH PIC 9(5) VALUE ZEROS.
01 SALESMAN-TOTAL PIC 9(6) VALUE ZEROS.
01 FINAL-M-TOTAL-1 PIC 9(7) VALUE ZEROS.
01 FINAL-M-TOTAL-3 PIC 9(7) VALUE ZEROS.
01 FINAL-M-TOTAL-2 PIC 9(7) VALUE ZEROS.
01 FINAL-TOTAL PIC 9(7) VALUE ZEROS.
01 SM-NUM-M PIC 99 VALUE ZEROS.
01 MORE-TABLE-RECS PIC X VALUE 'Y'.
01 SPACE-LINE PIC X VALUE SPACE.
01 MONTH-NAMES
VALUE 'JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC'.
05 MONTH-TITLES OCCURS 12 TIMES PIC X(3).
01 MONTH-ARRAY.
05 THREE-MONTHS OCCURS 3 TIMES.
10 MONTH-TOTAL OCCURS 99 TIMES PIC 9(7) VALUE ZEROS.
01 SALESMAN-TABLE.
05 TABLE-ENTRIES OCCURS 99 TIMES
INDEXED BY IND-TABLE-ENTRIES.
10 SALESMAN-NUMBER PIC 99 VALUE ZEROS.
10 SALESMAN-NAME PIC X(20) VALUE SPACES.
01 SALESMAN-COUNT PIC 9(3) VALUE ZEROS.
01 WS-DATE.
05 RUN-YEAR PIC XX.
05 RUN-MONTH PIC XX.
05 RUN-DAY PIC XX.
01 HEADING-LINE-1.
05 PIC X(17) VALUE SPACES.
05 PIC X(35)
VALUE 'SALES AMOUNTS BY SALESMAN AND MONTH'.
05 PIC X(10) VALUE SPACES.
05 HL-1-DATE.
10 MONTH-2 PIC XX.
10 PIC X VALUE '/'.
10 DAY-2 PIC XX.
10 PIC X VALUE '/'.
10 YEAR-2 PIC XX.
05 PIC X(3) VALUE SPACES.
05 PAGE-1 PIC X(4) VALUE 'PAGE'.
05 PIC X(1) VALUE SPACES.
05 NUMBER-PAGE PIC Z9.
01 HEADING-LINE-2.
05 HL-NUM PIC X(3) VALUE 'NUM'.
05 HL-BLANK-A PIC XX VALUE SPACES.
05 HL-NAME PIC X(4) VALUE 'NAME'.
05 HL-BLANK-B PIC X(20) VALUE SPACES.
05 HL-MONTH-1 PIC X(3) VALUE SPACES.
05 HL-BLANK-C PIC X(8) VALUE SPACES.
05 HL-MONTH-2 PIC X(3) VALUE SPACES.
05 HL-BLANK-D PIC X(8) VALUE SPACES.
05 HL-MONTH-3 PIC X(3) VALUE SPACES.
05 HL-BLANK-E PIC X(10) VALUE SPACES.
05 HL-TOTAL PIC X(5) VALUE 'TOTAL'.
01 DETAIL-LINE.
05 DL-BLANK-A PIC X VALUE SPACES.
05 DL-NUM-COLUMN PIC 99.
05 DL-BLANK-B PIC XX VALUE SPACES.
05 DL-NAME-COLUMN PIC X(17).
05 DL-BLANK-C PIC X(4) VALUE SPACES.
05 DL-MONTH-1 PIC ZZ,Z(3).
05 DL-BLANK-D PIC X(5) VALUE SPACES.
05 DL-MONTH-2 PIC ZZ,Z(3).
05 DL-BLANK-E PIC X(5) VALUE SPACES.
05 DL-MONTH-3 PIC ZZ,Z(3).
05 DL-BLANK-F PIC X(8) VALUE SPACES.
05 DL-TOTAL PIC Z(3),Z(3).
01 TOTALS-LINE.
05 TL-WORDS PIC X(12)
VALUE 'Final Totals'.
05 TL-BLANK-A PIC X(12) VALUE SPACES.
05 MONTH-1-TOTAL PIC Z,Z(3),Z(3).
05 TL-BLANK-A PIC X(2) VALUE SPACES.
05 MONTH-2-TOTAL PIC Z,Z(3),Z(3).
05 TL-BLANK-A PIC X(2) VALUE SPACES.
05 MONTH-3-TOTAL PIC Z,Z(3),Z(3).
05 TL-BLANK-A PIC X(5) VALUE SPACES.
05 MONTH-FINAL-TOTAL PIC Z,Z(3),Z(3).
PROCEDURE DIVISION.
100-MAIN.
OPEN INPUT SALESAMT-FILE-IN, SALESMAN-FILE-IN,
SALESQTR-FILE-IN
OPEN OUTPUT SALESAMT-FILE-OUT
ACCEPT WS-DATE FROM DATE
MOVE RUN-MONTH TO MONTH-2
MOVE RUN-DAY TO DAY-2
MOVE RUN-YEAR TO YEAR-2
PERFORM 200-NEXT-PAGE
PERFORM 300-SALES-ARRAY
PERFORM 400-SALESMAN-NAME
PERFORM 500-PROCESS-FILE
PERFORM 600-FINAL-TOTALS
CLOSE SALESAMT-FILE-IN, SALESMAN-FILE-IN, SALESQTR-FILE-IN
CLOSE SALESAMT-FILE-OUT
STOP RUN.
200-NEXT-PAGE.
ADD 1 TO PAGE-NUMBER
MOVE PAGE-NUMBER TO NUMBER-PAGE
MOVE HEADING-LINE-1 TO SALESAMT-RECORD-OUT
IF REPORT-START = 'N'
WRITE SALESAMT-RECORD-OUT
AFTER ADVANCING PAGE
ELSE
MOVE 'N' TO REPORT-START
WRITE SALESAMT-RECORD-OUT
AFTER ADVANCING 1 LINE
PERFORM 210-MONTH-CHECK
END-IF.
MOVE HEADING-LINE-2 TO SALESAMT-RECORD-OUT
WRITE SALESAMT-RECORD-OUT
AFTER ADVANCING 2 LINES
MOVE ZEROS TO LINE-COUNT.
210-MONTH-CHECK.
READ SALESQTR-FILE-IN
AT END
CONTINUE
NOT AT END
PERFORM 220-MONTH-NAME
END-READ.
220-MONTH-NAME.
EVALUATE QUARTER-YEAR
WHEN = 1 MOVE MONTH-TITLES(1) TO HL-MONTH-1
MOVE MONTH-TITLES(2) TO HL-MONTH-2
MOVE MONTH-TITLES(3) TO HL-MONTH-3
WHEN = 2 MOVE MONTH-TITLES(4) TO HL-MONTH-1
MOVE MONTH-TITLES(5) TO HL-MONTH-2
MOVE MONTH-TITLES(6) TO HL-MONTH-3
WHEN = 3 MOVE MONTH-TITLES(7) TO HL-MONTH-1
MOVE MONTH-TITLES(8) TO HL-MONTH-2
MOVE MONTH-TITLES(9) TO HL-MONTH-3
WHEN = 4 MOVE MONTH-TITLES(10) TO HL-MONTH-1
MOVE MONTH-TITLES(11) TO HL-MONTH-2
MOVE MONTH-TITLES(12) TO HL-MONTH-3
END-EVALUATE.
300-SALES-ARRAY.
PERFORM UNTIL ARE-THERE-MORE-RECORDS = 'NO '
READ SALESAMT-FILE-IN
AT END
MOVE 'NO ' TO ARE-THERE-MORE-RECORDS
NOT AT END
PERFORM 310-STORE-DATA
END-READ
END-PERFORM.
310-STORE-DATA.
MOVE SM-NUMBER TO SM-NUM-M
EVALUATE MONTH-NUMBER
WHEN 1 PERFORM 320-FIRST-MONTH
WHEN 2 PERFORM 330-SECOND-MONTH
WHEN 3 PERFORM 340-THIRD-MONTH
END-EVALUATE.
320-FIRST-MONTH.
ADD SALES-AMOUNT TO
MONTH-TOTAL OF MONTH-ARRAY (1, SM-NUM-M).
330-SECOND-MONTH.
ADD SALES-AMOUNT TO
MONTH-TOTAL OF MONTH-ARRAY (2, SM-NUM-M).
340-THIRD-MONTH.
ADD SALES-AMOUNT TO
MONTH-TOTAL OF MONTH-ARRAY (3, SM-NUM-M).
400-SALESMAN-NAME.
PERFORM UNTIL MORE-TABLE-RECS = 'N'
READ SALESMAN-FILE-IN
AT END
MOVE 'N' TO MORE-TABLE-RECS
NOT AT END
PERFORM 450-TABLE-LOAD
END-READ
END-PERFORM.
450-TABLE-LOAD.
MOVE SM-NUMBER-IN TO SALESMAN-COUNT
MOVE SM-NUMBER-IN TO SALESMAN-NUMBER (SALESMAN-COUNT)
MOVE SM-NAME-IN TO SALESMAN-NAME (SALESMAN-COUNT).
500-PROCESS-FILE.
PERFORM UNTIL ROUTINE-CHECK = 99
ADD 1 TO ROUTINE-CHECK
PERFORM 510-TABLE-SEARCH
END-PERFORM.
510-TABLE-SEARCH.
SEARCH TABLE-ENTRIES
WHEN SALESMAN-NUMBER (ROUTINE-CHECK) = ROUTINE-CHECK
PERFORM 520-WRITE-FILE
WHEN SALESMAN-NUMBER (ROUTINE-CHECK) = 0
CONTINUE
END-SEARCH.
520-WRITE-FILE.
MOVE SALESMAN-NAME (ROUTINE-CHECK) TO DL-NAME-COLUMN
IF DL-NAME-COLUMN = SPACES
MOVE '*** Not Found ***' TO DL-NAME-COLUMN
END-IF
MOVE ROUTINE-CHECK TO DL-NUM-COLUMN
MOVE ROUTINE-CHECK TO SM-NUM-M
MOVE MONTH-TOTAL (1, SM-NUM-M) TO DL-MONTH-1
MOVE DL-MONTH-1 TO SALESMAN-MATH
ADD SALESMAN-MATH TO SALESMAN-TOTAL
ADD SALESMAN-MATH TO FINAL-M-TOTAL-1
ADD SALESMAN-MATH TO FINAL-TOTAL
MOVE MONTH-TOTAL (2, SM-NUM-M) TO DL-MONTH-2
MOVE DL-MONTH-2 TO SALESMAN-MATH
ADD SALESMAN-MATH TO SALESMAN-TOTAL
ADD SALESMAN-MATH TO FINAL-M-TOTAL-2
ADD SALESMAN-MATH TO FINAL-TOTAL
MOVE MONTH-TOTAL (3, SM-NUM-M) TO DL-MONTH-3
MOVE DL-MONTH-3 TO SALESMAN-MATH
ADD SALESMAN-MATH TO SALESMAN-TOTAL
ADD SALESMAN-MATH TO FINAL-M-TOTAL-3
ADD SALESMAN-MATH TO FINAL-TOTAL
IF SALESMAN-TOTAL > 0
MOVE SALESMAN-TOTAL TO DL-TOTAL
MOVE DETAIL-LINE TO SALESAMT-RECORD-OUT
WRITE SALESAMT-RECORD-OUT
AFTER ADVANCING 2 LINES
END-IF
MOVE ZEROS TO SALESMAN-TOTAL.
600-FINAL-TOTALS.
MOVE FINAL-M-TOTAL-1 TO MONTH-1-TOTAL
MOVE FINAL-M-TOTAL-2 TO MONTH-2-TOTAL
MOVE FINAL-M-TOTAL-3 TO MONTH-3-TOTAL
MOVE FINAL-TOTAL TO MONTH-FINAL-TOTAL
MOVE TOTALS-LINE TO SALESAMT-RECORD-OUT
WRITE SALESAMT-RECORD-OUT
AFTER ADVANCING 3 LINES.
对我来说,逻辑似乎是正确的,因为它确实有效,但由于某种原因,它(在我看到结果时的脑海中)在运行时完全跳过了520-WRITE-FILE。有了这些,我留下了一些笔记
SELECT SALESAMT-FILE-OUT
ASSIGN TO 'SALESAMT.RPT'
ORGANIZATION IS LINE SEQUENTIAL
File Status is FILESTATUS.
并加上: 01文件状态
02 FILESTATUS-1 Pic 9.
88 SUCCESSFULL Value 0.
88 END-OF-FILE Value 1.
88 INVALID-KEY Value 2.
88 PERMANENT-ERROR Value 3, 9.
02 FILESTATUS-2 Pic 9.
88 DUPLICATE-KEY Value 2.
88 NO-RECORD-FOUND Value 3.
88 FILE-IS-FULL Value 4.
每次对SALESAMT-FILE-OUT执行操作时,请检查文件状态。(你也可以处理其他文件)。 在这种修改的帮助下,您将能够看到在执行IO时是否有任何错误 这是第一步,所以这不是问题的最终答案。“它只显示我的两个标题行,然后是我的总计行” 在您的520-WRITE-FILE段中,您有以下代码
IF SALESMAN-TOTAL > 0
MOVE SALESMAN-TOTAL TO DL-TOTAL
MOVE DETAIL-LINE TO SALESAMT-RECORD-OUT
WRITE SALESAMT-RECORD-OUT
AFTER ADVANCING 2 LINES
END-IF
如果saller-TOTAL为零,则程序将不会打印详细信息行。
看起来您的销售人员总数中有数据或逻辑错误。我添加了这一点作为第二个答案,我认为这是正确的 520-WRITE-FILE未执行,因为调用它的搜索失败 在510-TABLE-SEARCH中,我认为您需要搜索为表声明的索引, IND-TABLE-ENTRIES。您可能需要重新编码500-PROCESS-FILE和510-TABLE-SEARCH
在另一个问题中,您询问了搜索动词。fmartin给出了一个链接,描述了它是如何工作的,并举例说明。我认为您有一个相当简单的问题,这与您当前的工作目录有关 在“环境”部分中,声明文件句柄并将其指定给文件名 调试程序时,输入文件位于当前工作目录中,因此可以正确解析
当您运行程序时,我猜您是从不同的目录运行它,因此输入文件没有解析,因此输出文件只包含一个标题行。我不确定这是否是问题所在,但我可以看到一个逻辑流不会很好地工作 首先:
400-saller-NAME
将salesmen记录从文件读入工作存储表saller-table
该文件可能类似于:
01Sales Guy One
02Lance Winslow
03Scott Peterson
04Willy Loman
500-PROCESS-FILE.
PERFORM VARYING ROUTINE-CHECK FROM 1 BY 1
UNTIL ROUTINE-CHECK > 99
IF SALESMAN-NUMBER (ROUTINE-CHECK) = ZERO
CONTINUE
ELSE
PERFORM 520-WRITE-FILE
END-IF
END-PERFORM.
读取循环完成后,saller-NUMBER
将等于表索引,因为
加载表格的方式(使用SM-NUMBER-IN
设置表格下标)。到目前为止没有问题
下一步:500-PROCESS-FILE
循环通过saller-TABLE
中的所有行,从1到99运行subscriptROUTINE-CHECK
,并执行510-TABLE-SEARCH
为下标等于saller-NUMBER
的销售员编写报告
下一步:搜索语句。这就是一切变得奇怪的地方,它从不执行520-WRITE-FILE
。
这就是为什么
SEARCH
语句实现线性搜索(SEARCH ALL
是二进制搜索)<代码>搜索只是增加与搜索表相关联的索引,然后在测试时运行一组,直到其中一个“激发”或索引从表的末尾运行。TABLE-ENTRIES
表的索引是IND-TABLE-ENTRIES
。但您从未设置或引用它(这是问题的根源)。我马上解释
请注意,搜索的WHEN
部分使用下标例行检查<代码>例行检查
在500-PROCESS-FILE
中设置。还请注意,只有当销售员编号
与例行检查
的值匹配时,才可以访问520-WRITE-FILE
——如果从输入文件中读取了具有该编号的销售员,就会这样做。这可能会起作用,因为加载表时,行号等于450-table-LOAD
中的销售员编号
现在,如果输入文件不包含SM-NUMBER-IN
等于01的销售员,会发生什么情况
让我们一起经历,一个接一个
ROUTINE-CHECK
设置为1,调用SEARCH
,因为与搜索表关联的IND-TABLE-ENTRIES
索引小于表中发生的次数(在程序加载时初始化为零),所以执行
子句时的
当销售员编号(例行检查)=例行检查时,第一个测试是。由于销售员1不存在,saller-NUMBER
将为零,测试失败(01)
尝试下一个时的子句,它成功是因为(0=0);但这是一个“不做任何事情”选项,因此在IND-TABLE-ENTRI之后进入另一个搜索周期