Попытка написать REXX для чтения ввода и создания задания для выполнения

Я пытаюсь создать программу REXX для создания задания с переданным в нем именем элемента. Изначально я настроил программу на получение имени элемента в качестве переданного параметра, однако, поскольку я запускаю REXX в процессоре Endevor, мне приходится вызывать REXX по-другому и я не могу передать параметр. Я настроил REXX для открытия файла, в который я поместил имя элемента. Затем я пытаюсь выделить файл, прочитать его и поместить запись (с именем элемента) в переменную. Я получаю «плохое арифметическое преобразование». Разве Parm.0 не имеет значение последней записи во входном файле (если у меня есть одна запись, то parm.0 будет равен 1)? Я новичок в REXX и не знаю, как настроить чтение файла. Любая помощь будет оценена по достоинству.

Вот программа:

/* REXX */                                                         
/*                                                                 
PARSE UPPER ARG ELEMENT                                            
*/                                                                 
TRACE !R                                                           
CALL GET_ELEMENT                                                   
QUOTE = "'"                                                        
QUEUE '//ENSETTV3 JOB ,TSDSMPR.27,                               ' 
QUEUE '//             CLASS=C,PRTY=1,                            ' 
QUEUE '//*            TYPRUN=HOLD,                               ' 
QUEUE '//             MSGLEVEL=1,                                ' 
QUEUE '//             MSGCLASS=P,                                ' 
QUEUE '//             NOTIFY=&SYSUID,                            ' 
QUEUE '//             REGION=4096K                               ' 
QUEUE '/*XEQ      N11                                            ' 
QUEUE '//DELETEIT EXEC PGM=IDCAMS                                ' 
QUEUE '//SYSPRINT DD  SYSOUT=*                                   ' 
QUEUE '//SYSIN    DD  *                                          ' 
QUEUE '  DEL-                                                    ' 
Q_LINE = 'SCM.XCST.T.XXXXX.LOADLIB('"ELEMENT"')-'                  
SAY Q_LINE                                                         
QUEUE Q_LINE                                                       
QUEUE '    PURGE                                                 ' 
QUEUE '  DEL-                                                    ' 
Q_LINE = 'SCM.XCST.T.XXXXX.LOADIMS('"ELEMENT"')-'                  
SAY Q_LINE                                                         
QUEUE Q_LINE                                                       
QUEUE '    PURGE                                                 '
QUEUE '/*                                                        '
QUEUE '//                                                        '
ADDRESS TSO "EXECIO" QUEUED() "DISKW OUTJCL (FINIS"               
EXIT(0)                                                           
                                                                  
GET_ELEMENT:                                                      
SAY 'GET_ELEMENT'                                                 
  DATASET_NAME = 'NDV.D000000.T000000.CONNCMD.FILE(ELEMENT)'      
   "ALLOC DD(PARMS) DA("DATASET_NAME") SHR REUS"                  
  'EXECIO * DISKR PARMS     (STEM PARM. FINIS'                    
    DO P = 1 TO PARM.0              /* !  P LOOP */               
      INTERPRET PARM.P                                          
      ELEMENT = PARM.P                                            
    END                                                           
RETURN 

                                                       

Вот что я получаю, когда запускаю программу REXX:

      6 *-* CALL GET_ELEMENT                                                    
     34 *-*  GET_ELEMENT:                                                       
     35 *-*  SAY 'GET_ELEMENT'                                                  
        >>>    "GET_ELEMENT"                                                    
 GET_ELEMENT                                                                    
     36 *-*  DATASET_NAME = 'NDV.D000000.T000000.CONNCMD.FILE(ELEMENT)'         
        >>>    "NDV.D000000.T000000.CONNCMD.FILE(ELEMENT)"                      
     37 *-*  "ALLOC DD(PARMS) DA("DATASET_NAME") SHR REUS"                      
        >>>    "ALLOC DD(PARMS) DA(NDV.D000000.T000000.CONNCMD.FILE(ELEMENT)) SH
 R REUS"                                                                        
     38 *-*  'EXECIO * DISKR PARMS     (STEM PARM. FINIS'                       
        >>>    "EXECIO * DISKR PARMS     (STEM PARM. FINIS"                     
     39 *-*  DO P = 1 TO PARM.0              /* !  P LOOP */                    
        >>>    "1"                                                              
        >>>    "PARM.0"                                                         
     39 +++   DO P = 1 TO PARM.0              /* !  P LOOP */                   
      6 +++ CALL GET_ELEMENT                                                    
 IRX0041I Error running VOSBDELT, line 39: Bad arithmetic conversion     

   
                                                                    

