1
votes

I have a COBOL program that reads records from UNIT=TAPE

The record length is variable length.

I try to read variable length records and get the record length into a variable but I get zero length.

My question is what's wrong with the code I wrote

This is my code:

 IDENTIFICATION DIVISION.                                    
   PROGRAM-ID. TDCBLALC.                                       
   ENVIRONMENT DIVISION.                                       
   INPUT-OUTPUT SECTION.                                       
   FILE-CONTROL.                                               
       SELECT KOVETZ-SPOOL ASSIGN TO OTFILE                    
         ORGANIZATION IS SEQUENTIAL                            
         ACCESS  MODE IS SEQUENTIAL                            
         FILE STATUS IS SW-END.                                
   DATA DIVISION.                                              
   FILE SECTION.                                               
   FD  KOVETZ-SPOOL                                            
       LABEL RECORD IS STANDARD                                
       RECORD IS VARYING IN SIZE FROM 1 TO 12600               
       DEPENDING ON ORECH-S                                    
       RECORDING MODE IS V.                                    
    01  RESHUMAT-SPOOL             PIC X(12600).               
   WORKING-STORAGE SECTION.                                    
    01  ORECH-S           PIC 9(8) COMP.                       
    01 I                  PIC S9(4) VALUE 0.                   
    01 SW-END PIC 99.                                          
    01 FN PIC X(44).                                           
    01 WS-ALLOC-STRING PIC X(100).                             
    01 PGM PIC X(08) VALUE 'BPXWDYN'.                          
   PROCEDURE DIVISION.                                         
       MOVE 'LYTO.SPOOL.PISD0735.T1401803.M001.D1191030' TO FN.
       STRING 'ALLOC DD(OTFILE) DSN(' DELIMITED BY SIZE          
              FN DELIMITED BY SPACE                              
              ') SHR REUSE '                                     
              ' UNIT(TAPE) '                                     
               DELIMITED BY SIZE                                 
        INTO WS-ALLOC-STRING                                     
       END-STRING.                                               
       DISPLAY ' WS-ALLOC-STRING *' WS-ALLOC-STRING '*'          
       CALL PGM USING WS-ALLOC-STRING.                           
       DISPLAY 'ALLOC RC='RETURN-CODE.                           
       OPEN INPUT KOVETZ-SPOOL                                   
       DISPLAY 'OPEN RC='RETURN-CODE.                            
       MOVE 00 TO SW-END                                         
       READ KOVETZ-SPOOL                                         
            AT END MOVE 1 TO SW-END                              
       END-READ                                                  
       DISPLAY 'READ RC='RETURN-CODE' SW-END='SW-END             

       PERFORM UNTIL SW-END = 1 OR I > 100                       
            ADD 1 TO I                                           
            DISPLAY 'ORECH-S=' ORECH-S                           
            DISPLAY 'RESHUMAT-SPOOL=' RESHUMAT-SPOOL(1:100)      
             READ KOVETZ-SPOOL                                   
               AT END MOVE 1 TO SW-END                           
             END-READ                                            
            DISPLAY 'READ RC='RETURN-CODE' SW-END='SW-END        
       END-PERFORM           

        CLOSE KOVETZ-SPOOL   

       GOBACK. 

The return code of alloc=0

The return code of open=0

The return code of read=0

File status(SW-END) after read is 47 (A READ or START operation has been tried on a file not opened INPUT or I-O)

I don't know why, I explicitly open the file for input

Anyway, the problem remained. The record length after the read is zero

ORECH-S=00000000

1
Is file status zero after the OPEN? Does the file contain actual data? - Simon Sobisch
Just a side note: as you already use the AT END clause you could adjust it to remove the sw-end flag completely - the first one would be READ KOVETZ-SPOOL NOT AT END PERFORM UNTIL... END-PERFORM END-READ and the second one READ KOVETZ-SPOOL AT END EXIT PERFORM END-READ. - Simon Sobisch
According to the COBOL programmers Guide regarding the RDW "These control fields in the buffer are not available for you to use in your program." - NicC
What is the return code from BPXWDYN? Are there any messages in the JESMSGLG DD of your job, or your TSO session if you're running this from the READY prompt? - cschneid
ALLOCATION RETURN CODE=-0024 AFTER READ :RETURN CODE=-0024 AND SW-END=47 - user3274100

1 Answers

1
votes

Simple typo - you forgot to declare the WORKING-STORAGE SECTION

   IDENTIFICATION DIVISION.                       
   PROGRAM-ID. TDCBLALC.                          
   ENVIRONMENT DIVISION.                          
   INPUT-OUTPUT SECTION.                          
   FILE-CONTROL.                                  
       SELECT KOVETZ-SPOOL 
              ASSIGN TO OTFILE       
              ORGANIZATION IS SEQUENTIAL               
              FILE STATUS IS SW-END.                   

   DATA DIVISION.                                 
   FILE SECTION.                                  
   FD  KOVETZ-SPOOL                               
       LABEL RECORD IS STANDARD                                     
       RECORD IS VARYING IN SIZE FROM 1 TO 32600  
       DEPENDING ON ORECH-S                       
       RECORDING MODE IS V.                       
   01  RESHUMAT-SPOOL             PIC X(32600).

   WORKING-STORAGE SECTION.
   01  ORECH-S           PIC 9(8) COMP.     
   01 I                  PIC S9(4) VALUE 0. 
   01 SW-END PIC X(02).                     
   01 FN PIC X(44).                         
   01 WS-ALLOC-STRING PIC X(100).           
   01 PGM PIC X(08) VALUE 'BPXWDYN'.        

   PROCEDURE DIVISION.        
       MOVE 'LYTO.SPOOL.PISD0735.T1401803.M001.D1191030' TO FN.
       STRING 'ALLOC DD(OTFILE) DSN(' FN ') SHR REUSE '        
              ' UNIT(TAPE) '                                   
                   DELIMITED BY SIZE                                       
         INTO WS-ALLOC-STRING                                   
       END-STRING.   
       DISPLAY ' WS-ALLOC-STRING *' WS-ALLOC-STRING '*'        
       CALL PGM USING WS-ALLOC-STRING.                         
       DISPLAY RETURN-CODE.                                    
       OPEN INPUT KOVETZ-SPOOL                                 
       READ KOVETZ-SPOOL                                       
           AT END MOVE 1 TO SW-END                            
       END-READ   

       PERFORM UNTIL SW-END = 1 OR I > 100                   
           ADD 1 TO I                                       
           DISPLAY 'ORECH-S=' ORECH-S                       
           DISPLAY 'RESHUMAT-SPOOL=' RESHUMAT-SPOOL(1:100)  
           READ KOVETZ-SPOOL                               
             AT END MOVE 1 TO SW-END                       
           END-READ                                        
       END-PERFORM                                           

       CLOSE KOVETZ-SPOOL                                   

       GOBACK.

I compiled and ran this using GnuCobol so the program is syntactically and logically correct. I did substitute a local file and commented out the call to BPXDYN since I'm running it on Linux and the file has a Z/OS naming convention.

The file allocation fails so the file open fails too but he never checked the file status. The read returns the '47' as the file was never successfully opened

The program did output this: ALLOC DD(OTFILE) DSN(LYTO.SPOOL.PISD0735.T1401803.M001.D1191030 ) SHR REUSE UNIT(TAPE)

You need quotes around the data set name or the system will try to prefix it with your TSO ID.