Search code examples
mainframejclsyncsort

Mainframes JCL Record transposing using SORT


I want to do following transposing of records into column using SORT (snycsort or DFSORT). It should be scalable to any number of records .Is this possible ?

DE001XYX   A 
CD100000 B
CD200000 C
DE001KKK A
CD100000 B
DE003ZZZ A
DE001XYX A
CD100000 B
CD200000 C
DE001KKK A
CD100000 B
........

Transpose

DE001XYX   CD100000   CD200000   
DE001KKK   CD100000   
DE003ZZZ   
DE001XYX   CD100000   CD200000   
DE001KKK   CD100000   
.....

Solution

  • This is one question which I Favorited and longed to solve it myself for quite some time. After some research & try outs, I've just come up with a solution.


    UPDATE: Improvised approach is given below. It solves the problem in 1 pass itself whereas the initial approach took 3 passes.

    Improvised approach: No need of 3 passes.

    ***************************** Top of Data ******************************
    //JOBNAME JOB ('ACCOUNT INFORMATION'),'TRANSPOSE',                      
    //     CLASS=2,MSGCLASS=H,NOTIFY=&SYSUID                                
    //STEP1   EXEC PGM=SORT                                                 
    //SORTIN  DD *                                                          
    DE001XYX   A                                                            
    CD100000   B                                                            
    CD200000   C                                                            
    DE001KKK   A                                                            
    CD100000   B                                                            
    DE003ZZZ   A                                                            
    DE001XYX   A                                                            
    CD100000   B                                                            
    CD200000   C                                                            
    DE001KKK   A                                                            
    CD100000   B                                                            
    //SORTOUT DD SYSOUT=*                                                   
    //SYSOUT  DD SYSOUT=*                                                   
    //SYSIN   DD *                                                          
     SORT FIELDS=(30,1,CH,A)                                                
     INREC IFTHEN=(WHEN=GROUP,BEGIN=(12,1,CH,EQ,C'A'),                      
                  END=(12,1,CH,EQ,C'C'),PUSH=(14:ID=1)),                    
           IFTHEN=(WHEN=(12,1,CH,EQ,C'A'),BUILD=(1:1,8,19Z,28:12,1,         
                  30:14,1)),                                                
           IFTHEN=(WHEN=(12,1,CH,EQ,C'B'),                                  
                  BUILD=(1:9Z,10:1,8,18:10Z,28:12,1,30:14,1)),              
           IFTHEN=(WHEN=(12,1,CH,EQ,C'C'),                                  
                  BUILD=(1:18Z,19:1,8,28:12,1,30:14,1))                     
     SUM FIELDS=(1,8,10,8,19,8),FORMAT=BI                                   
     OUTREC FIELDS=(1:1,8,9:X,10:10,8,18:X,19:19,8)                         
    **************************** Bottom of Data ****************************
    

    Results in the same output which OP has shown in his/her question.


    Initial approach:

    Step 1: I used WHEN=GROUP with BEGIN, END and PUSH parameters.

    //JOBNAME JOB ('ACCOUNT NAME'),'TRANSPOSE',          
    //     CLASS=2,MSGCLASS=H,NOTIFY=&SYSUID             
    //STEP1   EXEC PGM=SORT                              
    //SORTIN  DD *                                       
    DE001XYX   A                                         
    CD100000   B                                         
    CD200000   C                                         
    DE001KKK   A                                         
    CD100000   B                                         
    DE003ZZZ   A                                         
    DE001XYX   A                                         
    CD100000   B                                         
    CD200000   C                                         
    DE001KKK   A                                         
    CD100000   B                                         
    //SORTOUT DD SYSOUT=*                                
    //SYSOUT  DD SYSOUT=*                                
    //SYSIN   DD *                                       
     SORT FIELDS=COPY                                    
     OUTREC IFTHEN=(WHEN=GROUP,BEGIN=(12,1,CH,EQ,C'A'),  
                   END=(12,1,CH,EQ,C'C'),PUSH=(14:ID=1))
    

    PUSH=(14:ID=1) means position 14 for 1 is an identifier that increments for each group. Each A indicates a new group regardless of whether the previous group was terminated with C. The identifier is +1'd when a new group is started.

    Note: Since we are only allowing one character for the ID, when the ID counter gets to 10, a '0' will appear in position 14. You may also assign more than 1 byte for the ID.

    Output from the Step 1:

    ********************************* TOP OF DATA **********************************
    DE001XYX   A 1                                                                  
    CD100000   B 1                                                                  
    CD200000   C 1                                                                  
    DE001KKK   A 2                                                                  
    CD100000   B 2                                                                  
    DE003ZZZ   A 3                                                                  
    DE001XYX   A 4                                                                  
    CD100000   B 4                                                                  
    CD200000   C 4                                                                  
    DE001KKK   A 5                                                                  
    CD100000   B 5                                                                  
    ******************************** BOTTOM OF DATA ********************************
    

    Step 2: Take the output from Step 1. Modify the position of DE, CD1 and CD2 records based on the three keys A, B and C respectively.

    //JOBNAME JOB ('ACCOUNT NAME'),'TRANSPOSE',                     
    //     CLASS=2,MSGCLASS=H,NOTIFY=&SYSUID                        
    //STEP1   EXEC PGM=SORT                                         
    //SORTIN  DD *                                                  
    DE001XYX   A 1                                                  
    CD100000   B 1                                                  
    CD200000   C 1                                                  
    DE001KKK   A 2                                                  
    CD100000   B 2                                                  
    DE003ZZZ   A 3                                                  
    DE001XYX   A 4                                                  
    CD100000   B 4                                                  
    CD200000   C 4                                                  
    DE001KKK   A 5                                                  
    CD100000   B 5                                                  
    //SORTOUT DD SYSOUT=*                                           
    //SYSOUT  DD SYSOUT=*                                           
    //SYSIN   DD *                                                  
     SORT FIELDS=COPY                                               
     OUTREC IFTHEN=(WHEN=(12,1,CH,EQ,C'A'),BUILD=(1:1,8,19Z,28:12,1,
                   30:14,1)),                                       
            IFTHEN=(WHEN=(12,1,CH,EQ,C'B'),                         
                   BUILD=(1:9Z,10:1,8,18:10Z,28:12,1,30:14,1)),     
            IFTHEN=(WHEN=(12,1,CH,EQ,C'C'),                         
                   BUILD=(1:18Z,19:1,8,28:12,1,30:14,1))            
    /*      
    

    Note: Binary zeros are inserted in between, as place holders so that they can be filled in with data, in Step 3.

    Output from Step 2:

    ********************************* TOP OF DATA **********************************
    DE001XYX                   A 1                                                  
             CD100000          B 1                                                  
                      CD200000 C 1                                                  
    DE001KKK                   A 2                                                  
             CD100000          B 2                                                  
    DE003ZZZ                   A 3                                                  
    DE001XYX                   A 4                                                  
             CD100000          B 4                                                  
                      CD200000 C 4                                                  
    DE001KKK                   A 5                                                  
             CD100000          B 5                                                  
    ******************************** BOTTOM OF DATA ********************************
    

    With Hex mode ON, you will be able to see the binary zeros (X'00).

    ***************************** Top of Data ******************************
    DE001XYX                   A 1                                          
    CCFFFEEE0000000000000000000C4F444444444444444444444444444444444444444444
    450017870000000000000000000101000000000000000000000000000000000000000000
    ----------------------------------------------------------------------- 
             CD100000          B 1                                          
    000000000CCFFFFFF0000000000C4F444444444444444444444444444444444444444444
    000000000341000000000000000201000000000000000000000000000000000000000000
    ----------------------------------------------------------------------- 
                      CD200000 C 1                                          
    000000000000000000CCFFFFFF4C4F444444444444444444444444444444444444444444
    000000000000000000342000000301000000000000000000000000000000000000000000
    ----------------------------------------------------------------------- 
    DE001KKK                   A 2                                          
    CCFFFDDD0000000000000000000C4F444444444444444444444444444444444444444444
    450012220000000000000000000102000000000000000000000000000000000000000000
    ----------------------------------------------------------------------- 
             CD100000          B 2                                          
    000000000CCFFFFFF0000000000C4F444444444444444444444444444444444444444444
    000000000341000000000000000202000000000000000000000000000000000000000000
    ----------------------------------------------------------------------- 
    DE003ZZZ                   A 3                                          
    CCFFFEEE0000000000000000000C4F444444444444444444444444444444444444444444
    450039990000000000000000000103000000000000000000000000000000000000000000
    ----------------------------------------------------------------------- 
    DE001XYX                   A 4                                          
    CCFFFEEE0000000000000000000C4F444444444444444444444444444444444444444444
    450017870000000000000000000104000000000000000000000000000000000000000000
    ----------------------------------------------------------------------- 
             CD100000          B 4                                          
    000000000CCFFFFFF0000000000C4F444444444444444444444444444444444444444444
    000000000341000000000000000204000000000000000000000000000000000000000000
    ----------------------------------------------------------------------- 
                      CD200000 C 4                                          
    000000000000000000CCFFFFFF4C4F444444444444444444444444444444444444444444
    000000000000000000342000000304000000000000000000000000000000000000000000
    DE001KKK                   A 5                                          
    CCFFFDDD0000000000000000000C4F444444444444444444444444444444444444444444
    450012220000000000000000000105000000000000000000000000000000000000000000
    ----------------------------------------------------------------------- 
             CD100000          B 5                                          
    000000000CCFFFFFF0000000000C4F444444444444444444444444444444444444444444
    000000000341000000000000000205000000000000000000000000000000000000000000
    ----------------------------------------------------------------------- 
    **************************** Bottom of Data ****************************
    

    Step 3: With output from Step 2 as input, use SUM FIELDS to combine DE, CD1 and CD2 records of the group, with SORT FIELDS on the ID field in 30th Position.

    //JOBNAME JOB ('ACCOUNT NAME'),'TRANSPOSE',                     
    //     CLASS=2,MSGCLASS=H,NOTIFY=&SYSUID                        
    //STEP1   EXEC PGM=SORT                                         
    //SORTIN  DD *                                                  
    DE001XYX                   A 1                                                  
             CD100000          B 1                                                  
                      CD200000 C 1                                                  
    DE001KKK                   A 2                                                  
             CD100000          B 2                                                  
    DE003ZZZ                   A 3                                                  
    DE001XYX                   A 4                                                  
             CD100000          B 4                                                  
                      CD200000 C 4                                                  
    DE001KKK                   A 5                                                  
             CD100000          B 5                                                  
    //SORTOUT DD SYSOUT=*                                           
    //SYSOUT  DD SYSOUT=*                                           
    //SYSIN   DD *
      SORT FIELDS=(30,1,CH,A)                       
      SUM FIELDS=(1,8,10,8,19,8),FORMAT=BI          
      OUTREC FIELDS=(1:1,8,9:X,10:10,8,18:X,19:19,8)
    /* 
    

    With OUTREC FIELDS=(1:1,8,9:X,10:10,8,18:X,19:19,8), replace binary zeros in between DE, CD1 and CD2 fields with spaces.

    Output from Step 3: Here you go!

    ***************************** Top of Data ******************************
    DE001XYX CD100000 CD200000                                              
    DE001KKK CD100000                                                       
    DE003ZZZ                                                                
    DE001XYX CD100000 CD200000                                              
    DE001KKK CD100000                                                       
    **************************** Bottom of Data ****************************
    

    More details on SUM FIELDS with Binary zeros:

    Binary addition operates on two bit patterns. Let's consider the following records (Hex mode is ON as I would like to show how Binary addition is being performed on the Hex values).

    ****** ********
    000001 DE001XYX
           CCFFFEEE
           45001787
    ---------------
    000002         
           00000000
           00000000
    

    Hex value of the first byte, X'C4' is being added with the binary zeros in the 1st byte of 2nd record.

     C4
    +00
     --
     C4
    

    X'C4' denotes Letter 'D' in EBCDIC

    If we change the Binary zero in the first byte to Binary one (X'01'), results will vary.

     C4
    +01
     --
     C5
    

    X'C5' denotes Letter 'E' in EBCDIC.

    With Binary zeros we can perform SUM FIELDS on Alphanumeric data items (EBCDIC characters a-z, A-Z, 0-9) to group them onto one single record.