Отредактировано: я отказался от попыток заставить цикл Do работать и вместо этого просто попытался работать с первой строкой входного файла, который я переименовал в in_file.

Теперь у меня есть следующее:

GET_ELEMENT:                                                   
SAY 'GET_ELEMENT'                                              
  DATASET_NAME = 'NDV.D000000.T000000.CONNCMD.FILE(ELEMENT)'   
  "ALLOC DD(INFILE) DA('"DATASET_NAME"') SHR REUS"             
  "EXECIO * DISKR INFILE    (FINIS STEM IN_FILE."              
/*  DO P = 1 TO IN_FILE.0         */                           
/*    INTERPRET IN_FILE.P         */                           
/*    ELEMENT = IN_FILE.P         */                           
/*  END                           */                           
  P = 1                                                        
  ELEMENT = LEFT(IN_FILE.P,8)                                  
  INTERPRET ELEMENT                                            
  "FREE FI(INFILE)"                                            
RETURN                                                         

Вот что я получаю при выполнении:

     6 *-* CALL GET_ELEMENT                                                    
    34 *-*  GET_ELEMENT:                                                       
    35 *-*  SAY 'GET_ELEMENT'                                                  
       >>>    "GET_ELEMENT"                                                    
GET_ELEMENT                                                                    
    36 *-*  DATASET_NAME = 'NDV.D000000.T000000.CONNCMD.FILE(ELEMENT)'         
       >>>    "NDV.D000000.T000000.CONNCMD.FILE(ELEMENT)"                      
    37 *-*  "ALLOC DD(INFILE) DA('"DATASET_NAME"') SHR REUS"                   
       >>>    "ALLOC DD(INFILE) DA('NDV.D000000.T000000.CONNCMD.FILE(ELEMENT)')
 SHR REUS"                                                                     
    38 *-*  "EXECIO * DISKR INFILE    (FINIS STEM IN_FILE."                    
       >>>    "EXECIO * DISKR INFILE    (FINIS STEM IN_FILE."                  
    39 *-*  /*  DO P = 1 TO IN_FILE.0         */                               
    40 *-*  /*    INTERPRET IN_FILE.P         */                               
    41 *-*  /*    ELEMENT = IN_FILE.P         */                               
    42 *-*  /*  END                           */                               
    43 *-*  P = 1                                                              
       >>>    "1"                                                              
    44 *-*  ELEMENT = LEFT(IN_FILE.P,8)                                        
       >>>    "IN_FILE."                                                       
    45 *-*  INTERPRET ELEMENT                                                  
       >>>    "IN_FILE."                                                       
       *-*   IN_FILE.                                                          
       >>>     "IN_FILE."                                                      
    46 *-*  "FREE FI(INFILE)"                                                  
       >>>    "FREE FI(INFILE)"                                                
    47 *-*  RETURN                                                             

Вместо того, чтобы отображать имя элемента из строки 1 in_file, которое оказывается «zoscbl19», вместо этого отображается «in_file». Что я делаю не так?


Снова отредактировано: я изменил свою функцию на следующую. Я больше не сдаюсь. Я добавил in_file. = '', чтобы очистить значение и установить его в пробелы. Я также проверил код возврата после execio, и он равен нулю, поэтому чтение работает, но на самом деле оно все еще не возвращает значение строки 1 zoscbl19.

GET_ELEMENT:                                                 
SAY 'GET_ELEMENT'                                            
DATASET_NAME = 'NDV.D000000.T000000.CONNCMD.FILE(ELEMENT)'   
"ALLOC DD(INFILE) DA('"DATASET_NAME"') SHR REUS"             
IN_FILE. = ''                                                
"EXECIO * DISKR INFILE    (FINIS STEM IN_FILE."              
SAY RC                                                       
IF RC = 0 THEN                                               
  DO                                                         
    "FREE FI(INFILE)"                                        
    ELEMENT = LEFT(IN_FILE.1,8)                              
    SAY 'ELEMENT:' ELEMENT                                   
  END                                                        
ELSE                                                         
  SAY 'RETURN CODE IS ' RC                                   
RETURN                                                       

person Monica Collins    schedule 30.07.2020    source источник


Ответы (2)


Вы читаете файл в базовую переменную INFILE.

"EXECIO * DISKR INFILE    (FINIS STEM IN_FILE." 

Затем вы пытаетесь получить доступ к основной переменной IN_FILE.

ELEMENT = LEFT(IN_FILE.P,8)            

изменить на

ELEMENT = LEFT(INFILE.P,8)            

