Странная ошибка (COBOL) - PullRequest
       7

Странная ошибка (COBOL)

7 голосов
/ 07 февраля 2011

Привет всем, есть одна гора проблем здесь. Я выполнил программу, которую должен был сделать для домашней работы колледжа, но когда я запускаю ее, вывод почти ничего не показывает. Это происходит только тогда, когда я запускаю это все же. Если я держу F11, чтобы пройти через все это, он показывает результаты, как это должно быть. Обычно я не спрашивал бы о чем-то таком большом, но я в тупике. Вот мой код:

   ENVIRONMENT DIVISION.
   INPUT-OUTPUT SECTION.
   FILE-CONTROL.

       SELECT SALESAMT-FILE-IN
           ASSIGN TO 'SALESAMT.SEQ'
           ORGANIZATION IS LINE SEQUENTIAL.

       SELECT SALESMAN-FILE-IN
           ASSIGN TO 'SALESMAN.SEQ'
           ORGANIZATION IS LINE SEQUENTIAL.

       SELECT SALESQTR-FILE-IN
           ASSIGN TO 'SALESQTR.SEQ'
           ORGANIZATION IS LINE SEQUENTIAL.

       SELECT SALESAMT-FILE-OUT
           ASSIGN TO 'SALESAMT.RPT'
           ORGANIZATION IS LINE SEQUENTIAL.

   DATA DIVISION.
   FILE SECTION.

   FD  SALESMAN-FILE-IN.
   01  SALESMAN-RECORD-IN.
       05  SM-NUMBER-IN                    PIC 99.
       05  SM-NAME-IN                      PIC X(20).

   FD  SALESQTR-FILE-IN.
   01  SALESQTR-RECORD-IN.
       05  QUARTER-YEAR                    PIC X.

   FD  SALESAMT-FILE-IN.
   01  SALESAMT-RECORD-IN.
       05  SM-NUMBER                       PIC 99.
       05                                  PIC X.
       05  MONTH-NUMBER                    PIC 9.
       05                                  PIC X.
       05  SALES-AMOUNT                    PIC 9(5).

   FD  SALESAMT-FILE-OUT.
   01  SALESAMT-RECORD-OUT                 PIC X(80).

   WORKING-STORAGE SECTION.
   01  ARE-THERE-MORE-RECORDS              PIC X(3)  VALUE 'YES'.

   01  REPORT-START                        PIC X     VALUE 'Y'.

   01  LINE-COUNT                          PIC 99    VALUE ZEROS.

   01  LINE-JUMP                           PIC X     VALUE 'Y'.

   01  PAGE-NUMBER                         PIC 99    VALUE ZEROS.

   01  QUARTER-CHECK                       PIC X.

   01  ROUTINE-CHECK                       PIC 99    VALUE ZEROS.

   01  SALESMAN-MATH                       PIC 9(5)  VALUE ZEROS.

   01  SALESMAN-TOTAL                      PIC 9(6)  VALUE ZEROS.

   01  FINAL-M-TOTAL-1                     PIC 9(7)  VALUE ZEROS.

   01  FINAL-M-TOTAL-3                     PIC 9(7)  VALUE ZEROS.

   01  FINAL-M-TOTAL-2                     PIC 9(7)  VALUE ZEROS.

   01  FINAL-TOTAL                         PIC 9(7)  VALUE ZEROS.

   01  SM-NUM-M                           PIC 99    VALUE ZEROS.

   01  MORE-TABLE-RECS                     PIC X     VALUE 'Y'.

   01  SPACE-LINE                          PIC X     VALUE SPACE.

   01  MONTH-NAMES
           VALUE 'JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC'.
       05  MONTH-TITLES OCCURS 12 TIMES    PIC X(3).

   01  MONTH-ARRAY.
       05  THREE-MONTHS OCCURS 3 TIMES.
           10 MONTH-TOTAL OCCURS 99 TIMES  PIC 9(7)  VALUE ZEROS.

   01  SALESMAN-TABLE.
       05  TABLE-ENTRIES OCCURS 99 TIMES
               INDEXED BY IND-TABLE-ENTRIES.
           10 SALESMAN-NUMBER              PIC 99    VALUE ZEROS.
           10 SALESMAN-NAME                PIC X(20) VALUE SPACES.
   01  SALESMAN-COUNT                      PIC 9(3)  VALUE ZEROS.

   01  WS-DATE.
       05  RUN-YEAR                        PIC XX.
       05  RUN-MONTH                       PIC XX.
       05  RUN-DAY                         PIC XX.

   01  HEADING-LINE-1.
       05                                  PIC X(17) VALUE SPACES.
       05                                  PIC X(35)
           VALUE 'SALES AMOUNTS BY SALESMAN AND MONTH'.
       05                                  PIC X(10)  VALUE SPACES.
       05  HL-1-DATE.
           10  MONTH-2                     PIC XX.
           10                              PIC X      VALUE '/'.
           10  DAY-2                       PIC XX.
           10                              PIC X      VALUE '/'.
           10  YEAR-2                      PIC XX.
       05                                  PIC X(3)   VALUE SPACES.
       05  PAGE-1                          PIC X(4)   VALUE 'PAGE'.
       05                                  PIC X(1)   VALUE SPACES.
       05  NUMBER-PAGE                     PIC Z9.

   01  HEADING-LINE-2.
       05  HL-NUM                          PIC X(3)   VALUE 'NUM'.
       05  HL-BLANK-A                      PIC XX     VALUE SPACES.
       05  HL-NAME                         PIC X(4)   VALUE 'NAME'.
       05  HL-BLANK-B                      PIC X(20)  VALUE SPACES.
       05  HL-MONTH-1                      PIC X(3)   VALUE SPACES.
       05  HL-BLANK-C                      PIC X(8)   VALUE SPACES.
       05  HL-MONTH-2                      PIC X(3)   VALUE SPACES.
       05  HL-BLANK-D                      PIC X(8)   VALUE SPACES.
       05  HL-MONTH-3                      PIC X(3)   VALUE SPACES.
       05  HL-BLANK-E                      PIC X(10)  VALUE SPACES.
       05  HL-TOTAL                        PIC X(5)   VALUE 'TOTAL'.

   01  DETAIL-LINE.
       05  DL-BLANK-A                      PIC X      VALUE SPACES.
       05  DL-NUM-COLUMN                   PIC 99.
       05  DL-BLANK-B                      PIC XX     VALUE SPACES.
       05  DL-NAME-COLUMN                  PIC X(17).
       05  DL-BLANK-C                      PIC X(4)   VALUE SPACES.
       05  DL-MONTH-1                      PIC ZZ,Z(3).
       05  DL-BLANK-D                      PIC X(5)   VALUE SPACES.
       05  DL-MONTH-2                      PIC ZZ,Z(3).
       05  DL-BLANK-E                      PIC X(5)   VALUE SPACES.
       05  DL-MONTH-3                      PIC ZZ,Z(3).
       05  DL-BLANK-F                      PIC X(8)   VALUE SPACES.
       05  DL-TOTAL                        PIC Z(3),Z(3).

   01 TOTALS-LINE.
       05  TL-WORDS                        PIC X(12)
           VALUE 'Final Totals'.
       05  TL-BLANK-A                      PIC X(12)   VALUE SPACES.
       05  MONTH-1-TOTAL                   PIC Z,Z(3),Z(3).
       05  TL-BLANK-A                      PIC X(2)   VALUE SPACES.
       05  MONTH-2-TOTAL                   PIC Z,Z(3),Z(3).
       05  TL-BLANK-A                      PIC X(2)   VALUE SPACES.
       05  MONTH-3-TOTAL                   PIC Z,Z(3),Z(3).
       05  TL-BLANK-A                      PIC X(5)   VALUE SPACES.
       05  MONTH-FINAL-TOTAL               PIC Z,Z(3),Z(3).

   PROCEDURE DIVISION.
   100-MAIN.
       OPEN INPUT SALESAMT-FILE-IN, SALESMAN-FILE-IN,
           SALESQTR-FILE-IN
       OPEN OUTPUT SALESAMT-FILE-OUT

       ACCEPT WS-DATE FROM DATE
       MOVE RUN-MONTH TO MONTH-2
       MOVE RUN-DAY TO DAY-2
       MOVE RUN-YEAR TO YEAR-2

       PERFORM 200-NEXT-PAGE

       PERFORM 300-SALES-ARRAY

       PERFORM 400-SALESMAN-NAME

       PERFORM 500-PROCESS-FILE

       PERFORM 600-FINAL-TOTALS

       CLOSE SALESAMT-FILE-IN, SALESMAN-FILE-IN, SALESQTR-FILE-IN
       CLOSE SALESAMT-FILE-OUT
       STOP RUN.

   200-NEXT-PAGE.
       ADD 1 TO PAGE-NUMBER
       MOVE PAGE-NUMBER TO NUMBER-PAGE
       MOVE HEADING-LINE-1 TO SALESAMT-RECORD-OUT
       IF REPORT-START = 'N'
           WRITE SALESAMT-RECORD-OUT
               AFTER ADVANCING PAGE
       ELSE
           MOVE 'N' TO REPORT-START
           WRITE SALESAMT-RECORD-OUT
               AFTER ADVANCING 1 LINE
           PERFORM 210-MONTH-CHECK
       END-IF.
       MOVE HEADING-LINE-2 TO SALESAMT-RECORD-OUT
       WRITE SALESAMT-RECORD-OUT
           AFTER ADVANCING 2 LINES
       MOVE ZEROS TO LINE-COUNT.

   210-MONTH-CHECK.
       READ SALESQTR-FILE-IN
           AT END
               CONTINUE
           NOT AT END
               PERFORM 220-MONTH-NAME
       END-READ.

   220-MONTH-NAME.
           EVALUATE QUARTER-YEAR
               WHEN = 1       MOVE MONTH-TITLES(1) TO HL-MONTH-1
                              MOVE MONTH-TITLES(2) TO HL-MONTH-2
                              MOVE MONTH-TITLES(3) TO HL-MONTH-3

               WHEN = 2       MOVE MONTH-TITLES(4) TO HL-MONTH-1
                              MOVE MONTH-TITLES(5) TO HL-MONTH-2
                              MOVE MONTH-TITLES(6) TO HL-MONTH-3

               WHEN = 3       MOVE MONTH-TITLES(7) TO HL-MONTH-1
                              MOVE MONTH-TITLES(8) TO HL-MONTH-2
                              MOVE MONTH-TITLES(9) TO HL-MONTH-3

               WHEN = 4       MOVE MONTH-TITLES(10) TO HL-MONTH-1
                              MOVE MONTH-TITLES(11) TO HL-MONTH-2
                              MOVE MONTH-TITLES(12) TO HL-MONTH-3
           END-EVALUATE.


   300-SALES-ARRAY.
       PERFORM UNTIL ARE-THERE-MORE-RECORDS = 'NO '
           READ SALESAMT-FILE-IN
               AT END
                   MOVE 'NO ' TO ARE-THERE-MORE-RECORDS
               NOT AT END
                   PERFORM 310-STORE-DATA
           END-READ
       END-PERFORM.

   310-STORE-DATA.
       MOVE SM-NUMBER TO SM-NUM-M
       EVALUATE MONTH-NUMBER
           WHEN 1                  PERFORM 320-FIRST-MONTH

           WHEN 2                  PERFORM 330-SECOND-MONTH

           WHEN 3                  PERFORM 340-THIRD-MONTH

       END-EVALUATE.

   320-FIRST-MONTH.
       ADD SALES-AMOUNT TO
           MONTH-TOTAL OF MONTH-ARRAY (1, SM-NUM-M).

   330-SECOND-MONTH.
       ADD SALES-AMOUNT TO
           MONTH-TOTAL OF MONTH-ARRAY (2, SM-NUM-M).

   340-THIRD-MONTH.
       ADD SALES-AMOUNT TO
           MONTH-TOTAL OF MONTH-ARRAY (3, SM-NUM-M).

   400-SALESMAN-NAME.
       PERFORM UNTIL MORE-TABLE-RECS = 'N'
           READ SALESMAN-FILE-IN
               AT END
                   MOVE 'N' TO MORE-TABLE-RECS
               NOT AT END
                   PERFORM 450-TABLE-LOAD
           END-READ
       END-PERFORM.

   450-TABLE-LOAD.
       MOVE SM-NUMBER-IN TO SALESMAN-COUNT
       MOVE SM-NUMBER-IN TO SALESMAN-NUMBER (SALESMAN-COUNT)
       MOVE SM-NAME-IN TO SALESMAN-NAME (SALESMAN-COUNT).

   500-PROCESS-FILE.
       PERFORM UNTIL ROUTINE-CHECK = 99
           ADD 1 TO ROUTINE-CHECK
           PERFORM 510-TABLE-SEARCH
       END-PERFORM.

   510-TABLE-SEARCH.
       SEARCH TABLE-ENTRIES
           WHEN SALESMAN-NUMBER (ROUTINE-CHECK) = ROUTINE-CHECK
               PERFORM 520-WRITE-FILE
           WHEN SALESMAN-NUMBER (ROUTINE-CHECK) = 0
               CONTINUE
       END-SEARCH.

   520-WRITE-FILE.
       MOVE SALESMAN-NAME (ROUTINE-CHECK) TO DL-NAME-COLUMN
       IF DL-NAME-COLUMN = SPACES
           MOVE '*** Not Found ***' TO DL-NAME-COLUMN
       END-IF
       MOVE ROUTINE-CHECK TO DL-NUM-COLUMN
       MOVE ROUTINE-CHECK TO SM-NUM-M
       MOVE MONTH-TOTAL (1, SM-NUM-M) TO DL-MONTH-1
       MOVE DL-MONTH-1 TO SALESMAN-MATH
       ADD SALESMAN-MATH TO SALESMAN-TOTAL
       ADD SALESMAN-MATH TO FINAL-M-TOTAL-1
       ADD SALESMAN-MATH TO FINAL-TOTAL
       MOVE MONTH-TOTAL (2, SM-NUM-M) TO DL-MONTH-2
       MOVE DL-MONTH-2 TO SALESMAN-MATH
       ADD SALESMAN-MATH TO SALESMAN-TOTAL
       ADD SALESMAN-MATH TO FINAL-M-TOTAL-2
       ADD SALESMAN-MATH TO FINAL-TOTAL
       MOVE MONTH-TOTAL (3, SM-NUM-M) TO DL-MONTH-3
       MOVE DL-MONTH-3 TO SALESMAN-MATH
       ADD SALESMAN-MATH TO SALESMAN-TOTAL
       ADD SALESMAN-MATH TO FINAL-M-TOTAL-3
       ADD SALESMAN-MATH TO FINAL-TOTAL
       IF SALESMAN-TOTAL > 0
           MOVE SALESMAN-TOTAL TO DL-TOTAL
           MOVE DETAIL-LINE TO SALESAMT-RECORD-OUT
           WRITE SALESAMT-RECORD-OUT
               AFTER ADVANCING 2 LINES
       END-IF
       MOVE ZEROS TO SALESMAN-TOTAL.

   600-FINAL-TOTALS.
       MOVE FINAL-M-TOTAL-1 TO MONTH-1-TOTAL
       MOVE FINAL-M-TOTAL-2 TO MONTH-2-TOTAL
       MOVE FINAL-M-TOTAL-3 TO MONTH-3-TOTAL
       MOVE FINAL-TOTAL TO MONTH-FINAL-TOTAL
       MOVE TOTALS-LINE TO SALESAMT-RECORD-OUT
       WRITE SALESAMT-RECORD-OUT
           AFTER ADVANCING 3 LINES.

