Wednesday, November 27, 2024

Wrapping lines when PC file uploaded to Mainframe

When trying to upload a notepad/CSV file that contains lines shorter than 80 characters to a mainframe file with LRECL of 80, the lines from the notepad or CSV file will be stored continuously in the mainframe file, with delimiter x'25', instead of individual records.

The below job can used to extract the individual lines from the uploaded file and store them as separate record in a output file

//COB    EXEC  PGM=IGYCRCTL                                      
//SYSPRINT DD  SYSOUT=*                                          
//SYSUT1   DD  UNIT=SYSDA,SPACE=(CYL,(1,1))                      
//SYSUT2   DD  UNIT=SYSDA,SPACE=(CYL,(1,1))                      
//SYSUT3   DD  UNIT=SYSDA,SPACE=(CYL,(1,1))                      
//SYSUT4   DD  UNIT=SYSDA,SPACE=(CYL,(1,1))                      
//SYSUT5   DD  UNIT=SYSDA,SPACE=(CYL,(1,1))                      
//SYSUT6   DD  UNIT=SYSDA,SPACE=(CYL,(1,1))                      
//SYSUT7   DD  UNIT=SYSDA,SPACE=(CYL,(1,1))                      
//SYSUT8   DD  UNIT=SYSDA,SPACE=(CYL,(1,1))                      
//SYSUT9   DD  UNIT=SYSDA,SPACE=(CYL,(1,1)) 
//SYSUT10  DD  UNIT=SYSDA,SPACE=(CYL,(1,1))       
//SYSUT11  DD  UNIT=SYSDA,SPACE=(CYL,(1,1))       
//SYSUT12  DD  UNIT=SYSDA,SPACE=(CYL,(1,1))       
//SYSUT13  DD  UNIT=SYSDA,SPACE=(CYL,(1,1))       
//SYSUT14  DD  UNIT=SYSDA,SPACE=(CYL,(1,1))       
//SYSUT15  DD  UNIT=SYSDA,SPACE=(CYL,(1,1))       
//SYSUT16  DD  UNIT=SYSDA,SPACE=(CYL,(1,1))       
//SYSUT17  DD  UNIT=SYSDA,SPACE=(CYL,(1,1))       
//SYSUT18  DD  UNIT=SYSDA,SPACE=(CYL,(1,1))       
//SYSUT19  DD  UNIT=SYSDA,SPACE=(CYL,(1,1))       
//SYSUT20  DD  UNIT=SYSDA,SPACE=(CYL,(1,1))                            
//SYSMDECK DD  UNIT=SYSDA,SPACE=(CYL,(1,1))                      
//SYSLIN   DD  DSN=&&LOADSET,UNIT=SYSDA,DISP=(MOD,PASS),         
//             SPACE=(TRK,(3,3)),DCB=BLKSIZE=800                 
//SYSIN    DD *                          
        IDENTIFICATION DIVISION.                                 
        PROGRAM-ID. HELLO.                                       
        ENVIRONMENT DIVISION.                                    
        CONFIGURATION SECTION.          
        SPECIAL-NAMES.                                       
        INPUT-OUTPUT SECTION.                                
        FILE-CONTROL.                                        
            SELECT INPUT-FILE        ASSIGN TO INFILE.       
            SELECT OUTPUT-FILE       ASSIGN TO OUTFILE.      
        DATA DIVISION.                                       
        FILE SECTION.                                        
        FD  INPUT-FILE.                                      
        01  INPUT-REC.                                       
            05 IN-CHAR  PIC X(01) OCCURS 80 TIMES.          
        FD  OUTPUT-FILE.                                     
        01  OUTPUT-REC   PIC X(80).                         
        WORKING-STORAGE SECTION.                             
        01 WS-REC.                                           
           05 WS-CHAR  PIC X(01) OCCURS 80 TIMES.           
        01 WS-IN       PIC S9(04) COMP.                      
        01 WS-OUT      PIC S9(04) COMP.                      
        01 WS-EOF PIC X(01) VALUE 'N'.                       
        PROCEDURE DIVISION.                                  
           OPEN INPUT  INPUT-FILE                            
                OUTPUT OUTPUT-FILE                                    
           MOVE SPACES  TO WS-REC                                     
           READ INPUT-FILE                                            
             AT END MOVE 'Y' TO WS-EOF                                
           END-READ                                                   
           PERFORM UNTIL WS-EOF = 'Y'                                 
             PERFORM VARYING WS-IN                                    
                FROM 1 BY 1 UNTIL WS-IN > 80                         
                EVALUATE TRUE                                         
                  WHEN IN-CHAR (WS-IN) = '"'                          
                       CONTINUE                                       
                  WHEN IN-CHAR (WS-IN) = X'25'                        
                       WRITE OUTPUT-REC FROM WS-REC                   
                       MOVE ZEROS   TO WS-OUT                         
                       MOVE SPACES  TO WS-REC                         
                  WHEN OTHER                                          
                       ADD 1        TO WS-OUT                         
                       MOVE IN-CHAR (WS-IN) TO WS-CHAR (WS-OUT)       
                END-EVALUATE                                          
             END-PERFORM                                              
             READ INPUT-FILE                                         
               AT END MOVE 'Y' TO WS-EOF                             
             END-READ                                                
           END-PERFORM                                               
           CLOSE INPUT-FILE                                          
                 OUTPUT-FILE                                         
           GOBACK.                                                   
