我发现自己对输入文件进行排序,并使用控制中断来计算一些数据。我们在控制中断时需要标题,报表编写者每次都重复标题,我无法弄清楚我的生活。 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
...
答案 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
.