Мне кажется, что логика верна, так как она работает, но по какой-то причине она (по моему мнению, когда я вижу результаты) полностью перепрыгивает через 520-WRITE-FILE при запуске. С этим я оставляю несколько заметок.

  1. Я знаю, что 510-TABLE-SEARCH не имеет смысла, и я собираюсь изменить его позже, но мне нужно сначала исправить это, и на данный момент это работает. Если это не главная проблема, пожалуйста, не беспокойте меня за это.

  2. Я буду готов добавить данные в файлы SEQ, если кто-нибудь спросит меня об этом.

  3. Мой код может быть немного сложным, и я признаю это, но я стараюсь изо всех сил, с моим учителем (я в основном должен изучить этот материал самостоятельно).

Я ценю любую помощь, которую я получаю, и благодарю всех, кто пытается помочь заранее.

edit: я использую компилятор под названием Micro Focus, Net Express 5.1 Academic Edition, и моя ОС - Windows Vista. Что касается того, что программа показывает, когда я ее запускаю, она просто показывает мои две строки заголовка и затем мою итоговую строку без чего-либо, кроме показа первого поля. Надеюсь, это поможет.

Ответы [ 5 ]

4 голосов
/ 08 февраля 2011

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

Первый: 400-SALESMAN-NAME читает записи продавцов изфайл в рабочую таблицу хранения SALESMAN-TABLE.

