#cobol #mainframe #jcl #gnucobol #cobol85
#cobol #мэйнфрейм #jcl #gnucobol #cobol85
Вопрос:
Это код cobol
*-----------------------
IDENTIFICATION DIVISION.
*-----------------------
PROGRAM-ID. TOPACCTS
AUTHOR. Otto B. Boolean.
*--------------------
ENVIRONMENT DIVISION.
*--------------------
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT PRINT-LINE ASSIGN TO PRTLINE.
SELECT CUST-RECS ASSIGN TO CUSTRECS.
*-------------
DATA DIVISION.
*-------------
FILE SECTION.
FD PRINT-LINE RECORDING MODE F.
01 PRINT-REC.
05 FILLER PIC X(02) VALUE SPACES.
05 LAST-NAME-O PIC X(25).
05 FILLER PIC X(02) VALUE SPACES.
05 ACCT-BALANCE-O PIC X(18).
05 FILLER PIC X(33) VALUE SPACES.
*
FD CUST-RECS RECORDING MODE F.
01 CUSTOMER-REC.
05 LAST-NAME PIC X(25).
05 FILLER PIC X(10) VALUE SPACES.
05 FIRST-NAME PIC X(15).
05 FILLER PIC X(10) VALUE SPACES.
05 ACCT-BALANCE PIC X(18).
05 FILLER PIC X(02) VALUE SPACES.
*
WORKING-STORAGE SECTION.
01 Filler.
05 LASTREC PIC X VALUE SPACE.
05 TOTL PIC 9(2) VALUE ZEROS.
05 SUB1 PIC 9(2) VALUE 01.
05 S PIC X(12) VALUE "8,500,000.00".
*
01 OVERLIMIT.
03 FILLER OCCURS 20 TIMES.
05 OL-ACCT-NO PIC X(8).
05 OL-ACCT-LIMIT PIC S9(7)V99 COMP-3.
05 OL-ACCT-BALANCE PIC S9(7)V99 COMP-3.
05 OL-LASTNAME PIC X(20).
05 OL-FIRSTNAME PIC X(15).
*
01 HEADER-1.
05 FILLER PIC X(20)
VALUE 'Financial Report for'.
05 FILLER PIC X(01) VALUE SPACES.
05 FILLER PIC X(14)
VALUE "Account holder".
05 FILLER PIC X(45) VALUE SPACES.
*
01 HEADER-2.
05 FILLER PIC X(05) VALUE 'Year '.
05 HDR-YR PIC 9(04).
05 FILLER PIC X(02) VALUE SPACES.
05 FILLER PIC X(06) VALUE 'Month '.
05 HDR-MO PIC X(02).
05 FILLER PIC X(02) VALUE SPACES.
05 FILLER PIC X(04) VALUE 'Day '.
05 HDR-DAY PIC X(02).
05 FILLER PIC X(56) VALUE SPACES.
*
01 HEADER-3.
05 FILLER PIC X(08) VALUE 'No.'.
05 FILLER PIC X(02) VALUE SPACES.
05 FILLER PIC X(10) VALUE 'Cust Name '.
05 FILLER PIC X(15) VALUE SPACES.
05 FILLER PIC X(08) VALUE 'Balance '.
05 FILLER PIC X(40) VALUE SPACES.
*
01 HEADER-4.
05 FILLER PIC X(08) VALUE '--------'.
05 FILLER PIC X(02) VALUE SPACES.
05 FILLER PIC X(10) VALUE '----------'.
05 FILLER PIC X(15) VALUE SPACES.
05 FILLER PIC X(10) VALUE '----------'.
05 FILLER PIC X(02) VALUE SPACES.
05 FILLER PIC X(13) VALUE '-------------'.
05 FILLER PIC X(40) VALUE SPACES.
*
01 WS-CURRENT-DATE-DATA.
05 WS-CURRENT-DATE.
10 WS-CURRENT-YEAR PIC 9(04).
10 WS-CURRENT-MONTH PIC 9(02).
10 WS-CURRENT-DAY PIC 9(02).
05 WS-CURRENT-TIME.
10 WS-CURRENT-HOURS PIC 9(02).
10 WS-CURRENT-MINUTE PIC 9(02).
10 WS-CURRENT-SECOND PIC 9(02).
10 WS-CURRENT-MILLISECONDS PIC 9(02).
*
*------------------
PROCEDURE DIVISION.
*------------------
OPEN-FILES.
OPEN INPUT CUST-RECS.
OPEN OUTPUT PRINT-LINE.
DISPLAY HEADER-1.
PERFORM WRITE-HEADERS.
DISPLAY 'PREPARED ON ' HDR-DAY '.' HDR-MO '.' HDR-YR.
DISPLAY '# OF RECORDS: ' TOTL.
DISPLAY '==========================================='.
PERFORM READ-NEXT-RECORD.
*
WRITE-HEADERS.
MOVE FUNCTION CURRENT-DATE TO WS-CURRENT-DATE-DATA.
MOVE WS-CURRENT-YEAR TO HDR-YR.
MOVE WS-CURRENT-MONTH TO HDR-MO.
MOVE WS-CURRENT-DAY TO HDR-DAY.
MOVE SPACES TO PRINT-REC.
WRITE PRINT-REC AFTER ADVANCING 1 LINES.
MOVE SPACES TO PRINT-REC.
*
*
READ-NEXT-RECORD.
PERFORM READ-RECORD
PERFORM UNTIL LASTREC = 'Y'
PERFORM THE-RICH
PERFORM WRITE-RECORD
PERFORM READ-RECORD
END-PERFORM.
EXIT.
*
*
READ-RECORD.
READ CUST-RECS
AT END MOVE 'Y' TO LASTREC
END-READ.
EXIT.
*
THE-RICH.
IF FUNCTION NUMVAL-C(S) < FUNCTION NUMVAL-C(ACCT-BALANCE)
THEN
DISPLAY LAST-NAME ACCT-BALANCE
MOVE ACCT-BALANCE TO ACCT-BALANCE-O
MOVE LAST-NAME TO LAST-NAME-O
ADD 1 TO SUB1
MOVE SUB1 TO TOTL
END-IF.
EXIT.
*
WRITE-RECORD.
MOVE ACCT-BALANCE TO ACCT-BALANCE-O.
MOVE LAST-NAME TO LAST-NAME-O.
* MOVE FIRST-NAME TO FIRST-NAME-O.
WRITE PRINT-REC.
EXIT.
*
это вывод SYSOUT
Financial Report for Account holder
PREPARED ON 24.09.2020
no OF RECORDS: 00
===========================================
Maggie Bignell 8,670,838.00
Saw Eckart 8,668,500.00
Dede Quickenden 8,667,260.00
Allison Oxshott 8,593,183.00
Ambrose Inch 8,557,403.00
Leann Lob 8,656,689.00
Nevile Roswarn 8,579,721.00
Hedda Littrell 8,598,965.00
KonstantineMerner 8,557,306.00
Heddie Atwel 8,674,813.00
Torie Gimenez 8,662,345.00
Lorraine Van Hault 8,500,390.00
Javier Coltan 8,534,879.00
Kissee Kidston 8,650,707.00
Benedikta Spitell 8,589,633.00
Niles Garnson 8,649,886.00
Alair Sturrock 8,576,908.00
Tandy Pilgram 8,626,022.00
Elfrida Bamlet 8,540,474.00
IGZ0020S A logic error occurred. Neither FILE STATUS nor a declarative was specified for file CUSTRECS in program
TOPACCTS at relative location X'414'. The status code was 46.
From compile unit TOPACCTS at entry point TOPACCTS at compile unit offset 00000414 at entry offset 00000414
at address 1B800414.
Ответ №1:
Если вы используете мэйнфреймовый компилятор COBOL, вы переходите к документации и выбираете свою версию. Затем вы выполняете поиск по «ключу состояния файла» и просматриваете, что означает состояние файла 46.
Для файла, открытого в режиме ввода или ввода-вывода, была предпринята попытка последовательного чтения, и не было установлено ни одной допустимой следующей записи, поскольку:
- Предыдущая инструкция READ была неудачной, но не вызвала условие завершения.
- Предыдущий оператор чтения вызвал условие завершения.
Обратите внимание, что в вашем OPEN-FILES
абзаце вы PERFORM READ-NEXT-RECORD
, а затем переходите к остальной части вашего кода после того, как уже достигли конца файла.
Вероятно, вам нужен STOP RUN
или GOBACK
в конце вашего первого абзаца.
Редактировать относительно количества записей печати: на самом деле нет хорошего способа отобразить количество записей в верхней части отчета, потому что вы не знаете количество записей, пока не прочитаете весь входной файл, но вы печатаете строки отчета по ходу. Большая часть контрольных значений времени, таких как количество записей, редактируется DISPLAY
(что по умолчанию передается в DD SYSOUT), а отчеты отправляются в другой DD, определенный в FILE-CONTROL
(через a WRITE
, точно так же, как то, что вы делаете).
Второе редактирование, касающееся количества записей печати: как указывает @GilbertLeBlanc, вы можете сохранять свои выходные строки в таблице до тех пор, пока не прочитаете все записи во входном файле. В таблице должно быть достаточно места для обработки всех выходных записей, и для этого существует несколько различных способов.
- Ваша таблица может быть статически определена с достаточно большим
OCCURS
предложением для обработки того, что, как вам сказали, является разумным количеством записей. Раньше это было очень распространенным явлением, и был бы код для проверки, было ли превышено разумное число, и отменить, если это так. - В вашей таблице может по-разному встречаться
UNBOUNDED
фраза с учетом ее ограничений, а хранилище управляется сALLOCATE
помощью оператора иFREE
инструкции. - Вы могли бы выполнить собственное распределение и перераспределение с помощью вызываемых файлов CEEGTST, CEEFRST и CEECZST.
Гилберт также указывает, что вы можете прочитать файл дважды, один раз, чтобы получить количество записей, затем закрыть и снова открыть для выполнения обычной обработки. Это будет работать до тех пор, пока вы не делаете что-то сложное с вашим JCL, например…
//TOPACCTS EXEC PGM=TOPACCTS
//SYSOUT DD SYSOUT=*
//CUSTRECS DD DISP=SHR,DSN=MY.INPUT.FILE01
//CUSTRECS DD DISP=SHR,DSN=MY.INPUT.FILE02
//CUSTRECS DD DISP=SHR,DSN=MY.INPUT.FILE03
//PRTLINE DD SYSOUT=*
//PRTLINE DD SYSOUT=*
//PRTLINE DD SYSOUT=*
… где каждый раз, когда вы закрываете и открываете CUST-RECS и PRINT-LINE, вы получаете следующий DD. Но это более сложная тема JCL, с которой вы, возможно, не очень часто сталкиваетесь на практике.
Комментарии:
1.
STOP RUN
работал с C0000. Я не подумал об этом, спасибо.2. Теперь я хочу напечатать количество записей в SYSOUT поверх выходных данных, но, похоже, я могу распечатать его только после
READ-NEXT-RECORD
запуска. Есть какой-нибудь умный способ сделать это?3. @Fnechz: вы можете либо сохранить все выходные данные в алфавитно-цифровой форме, пока все входные записи не будут прочитаны, затем записать выходные строки, либо вы можете прочитать входной файл дважды, то есть открыть файл, прочитать файл, закрыть файл, снова открыть файл, прочитать файлснова и снова закрываем файл.