You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 04:45:03