Файл, вероятно, выглядит примерно так:

01Sales Guy One   
02Lance Winslow   
03Scott Peterson   
04Willy Loman   

Когда цикл чтения завершится, SALESMAN-NUMBER будет равен индексу таблицы из-за способа загрузки таблицы (используя SM-NUMBER-INустановить нижний индекс таблицы).Пока проблем нет ...

Далее: 500-PROCESS-FILE перебирает все строки в SALESMAN-TABLE, выполняя индекс ROUTINE-CHECK от 1 до 99 и выполняя 510-TABLE-SEARCH, чтобы выписать отчет для продавцагде индекс равен SALESMAN-NUMBER ...

Далее: оператор SEARCH.Здесь все странно и никогда не выполняет 520-WRITE-FILE.Вот почему.

Оператор SEARCH реализует линейный поиск (SEARCH ALL - это двоичный поиск).SEARCH просто увеличивает индекс, связанный с искомой таблицей, и затем проходит серию WHEN тестов, пока один из них не «сработает» или индекс не выйдет за конец таблицы.Индекс для вашей таблицы TABLE-ENTRIES: IND-TABLE-ENTRIES.Но вы никогда не устанавливаете и не ссылаетесь на него (это корень проблемы).Я объясню через минуту ...

Обратите внимание, что WHEN часть вашего SEARCH использует индекс ROUTINE-CHECK.ROUTINE-CHECK было установлено в 500-PROCESS-FILE.Также обратите внимание, что вы получаете значение 520-WRITE-FILE, только если SALESMAN-NUMBER соответствует значению ROUTINE-CHECK - что будет, если продавец с таким номером был прочитан из входного файла.Это может работать, потому что вы загрузили таблицу так, что номер строки равен номеру продавца обратно в 450-TABLE-LOAD.

