Report Writer 复制最后一行的报告

Report with Report Writer duplicating last line

我发现自己正在对输入文件进行排序,并使用控制中断来计算一些数据。我们在控制中断中需要 headers,报告编写者每次都在复制 header,我一辈子都弄不明白。 break 段落中的 write 语句写了两次,但如果我使用 DISPLAY 它只显示一次。 Report Writer 哪里出错了?中断本身正在正确计算数据(但可能非常糟糕)

    environment division.
    configuration section.
    input-output section.
    file-control.
        SELECT corpranks
            ASSIGN TO                                                
                "corpranks.txt" 
            ORGANIZATION IS LINE SEQUENTIAL.
        SELECT out-file 
            ASSIGN TO                                                  
                "report"
            ORGANIZATION IS LINE SEQUENTIAL.
        SELECT sortfile
            ASSIGN TO
                "SortFile".

    data division.

    file section.

      FD corpranks

        RECORD CONTAINS 80 CHARACTERS. 

          01 gf-rec.
            05 first-initial PIC x.
            05 middle-initial PIC x.
            05 last-name PIC x(14).
            05 rank-code PIC 9.
            05 Filler PIC x(15).
            05 rank PIC x(3).
            05 salary PIC 9(6).
            05 corporation PIC x(29) VALUE SPACE.

        FD out-file
        REPORT IS corp-report.

        01 of-rec PIC x(80).

        SD sortfile.
        01 Sortrec.
            05 PIC x(16).  
            05 SR-rank PIC xxx.
            05 PIC x(22).
            05 SR-corporation PIC x(29).


    working-storage section.
        77 EOF PIC x VALUE "N".
        77 current-corp PIC x(29).
        77 total-salary PIC 9(6) VALUE 0.                           
        77 current-salary PIC 9(6).                                
        77 converted-month PIC x(3).
        77 concatenated-date PIC x(28).
        77 formatted-date PIC x(80) JUSTIFIED RIGHT.
        77 formatted-name PIC x(20).
        77 tally-counter PIC 9.
        77 inp-len PIC 9.

        01 current-date.
            05 YYYY PIC x(4).
            05 MM PIC x(2).
            05 DD PIC x(2).
        01 corporation-header.
          05 FILLER pic x(18) VALUE SPACES.
          05 FILLER pic x(13) VALUE "Corporation: ".
          05 ch-corp pic x(40).
        01 corporation-subheader.
            05 FILLER pic x(5) VALUE SPACES.
            05 FILLER pic x(4) VALUE "RANK".
            05 FILLER pic x(5) VALUE SPACES.
            05 FILLER pic x(4) VALUE "NAME".
            05 FILLER pic x(15) VALUE SPACES.
            05 FILLER pic x(6) VALUE "SALARY".                   
        77 csh-underline pic x(40) Value 
        "========================================".
        01 main-header.
         05 FILLER PIC x(5).                                         
         05 header-content PIC x(69) VALUE "Jacksonville Computer App
    "lications Support Personnel Salaries".

    report section.

    RD corp-report.
    01   REPORT-LINE

    TYPE DETAIL
    LINE PLUS 2.
        05  COLUMN 6      PIC x(3)  SOURCE  rank.
        05  COLUMN 12     PIC x(20)    SOURCE   formatted-name.
        05  COLUMN 37     PIC 9(6)     SOURCE   salary.


    procedure division.
    0000-MAIN.

        Sort Sortfile on ascending key SR-corporation 
                      on ascending key SR-rank
                  Using corpranks 
                      giving corpranks.
        OPEN    
            INPUT corpranks
            OUTPUT out-file
        INITIATE corp-report.

       WRITE of-rec FROM main-header.
       ACCEPT current-date from DATE YYYYMMDD.
       PERFORM 3000-CONVERT-MONTH.
       STRING "As of: " DELIMITED BY SIZE
            DD DELIMITED BY SIZE
            SPACE
            converted-month DELIMITED BY SIZE
            SPACE
            YYYY DELIMITED BY SIZE
            INTO concatenated-date.

       MOVE concatenated-date TO formatted-date.

       WRITE of-rec FROM formatted-date.
       PERFORM 2000-GENERATE-REPORT UNTIL EOF = 1.
        TERMINATE corp-report.
        stop run.


    2000-GENERATE-REPORT.
            PERFORM 3100-TRIM-FIELDS
        GENERATE REPORT-LINE
        READ corpranks

            AT END
                CLOSE   corpranks
                        out-file
                MOVE 1 TO eof

            NOT AT END

                IF current-corp = SPACE
                    MOVE corporation to current-corp
                    MOVE current-corp to ch-corp
                    WRITE of-rec FROM corporation-header
                    WRITE of-rec FROM corporation-subheader
                    WRITE of-rec FROM csh-underline
                END-IF

                IF current-corp NOT = corporation
                    PERFORM 2500-CONTROL-BREAK
                END-IF

                COMPUTE total-salary = total-salary + salary
         MOVE corporation to current-corp
         END-READ.


    2500-CONTROL-BREAK.
        WRITE of-rec FROM corporation
        MOVE 0 to total-salary
        .

    3000-CONVERT-MONTH.
        EVALUATE mm
            WHEN "01" MOVE "JAN" TO converted-month
            WHEN "02" MOVE "FEB" TO converted-month
            WHEN "03" MOVE "MAR" TO converted-month
            WHEN "04" MOVE "APR" TO converted-month
            WHEN "05" MOVE "MAY" TO converted-month
            WHEN "06" MOVE "JUN" TO converted-month
            WHEN "07" MOVE "JUL" TO converted-month
            WHEN "08" MOVE "AUG" TO converted-month
            WHEN "09" MOVE "SEP" TO converted-month
            WHEN "10" MOVE "OCT" TO converted-month
            WHEN "11" MOVE "NOV" TO converted-month
            WHEN "12" MOVE "DEC" TO converted-month
            WHEN OTHER MOVE mm to converted-month
        END-EVALUATE.

    3100-TRIM-FIELDS.
        INSPECT last-name TALLYING tally-counter FOR trailing
            spaces.

            COMPUTE inp-len = LENGTH OF last-name - tally-counter

            MOVE last-name(1: inp-len) to formatted-name

            STRING last-name(1: inp-len) DELIMITED BY SIZE
                SPACE
                first-initial DELIMITED BY SIZE
                INTO formatted-name
          MOVE 0 TO tally-counter


    end program Program2.

