2015-02-17 2 views
0

Я нахожу, что сортирую входной файл и используя прерывание управления для вычисления некоторых данных. Нам нужны заголовки в контрольном перерыве, писатель отчетов дублирует заголовок каждый раз, и я не могу понять это для жизни меня. Оператор записи в абзаце break записывается дважды, но если я использую DISPLAY, он отображается только один раз. Где я ошибся с Report Writer? Распад сам правильно вычисляя данные (но, вероятно, ужасно)Отчет с 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. 

Некоторые вывод отчета: (в начале заголовка, CSH-Подчеркивание это последнее, что написано, то === подчеркивание отображается в два раза В корпорации. управления разрывами, следующая АМФ название это последнее, что написано, и написано дважды)

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

ОК, я думаю, что это нечто более фундаментальное. Report Writer может составлять весь ваш отчет, заголовки, заголовки столбцов, номера страниц, итоговые итоги, итоговые итоги. Тем не менее, вы сделали очень простой отчет только с подробной строкой, а остальное вы делаете сами с WRITE. У вас есть *, чтобы использовать Report Writer? Если да, то вы должны определить весь отчет и позволить ему делать все. Если нет, то удалите ОТЧЕТ и просто сделайте простой WRITE для ваших подробных строк. Сообщите нам об этих вопросах и информацию о компиляторе/ОС. –

+0

Некоторые примеры ввода и вывод, который вы получите, также будут полезны. –

ответ

3

Вот ссылка на какой-то Report Writer документации от Micro Focus. Это не единственная документация, которую они предоставляют, но это все, что я просканировал: 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 File

файл отчета представляет собой выходной файл, имеющий последовательную организацию. В файле отчета есть запись описания файла, содержащая предложение REPORT. Содержание файла отчета состоит из записей, которые написаны под управлением RWCS.

Файл отчета назван записью управления файлами и описан в записи описания файла , содержащей предложение REPORT. Файл отчета - , на который ссылаются и доступ к операциям OPEN, GENERATE, INITIATE, SUPPRESS, . ТЕРМИНАЦИЯ, ИСПОЛЬЗОВАНИЕ ДО ОТЧЕТОВ и ЗАКРЫТЬ.

Хотя это окончательно не говорит «Не используйте свои собственные заявления WRITE и надейтесь, что они будут работать». Я думаю, ясно, что вы не должны. Что происходит, когда вы это делаете, это не определено, или это «неопределенное поведение».

Вы получаете повторяющиеся строки перед перерывом, и после перерыва точно, где Report Writer будет проверять, есть ли что-то, что ему нужно сделать. Хотя я ничего не знаю о реализации Report Writer в Micro Focus COBOL, я вполне уверен, что вы правильно определили, что повторение происходит и находится вне вашего контроля. Я думаю, что приведенная выше цитата подтверждает это, и в других частях документации Micro Focus это можно сделать более явным.

Вам необходимо полностью использовать Report Writer (если задача заключается в использовании Report Writer) или вообще не использовать его. Кажется, вы не можете смешивать автоматическое и ручное в одном файле отчета, и это имеет смысл для меня.

Помните, что это не имеет значения, что некоторые ваших утверждений WRITE похоже на работу, потому что это компьютер, и вы должны их все работать.

Некоторые общие замечания по программе:

В главном-заголовке у вас есть FILLER без оговорки VALUE, которые могут вызвать проблемы при записи в файл для печати. Независимо от того, как эти пять байтов не отображаются на вашем выходе или из-за форматирования в проводке здесь, я не знаю.

Также в главном заголовке у вас есть длинный литерал, продолжающийся на второй строке. Я не могу видеть маркер продолжения, и это может быть особенностью того, как это делается в этом 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.

Если вы перейдете к Report Writer, ваш код PROCEDURE DIVISION будет значительно сокращен, так как определение элементов отчета определяет автоматическую обработку.


Функция записи сообщений COBOL очень эффективна. Это позволяет вам определить сложный отчет в разделе ОТЧЕТЫ программы COBOL с заголовками, заголовками столбцов, подробными строками, итогами контрольного прорыва и т. Д. В разделе ПРОЦЕДУРНОЕ ОТДЕЛЕНИЕ вам нужно всего лишь столько, сколько сделать доступными исходные данные (скажем, с READ), а затем GENERATE отчет, а COBOL сделает все остальное за вас.

Однако вы определили очень простой отчет и сами пытаетесь делать заголовки, итоги и т. Д. Я никогда не делал этого и не знаю, работает ли он вообще, или если он работает для вашего компилятора.

Из вашего тестирования кажется, что может возникнуть проблема с этим, и может быть, ошибочно, повторить строку, которую вы сами написали. Вам нужно проверить, что эта конкретная строка не выводится в другом месте вашей программы.

Нам нужно увидеть выдающиеся ответы на вопросы из комментариев и, если это не чрезмерный размер, всей вашей программы.

Если ваше упражнение специально предназначено для использования Report Writer, то я думаю, вам нужно определить более «сложный» отчет, который автоматически создаст из определения все, что вы хотите.

Если вам не нужно использовать Report Writer для этого упражнения, не используйте его, просто выполните форматирование подробной строки и НАПИШИТЕ его, как вы уже делаете для заголовков и итогов.


В предположении (позже опровергнут), что вы использовали Report Writer, чтобы сделать все, что нужно, то проблема была бы вручную писать на тот же выходной файл, что Report Writer использовал.

При использовании в полной мере особенности Report Writer, просто сделать это изменение и удалять любые другие Пишет в этом выходной файл, а также использовать функции Report Writer для всего:

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

Действующие очки, просто хотели быть прозрачными, будут лучше продумать это в следующий раз, когда я обращусь за помощью к сообществу, и выйду на голосование, когда смогу добавить решение после работы. – NoobException

+0

И для чего это стоит, я забочусь о понимании любого языка, с которым я работаю, разочарован в погоне за этой ошибкой в ​​течение нескольких часов подряд, и пусть это станет лучше меня. Извините, если я обидел вас и благодарю за вашу помощь. Ну, если я удалю запись записи из контрольного перерыва, то у меня нет вывода заголовка, в отличие от дубликата. После некоторого ворчания отчет, кажется, просто запишет последнее заявление о записи, которое я использую. – NoobException

+0

Итак, нам нужно будет увидеть полное определение отчета. Я предположил, что вы сообщаете отчету, чтобы писать на перерывах, так что ваш собственный WRITE был лишним, но производил идентичные строки. Когда вы вставляете DISPLAY, см. Только одно, потому что код Report Writer делает другой. Кажется, что-то немного глубже, чем это, однако, если это не исправить. Какой компилятор это и ОС? –