Теперь, что произойдет, если входной файл не содержит продавца, где SM-NUMBER-IN равно 01?

Позволяет пройти через это, удар за ударом ...

ROUTINE-CHECK установлен в 1, вызывается SEARCH, и потому что индекс IND-TABLE-ENTRIES, связанный с найденной таблицей, меньше чемчисло встречается в таблице (оно было инициализировано нулем при загрузке программы), выполняются предложения WHEN.

Первый тест - WHEN SALESMAN-NUMBER (ROUTINE-CHECK) = ROUTINE-CHECK.Поскольку продавец 1 не существует, SALESMAN-NUMBER будет равен нулю, и тест не пройден (0 <> 1).

Выполняется следующее предложение WHEN, и оно успешно выполнено, потому что (0 = 0);но это опция «ничего не делать», поэтому другой цикл ПОИСКА вводится после увеличения IND-TABLE-ENTRIES .

Те же результаты для этой и всех последующих итераций в списке SEARCH ed WHEN (ни одно из предложений не соответствует) ... Повторяйте этот цикл до тех пор, пока IND-TABLE-ENTRIES не будет увеличен за пределами таблицы.

В этот момент SEARCH завершается, и управление возвращается к следующему циклу в 500-PROCESS-FILE.Ничего не было напечатано.