部分报表输出:(开头header,csh-underline是最后写的,===下划线显示两次。在公司控制中断时,下一个公司名称是最后写的东西,写了两次)

Jacksonville Computer Applications Support Personnel Salaries
                                                As of: 18 FEB 2015

Corporation: Alltel Information Services
RANK     NAME               SALARY
========================================
========================================

 EVP   COLUMBUS C               100000

 SVP   ADAMS S                  042500

 VP    REAGAN R                 081000

 VP    FRANKLIN B               080000

 A&P   FORD G                   060000

 A&P   HAYES R                  050000

 A&P   JACKSON A                057600

 A&P   TYLER J                  069000

 A&P   HARRISON B               052000

 A&P   TAFT W                   070500

 A&P   HOOVER H                 035000

 A&P   PIERCE F                 044000

American Express
American Express

 EVP   JOHNSON L                098000

 SVP   CLINTON W                086000

 VP    ROOSEVELT F              072000

 A&P   HARDING W                040000

.....

这是来自 Micro Focus 的一些 Report Writer 文档的 link。这不是他们提供的唯一文档,但这是我扫描过的所有文档:http://documentation.microfocus.com/help/index.jsp?topic=%2Fcom.microfocus.eclipse.infocenter.studee60win%2FGUID-48E4E734-F1A4-41C4-BA30-38993C8FE100.html

如果您在 Enterprise > Micro Focus Studio Enterprise Edition 6.0 > General Reference > COBOL Language Reference > Part 3. Additional Topics > Report Writer 下找到 Report File,您将看到:

Report File

A report file is an output file having sequential organization. A report file has a file description entry containing a REPORT clause. The content of a report file consists of records that are written under control of the RWCS.

