使用Report Writer报告重复最后一行

时间:2015-02-17 21:41:33

标签: cobol

我发现自己对输入文件进行排序,并使用控制中断来计算一些数据。我们在控制中断时需要标题,报表编写者每次都重复标题,我无法弄清楚我的生活。 break段落中的write语句被写入两次,但如果我使用DISPLAY则只显示一次。报告撰写人我在哪里错了?休息本身正在正确地计算数据(但可能非常糟糕)

    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.

一些报告输出:(在开头标题处,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

...

1 个答案:

答案 0 :(得分:3)

这里是Micro Focus的一些Report Writer文档的链接。它不是他们提供的唯一文档,但它是我扫描过的所有内容: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>一般参考> COBOL语言参考>第3部分。其他主题> Report Writer你会看到:

  

报告档案

     

报告文件是具有顺序组织的输出文件。一个   报告文件具有包含REPORT子句的文件描述条目。   报告文件的内容由写入的记录组成   在RWCS的控制下。

     

报告文件由文件控制条目命名,由a描述   包含REPORT子句的文件描述条目。报告文件是   由OPEN,GENERATE,INITIATE,SUPPRESS提及并访问,   终止,报告前使用,以及关闭声明。

虽然这并没有明确地说"不要使用你自己的WRITE声明,并希望它们能够正常工作。我认为很明显你不应该这样做。当你这样做时会发生什么没有定义,或者是"未定义的行为"。

您在休息之前获得重复的行,并且在休息之后,确切地说,报告编写者将检查它是否需要执行任何操作。虽然我对Micro Focus COBOL中的Report Writer的实现一无所知,但我确信你已经正确地确定了重复发生并且超出了你的控制范围。我认为以上引用证实了这一点,并且在Micro Focus的文档的其他部分中,这可能会更明确。

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

请记住,你的WRITE语句的某些似乎无效,因为这是一台计算机,你需要它们所有才能工作。

对您的计划的一些一般性评论:

在主标题中,您有一个没有VALUE子句的FILLER,这可能会在写入文件进行打印时导致问题。无论这五个字节是否显示在您的输出上,或者是否由于此处发布的格式,我都不知道。

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

你有这个:

COMPUTE total-salary = total-salary + salary

然而,这被认为更清楚:

ADD salary TO total-salary

您正在使用STRING。您应该知道,当填充接收字段或处理完所有发送字段时,发送字段的数据传输将停止。在后一种情况下,与MOVE语句的行为不同,自动空格填充。您需要在执行STRING之前将接收字段设置为初始值,否则当STRING的当前执行具有较少的实际数据时,您将保留先前执行STRING的数据。

STRING之后你会这样做:

MOVE 0 TO tally-counter

这意味着你的INSPECT,之前的几个语句,但是在使用了计数器的情况下,依赖于前一个值的计数器计数器,之后代码才能工作。这不是好习惯。在之前将计数器计数器设置为初始值。它在INSPECT中使用。

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


COBOL的报告写入功能非常强大。它允许您在COBOL程序的REPORT SECTION中定义复杂的报告,包括标题,列标题,详细信息行,控制中断总数等。在PROCEDURE DIVISION中,您只需要尽可能少的源数据(比如说)使用READ)然后生成报告,COBOL为您完成剩下的工作。

但是,您已经定义了一个非常简单的报告,并且正在尝试自己进行标题,总计等。我从来没有这样做过,也不知道它是否有效,或者它是否适用于你的编译器。

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

我们需要从评论中看到问题的优秀答案,并且除非篇幅过大,否则需要整个程序。

如果你的练习专门用于报告作者,那么我认为你需要定义一个更复杂的"报告,它将自动从定义中生成您想要的所有内容。

如果您不必使用报告编写器进行本练习,请不要使用它,只需自己进行详细信息行格式化,然后按照标题和总计的内容进行编写。


假设(后来证明是假的)您使用Report Writer来完成所需的一切,问题就是手动写入Report Writer正在使用的相同输出文件。

如果使用Report Writer的完整功能,只需进行此更改并删除该输出文件的任何其他WRITE,并使用Report Writer功能:

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