500-PROCESS-FILE, затем увеличивает ROUTINE-CHECK на 1 (теперь это 2).У нас есть продавец с SALESMAN-NUMBER, равным 02, поэтому мы должны получить какой-то результат - верно?Неправильно!Но почему?

Если вы прочитаете глагол SEARCH, вы обнаружите, что он не сбрасывает индекс таблицы (в данном случае: IND-TABLE-ENTRIES).Он начинает использовать любое значение, которое имеет при вводе ПОИСКА.Вы никогда не сбрасываете его, поэтому оно уже установлено за пределами таблицы.ПОИСК просто завершается и ничего не печатается - когда-либо снова.

Устранение проблемы

Учитывая, что вы сначала загрузили TABLE-ENTRIES по номеру продавца, я не вижу цели использования ПОИСКА.Просто сделайте что-то вроде:

500-PROCESS-FILE.   
    PERFORM VARYING ROUTINE-CHECK FROM 1 BY 1  
              UNTIL ROUTINE-CHECK > 99   
        IF SALESMAN-NUMBER (ROUTINE-CHECK) = ZERO   
           CONTINUE   
        ELSE   
           PERFORM 520-WRITE-FILE   
        END-IF   
    END-PERFORM.    

Может также быть хорошей идеей иметь цикл инициализации для таблицы, чтобы каждый SALESMAN-NUMBER был явно установлен в ноль, прежде чем вы прочитаете файл продавца.1091 * Если вам необходимо использовать ПОИСК в этой программе, не забудьте установить и использовать связанную индексную переменную таблицы при обращении к поисковой таблице.