A report file is named by a file control entry and is described by a file description entry containing a REPORT clause. A report file is referred to and accessed by the OPEN, GENERATE, INITIATE, SUPPRESS, TERMINATE, USE BEFORE REPORTING, and CLOSE statements.

虽然这并没有明确地说 "Don't use your own WRITE statements and hope that they will work" 我认为很明显你不应该。当你这样做时会发生什么没有定义,或者是 "undefined behaviour".

您在中断前和中断后收到重复的行,报告编写器将在何处检查是否有任何需要做的事情。尽管我对 Micro Focus COBOL 中 Report Writer 的实现一无所知,但我非常确定您已经正确地确定了重复发生并且超出了您的控制范围。我认为以上引用证实了这一点,并且在 Micro Focus 文档的其他部分中,这可能会更加明确。

您要么需要完全使用 Report Writer(如果任务是使用 Report Writer),要么根本不用它。你不能在同一个报告文件上混合使用自动和手动,这对我来说很有意义。

请记住,某些 WRITE 语句似乎有效并不重要,因为这是一台计算机,您需要它们全部 上班。

对您的程序的一些一般性评论:

在 main-header 中,您有一个没有 VALUE 子句的 FILLER,这在写入文件进行打印时可能会导致问题。这是否是这五个字节未显示在您的输出中的方式,还是由于此处发布的格式,我不知道。

同样在 main-header 中,您有一个很长的文字,继续到第二行。我看不到延续标记,这可能是在 Micro Focus COBOL 中如何完成的一个特征,但如果不继续文字,它总是会让事情变得更容易。一个接一个地定义两个较小的字段,较小的字面量合在一起构成了一个整体。

你有这个:

COMPUTE total-salary = total-salary + salary

然而,这被认为更清楚:

ADD salary TO total-salary

您正在使用STRING。您应该知道发送字段中的 data-transfer 在接收字段已填满或所有发送字段都已处理时停止。在后一种情况下,自动 space-padding 是 而不是 执行的,这与 MOVE 语句的行为不同。您需要在执行 STRING 之前 将接收字段设置为初始值 ,否则当当前执行的 STRING 实际数据较少时,您将保留上一次执行 STRING 的数据。

在 STRING 之后执行此操作:

MOVE 0 TO tally-counter

这意味着您的 INSPECT,之前的几个语句,但在使用 tally-counter 的地方,依赖于 tally-counter 的先前值才能使之后的代码正常工作。这不是好的做法。使 tally-counter 成为初始值 ,然后 它被用于 INSPECT。

如果您使用 Report Writer,您的 PROCEDURE DIVISION 代码将显着减少,因为报告元素的定义定义了自动处理。


COBOL的Report Write功能非常强大。它允许您在 COBOL 程序的 REPORT SECTION 中定义复杂的报告,包括标题、列标题、详细信息行、control-break 总计等。在 PROCEDURE DIVISION 中,您只需要制作 source-data 可用(比如阅读),然后生成报告,COBOL 会为您完成剩下的工作。

但是,您已经定义了一个非常简单的报表,并试图自己制作标题、总计等。我从来没有这样做过,不知道它是否一般有效,或者它是否适用于您的编译器。

从您的测试来看,这样做似乎有问题,并且可能错误地重复了您自己编写的行。您需要检查该特定行是否未在程序的其他地方输出。

我们需要从评论中看到对问题的突出回答,并且,除非它过大,否则你的整个程序。

如果您的练习专门用于使用报告编写器,那么我认为您需要定义更多 "complex" 报告,它将根据定义自动生成您想要的一切。

如果您不必为此练习使用 Report Writer,请不要使用它,只需自己进行 detail-line 格式化并像您已经为标题和总计所做的那样 WRITE 它。


假设(后来证明是错误的)您正在使用 Report Writer 来完成您需要的一切,那么问题可能出在手动写入 Report Writer 正在使用的同一输出文件中。

如果使用 Report Writer 的全部功能,只需进行此更改并删除对该输出文件的任何其他 WRITE,然后使用 te Report Writer 的所有功能:

2500-CONTROL-BREAK.
    MOVE 0 to total-salary
    .