//*                                                                  
//LKED   EXEC  PGM=IEWL,PARM='LIST,MAP',COND=(5,LT,COB)           
//SYSLIN   DD  DSN=&&LOADSET,DISP=(OLD,DELETE)                    
//         DD  DDNAME=SYSIN                                       
//SYSLMOD  DD  SPACE=(CYL,(5,5,5)),DISP=(,PASS),DSN=&&TEMP(GO),   
//         DSNTYPE=LIBRARY                                        
//SYSLIB   DD  DISP=SHR,DSN=CEE.SCEELKED                          
//SYSUT1   DD  UNIT=SYSDA,SPACE=(CYL,(1,1))                       
//SYSPRINT DD  SYSOUT=*                                           
//*                                                               
//GO     EXEC  PGM=*.LKED.SYSLMOD,COND=((5,LT,COB),(5,LT,LKED))   
//SYSOUT   DD  SYSOUT=*                                           
//INFILE   DD  DISP=SHR,DSN=PS file with uploaded text data                     
//OUTFILE  DD  DSN=output file       
//           LRECL=80,RECFM=FB,                                  
//          DISP=(,CATLG),SPACE=(CYL,(50,50),RLSE)

Friday, November 22, 2024

Finding non numeric data in the numeric fields using SORT

Suppose you think that some of the values in the Employees field might contain invalid numeric data, and you want to select the records with those values, if any. Each byte of the 4-byte Employees field should contain '0' through '9'; you would consider any other character, such as 'A' or '.' to be invalid. '1234' is a valid numeric value; it contains all numerics. '12.3' is an invalid numeric value; it contains a non-numeric. You can use one of the numeric test capabilities of the INCLUDE statement to collect the records you want as follows:

  INCLUDE COND=(18,4,FS,NE,NUM)

If the value in the field (18,4,FS) is not equal (NE) to numerics (NUM), the record is included. The records in the output data set will be those in which the field has non-numerics (a character other than '0'-'9' appears somewhere in the field).

Use NUM to indicate a test for numerics or non-numerics.

Use EQ to test for numerics, or NE to test for non-numerics.

Use FS format for the field if you want to test for character numerics ('0'-'9' in every byte).

Use ZD format for the field if you want to test for zoned decimal numerics ('0'-'9' in all non-sign bytes; X'F0'-X'F9', X'D0'-X'D9' or X'C0'-X'C9' in the sign byte).

Use PD format for the field if you want to test for packed decimal numerics (0-9 for all digits; F, D or C for the sign).

Here's an INCLUDE statement that only includes records in which the Revenue field and Profit field have packed decimal numerics (that is, there are no invalid packed decimal values in these fields).

  INCLUDE COND=(22,6,PD,EQ,NUM,AND,28,6,PD,EQ,NUM)