1 голос
/ 08 февраля 2011

Я добавил это как второй ответ, который я считаю правильным!

520-WRITE-FILE не выполняется, потому что ПОИСК вызвать его не удается.

В510-TABLE-SEARCH, я полагаю, вам нужно выполнить поиск по индексу, объявленному для таблицы IND-TABLE-ENTRIES.Вам, вероятно, потребуется повторно кодировать 500-PROCESS-FILE и 510-TABLE-SEARCH.

В другом вопросе вы задали вопрос о глаголе SEARCH.fmartin дал ссылку, описывающую, как это работает, с примерами.

0 голосов
/ 08 февраля 2011

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

В разделе среды вы объявляете дескрипторы файлов и присваиваете им имена файлов.

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

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

0 голосов
/ 07 февраля 2011

"это просто показывает мои две строки заголовка и затем мою итоговую строку"

В вашем пункте 520-WRITE-FILE у вас есть следующий код

IF SALESMAN-TOTAL > 0
           MOVE SALESMAN-TOTAL TO DL-TOTAL
           MOVE DETAIL-LINE TO SALESAMT-RECORD-OUT
           WRITE SALESAMT-RECORD-OUT
               AFTER ADVANCING 2 LINES
       END-IF

Если SALESMAN-TOTAL равен нулю, ваша программа не будет печатать подробные строки. Похоже, у вас есть данные или логическая ошибка в итоговой сумме SALESMAN-TOTAL.

0 голосов
/ 07 февраля 2011

Pls.Измените это:

   SELECT SALESAMT-FILE-OUT
       ASSIGN TO 'SALESAMT.RPT'
       ORGANIZATION IS LINE SEQUENTIAL
       File Status is FILESTATUS.

И добавьте это:

01 FILESTATUS.

 02 FILESTATUS-1                   Pic 9.
   88 SUCCESSFULL                  Value 0.
   88 END-OF-FILE                  Value 1.
   88 INVALID-KEY                  Value 2.
   88 PERMANENT-ERROR              Value 3, 9.
 02 FILESTATUS-2                   Pic 9.
   88 DUPLICATE-KEY                Value 2.
   88 NO-RECORD-FOUND              Value 3.
   88 FILE-IS-FULL                 Value 4.

Проверяйте FILESTATUS каждый раз, когда вы что-то делаете с SALESAMT-file-OUT.(Вы можете сделать с другими файлами, а также).С помощью этой модификации вы сможете увидеть, есть ли какая-либо ошибка, когда вы делаете IO.

Это первый шаг, так что это не окончательный ответ на вопрос.

...