Запись в последовательный набор данных в COBOL делает его недоступным для двоичного файла

#file #io #cobol #jcl

#файл #io #cobol #jcl

Вопрос:

Следующий код должен принимать последовательный набор данных в качестве входных данных через DDINPUT, описывающий банковские счета, и выводить последовательный набор данных через DDOUTPUT с именами владельцев банковских счетов с балансом более 8 500 000 долларов. Но, поскольку мы находимся в состоянии переполнения стека, этого не происходит.

        IDENTIFICATION DIVISION.
       PROGRAM-ID.    TOPACCTS.
      *
       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT INFILE ASSIGN TO DDINPUT
           ORGANIZATION IS SEQUENTIAL.
           SELECT OUTFILE ASSIGN TO DDOUTPUT
           ORGANIZATION IS SEQUENTIAL.
      *
       DATA DIVISION.
       FILE SECTION.
       FD  INFILE RECORD CONTAINS 80 CHARACTERS RECORDING MODE F.
       01  ACCT-FIELDS.
           05  LAST-NAME        PIC A(11).
           05  FIRST-NAME       PIC A(22).
           05  ACCT-NO-A        PIC 9(8).
           05  FILLER           PIC X(3) VALUE SPACES.
           05  ACCT-NO-B        PIC 9(8).
           05  FILLER           PIC X(9) VALUE SPACES.
           05  ACCT-BALANCE     PIC $,$$,$9.99.
      *
       FD  OUTFILE RECORD CONTAINS 80 CHARACTERS RECORDING MODE F.
       01  PRINT-ACC.
           05  LAST-NAME-O      PIC A(11) VALUE SPACES.
           05  FILLER           PIC X(2) VALUE SPACES.
           05  FIRST-NAME-O     PIC A(22) VALUE SPACES.
      *
       WORKING-STORAGE SECTION.
       01  WS-EOF   PIC A VALUE SPACE.
       01  RES      PIC 9(7)V99.
       01  WS-RECORD.
           05  WS-LAST-NAME        PIC A(11).
           05  WS-FIRST-NAME       PIC A(22).
           05  WS-ACCT-NO-A        PIC 9(8).
           05  WS-ACCT-NO-B        PIC 9(8).
           05  WS-ACCT-BALANCE     PIC $,$$,$9.99.

      *
       PROCEDURE DIVISION.
      *
           OPEN INPUT  INFILE.
           OPEN OUTPUT OUTFILE.
           PERFORM UNTIL WS-EOF = 'Y'
              READ INFILE INTO WS-RECORD
              AT END MOVE 'Y' TO WS-EOF
              NOT AT END PERFORM WRITE-RECORD
              END-READ
           END-PERFORM.
           CLOSE INFILE.
           CLOSE OUTFILE.
           STOP RUN.
      *
       WRITE-RECORD.
           COMPUTE RES = FUNCTION NUMVAL-C (ACCT-BALANCE).
           IF RES > 8500000
              DISPLAY "Adding " WS-FIRST-NAME " " WS-LAST-NAME "..."
              MOVE SPACES TO PRINT-ACC 
              MOVE WS-LAST-NAME    TO LAST-NAME-O
              MOVE WS-FIRST-NAME   TO FIRST-NAME-O
              DISPLAY "Writing " FIRST-NAME-O " " LAST-NAME-O "..."
              WRITE PRINT-ACC
              END-IF.

 

Код получает правильное имя владельцев с балансами, превышающими 8 500 000 долларов, но не записывается должным образом, поскольку при обращении к выходному набору данных VS Code выдает следующую ошибку:

не удается открыть файл:zowe_path. Подробно: Файл кажется двоичным и не может быть открыт как текст.

Я совсем новичок в COBOL и понятия не имею, что я делаю не так при записи в output. Возможно, проблема вызвана JCL:

 //TOPACJCL  JOB 1,NOTIFY=amp;SYSUID
//***************************************************/
//COBRUN  EXEC IGYWCL
//COBOL.SYSIN  DD DSN=amp;SYSUID..SOURCE(TOPACCTS),DISP=SHR
//LKED.SYSLMOD DD DSN=amp;SYSUID..LOAD(TOPACCTS),DISP=SHR
//***************************************************/
// IF RC = 0 THEN
//***************************************************/
//RUN     EXEC PGM=TOPACCTS
//STEPLIB   DD DSN=amp;SYSUID..LOAD,DISP=SHR
//DDINPUT   DD DSN=MY.DATA(INPUTD),DISP=SHR
//DDOUTPUT  DD DSN=MY.DATA(OUTPUTD),DISP=SHR
//SYSOUT    DD SYSOUT=*,OUTLIM=15000
//CEEDUMP   DD DUMMY
//SYSUDUMP  DD DUMMY
//***************************************************/
// ELSE
// ENDIF

 

Надеюсь, вы сможете мне помочь, поскольку я пытался исправить это в течение последних часов.
Заранее спасибо!

РЕДАКТИРОВАНИЕ # 1: добавлено «ПЕРЕМЕСТИТЬ ПРОБЕЛЫ В PRINT-ACC», по-прежнему не работает.

Ответ №1:

Попробуйте переместить пробелы в выходную запись перед ее обновлением

  WRITE-RECORD.
           COMPUTE RES = FUNCTION NUMVAL-C (ACCT-BALANCE).
           IF RES > 8500000
              DISPLAY "Adding " WS-FIRST-NAME " " WS-LAST-NAME "..."

              Move space           to PRINT-ACC

              MOVE WS-LAST-NAME    TO LAST-NAME-O
              MOVE WS-FIRST-NAME   TO FIRST-NAME-O
              DISPLAY "Writing " FIRST-NAME-O " " LAST-NAME-O "..."
              WRITE PRINT-ACC
              END-IF.
 

по сути, вы только обновляете LAST-NAME-O , а FIRST-NAME-O остальная часть записи будет шестнадцатеричной, следовательно, распознается как двоичная. Вы сможете редактировать файл на мэйнфрейме с ISPF edit помощью или File-Aid и т.д.

Комментарии:

1. Большое вам спасибо, ошибка закончилась тем, что мне пришлось добавить ЗАПОЛНИТЕЛЬ с 44 пробелами, поскольку я указывал длину записи равной 80 символам.

2. Из памяти value предложение игнорируется в File Section , так что это тоже было бы проблемой