使用GnuCOBOL Report Writer打印嵌套控制标题顺序异常求助
COBOL报表输出顺序异常问题
我尝试在COBOL程序的Report Section中生成报表,读取data.txt作为输入,输出到report.txt。实际输出的报表里分组标题(GROUP A)的顺序和预期不符,想知道问题出在哪。使用的GnuCOBOL版本是4.0-early-dev.0(GnuCOBOL 3.2会崩溃并打印"unexpected tree category")。
1. COBOL源代码
IDENTIFICATION DIVISION. PROGRAM-ID. PROGRAM. * ENVIRONMENT DIVISION. * INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT F-DATA ASSIGN TO 'data.txt' LINE SEQUENTIAL. SELECT F-REPORT ASSIGN TO 'report.txt' LINE SEQUENTIAL. * DATA DIVISION. * FILE SECTION. FD F-DATA. 01 R-DATA. 05 GRP PIC A(01). 05 NAME PIC X(04). 05 SCORE PIC 9(02). 05 FILLER PIC X(72). FD F-REPORT REPORT IS REP. WORKING-STORAGE SECTION. 77 FS-DATA PIC 9(02). 77 FS-REPORT PIC 9(02). 77 EOF PIC A(01). REPORT SECTION. RD REP PAGE LIMIT 10 CONTROLS ARE GRP NAME. 01 TYPE CH FOR GRP. 02 LINE +1. 03 COL 1 PIC A(05) VALUE 'GROUP'. 03 COL +2 PIC A(01) SOURCE GRP. 01 TYPE CH FOR NAME. 02 LINE +1. 03 COL 3 PIC X(16) SOURCE NAME. 01 DET TYPE DE. 02 LINE +1. 03 COL 5 PIC 9(02) SOURCE SCORE. 01 TYPE CF FOR NAME. 02 LINE +1. 03 COL 3 PIC A(05) VALUE 'TOTAL'. 03 COL +2 PIC X(04) SOURCE NAME. 03 COL +2 PIC X(01) VALUE '='. 03 COL +2 PIC 9(02) SUM OF SCORE. 01 TYPE CF FOR GRP. 02 LINE +1. 03 COL 1 PIC A(11) VALUE 'TOTAL GROUP'. 03 COL +2 PIC A(01) SOURCE GRP. 03 COL +2 PIC X(01) VALUE '='. 03 COL +2 PIC 9(02) SUM OF SCORE. * PROCEDURE DIVISION. * P-MAIN. MOVE 'N' TO EOF OPEN INPUT F-DATA OPEN OUTPUT F-REPORT INITIATE REP PERFORM P-READ PERFORM UNTIL EOF = 'Y' GENERATE DET PERFORM P-READ END-PERFORM TERMINATE REP CLOSE F-REPORT CLOSE F-DATA STOP RUN . P-READ. READ F-DATA AT END MOVE 'Y' TO EOF END-READ .
2. 输入文件data.txt内容
AJOHN01 AJOHN10 AJACK02 AJACK20
3. 编译执行命令
cobc -xj program.cob
4. 实际输出(report.txt)
JOHN GROUP A 01 10 TOTAL JOHN = 11 JACK 02 20 TOTAL JACK = 22 TOTAL GROUP A = 33
5. 预期输出
GROUP A JOHN 01 10 TOTAL JOHN = 11 JACK 02 20 TOTAL JACK = 22 TOTAL GROUP A = 33
问题原因与解决方法
问题出在首次GENERATE时的控制头触发顺序:
你定义的CONTROLS ARE GRP NAME中,GRP是外层控制项,NAME是内层,但直接GENERATE明细记录时,GnuCOBOL会优先触发内层控制头的初始化输出,导致NAME的标题先于GRP的标题打印。
解决步骤
修改Procedure Division的执行逻辑,在生成明细前显式触发外层和内层控制头的输出,确保顺序正确:
P-MAIN. MOVE 'N' TO EOF OPEN INPUT F-DATA OPEN OUTPUT F-REPORT INITIATE REP PERFORM P-READ PERFORM UNTIL EOF = 'Y' * 先触发组控制头(新组时自动输出) GENERATE CH FOR GRP * 再触发名称控制头(新名称时自动输出) GENERATE CH FOR NAME * 最后生成明细记录 GENERATE DET PERFORM P-READ END-PERFORM TERMINATE REP CLOSE F-REPORT CLOSE F-DATA STOP RUN .
修改后,系统会先检测并输出外层的GRP控制头,再处理内层的NAME控制头,最终输出顺序与预期一致。另外注意你的输入数据已经按GRP和NAME排序,这是Report Writer正常工作的前提,无需调整。
内容的提问来源于stack exchange,提问作者Zug
相关产品推荐
相关产品推荐