Другая проблема

Q_LINE = 'SCM.XCST.T.XXXXX.LOADLIB('"ELEMENT"')-'      

вероятно, неправильно, это должно быть либо

Q_LINE = 'SCM.XCST.T.XXXXX.LOADLIB('ELEMENT')-'   

или Q_LINE = 'SCM.XCST.T.XXXXX.LOADLIB(ЭЛЕМЕНТ)-'

по аналогии

Q_LINE = 'SCM.XCST.T.XXXXX.LOADIMS('"ELEMENT"')-'               
person Bruce Martin    schedule 30.07.2020
comment
Нет в отношении infile и in_file. INFILE — это читаемое DDNAME и in_file. это ствол, в который считываются данные. Что не так, так это то, что код возврата из EXECIO не проверяется, поэтому мы не знаем, правильно ли он вообще выполнился - это не так, поскольку не создан ствол. - person NicC; 31.07.2020
comment
Я изменил функцию, чтобы проверить код возврата, который возвращается как 0. Я также добавил in_file. = '' перед execio, чтобы очистить in_file. Я могу выполнить rexx, однако у него есть пробелы там, где должно быть значение элемента, то есть zoscbl19, поэтому чтение все еще не работает. - person Monica Collins; 31.07.2020
comment
Вы уверены, что набор данных (член), который вы просматриваете с помощью ISPF, совпадает с указанным в программе. На самом деле это выглядит так, как будто имя набора данных является временным - не так ли? Еще одна вещь, которую вы можете попробовать, это запустить exexc в пакетном режиме и использовать JCL для выделения набора данных (удалить/закомментировать код в exec). - person NicC; 01.08.2020
comment
Я пробовал «элемент = левый (infile.1,8)» и «элемент = левый (in_file.1,8)», и оба отображают «infile.1» и «in_file, 1», а не то, что на самом деле в записи . Это правильный набор данных, и в нем есть запись со значением. - person Monica Collins; 03.08.2020
comment
Вы уверены, что вышли из Endevor, а затем просматривали/просматривали этот набор данных (член)? Тот факт, что EXECIO дает RC=0 и нет данных, предполагает, что элемент пуст во время выполнения exec. Неправильное имя набора данных или имя члена приведет к ошибкам, но пустое имя не должно вызывать ошибку. В качестве дополнительной диагностики вы должны отобразить in_file.0 - person NicC; 04.08.2020

Я не следил за всеми правками вашего кода, поэтому я не уверен, что вы делаете неправильно, но для чтения члена из PDS в REXX это работает (я только что запустил его):

/* REXX */                                    
                                              
INPUT_FILE = 'JOCS065.STEVE.DATA(ELEMENT)'    
"ALLOC DD(INPUT) DS('"INPUT_FILE"') SHR"      
"EXECIO * DISKR INPUT (STEM input_fi. FINIS)" 
                                              
do i = 1 to input_fi.0                        
  say input_fi.i                              
  end                                         
                                              
"FREE DD(INPUT)"                              
                                              
exit  

STEVE.DATA — это довольно обычный PDS — LRECL 80, RECFM FB — с элементом «ELEMENT», содержащим одну строку:

VIEW       JOCS065.STEVE.DATA(ELEMENT) - 01.00                     Columns 00001 00080 
Command ===>                                                          Scroll ===> CSR  
****** ********************************* Top of Data **********************************
000001 MEMBER1                                                                         
****** ******************************** Bottom of Data ********************************

При выполнении он просто печатает:

MEMBER1    
 

Редактировать:

Я только что запустил ваш последний код, подставив свой собственный входной файл:

/* РЕКС */

GET_ELEMENT:                                     
SAY 'GET_ELEMENT'                                
DATASET_NAME = 'JOCS065.STEVE.DATA(ELEMENT)'     
"ALLOC DD(INFILE) DA('"DATASET_NAME"') SHR REUS" 
IN_FILE. = ''                                    
"EXECIO * DISKR INFILE    (FINIS STEM IN_FILE."  
SAY RC                                           
IF RC = 0 THEN                                   
  DO                                             
    "FREE FI(INFILE)"                            
    ELEMENT = LEFT(IN_FILE.1,8)                  
    SAY 'ELEMENT:' ELEMENT                       
  END                                            
ELSE                                             
  SAY 'RETURN CODE IS ' RC                       
RETURN       

и я получаю:

GET_ELEMENT     
0               
ELEMENT: MEMBER1

которые являются данными в (ЭЛЕМЕНТ).

person Steve Ives    schedule 04.08.2020