Search code examples
sortingmainframejcldfsort

Writing characters after x amount of records using a JCL Sort


I have written a JCL SORT that will sort/reformat various fields and print them to a new output file as in the code below. I need to amend this code to simply print the number '9' at the beginning of every tenth(10th) record. I presume I need an 'IFTHEN' but I'm not sure if it can be used with 'OUTREC FIELDS'.

SORT FIELDS=COPY
  OUTREC FIELDS=(2:26,5,
                 7:38,8,
                 22:15,9,
                 46:C'AAA')

Solution

  • Firstly, don't use OUTREC FIELDS=. Or INREC FIELDS=. Or OUTFIL OUTREC=.

    FIELDS= is "overloaded". The same word means different things in different places.

    BUILD is the modern version of FIELDS= on INREC and OUTREC and of OUTREC on OUTFIL.

    Use INREC BUILD=, OUTREC BUILD=, OUTFIL BUILD=.

    BUILD is an "alias" of FIELDS/OUTREC in those contexts, so there is no difference to processing, no difference to the computer, just difference for the human.

    SORT FIELDS=COPY
    INREC BUILD=(02:
                  26,5,
                  38,8,
                 22:
                  15,9,
                 46:
                  C'AAA')
    

    Suggestion for human readability. SORT doesn't care, so write your code for humans. Note that I've removed the redundant 7:. Column seven is the next avaialable position, so you only confuse things by specifying it.

    Consider using SORT symbols even.

      SORT FIELDS=COPY 
      INREC IFTHEN=(WHEN=INIT, 
                     BUILD=(SEQNUM, 
                             1, 
                             ZD, 
                             START=0, 
                            26,5, 
                            38,8, 
                            22: 
                             15,9, 
                            46: 
                             C'AAA')), 
              IFTHEN=(WHEN=(1,1,CH,NE,C'9'),
                       OVERLAY=(1:X)) 
    

    The trick to what you want is to use a sequence number. The above code includes a one-byte sequence number in each output record, as a Zoned Decimal. A "character" number. The default start for a sequence number is one, but for your case you want to start from zero, which is easy with START=. It does not matter that the 11th sequence number and onwards get truncated (leaving the low-order value) because that is exactly what you want.

    Almost. After formatting your record, you test the sequence number. If it is not "9", you use OVERLAY to change just that first byte to a blank (the X in the code).

    IFTHEN=(WHEN=INIT is done for each record, unconditionally, and you can have lots of them if needed. The are processed in sequence.

    IFTHEN=(WHEN=(logicalexpression must come after any WHEN=INIT, and they operate like a case/select-style statement (or a COBOL EVALUATE). Once an IFTHEN=(WHEN=(logicalepxression is true, processing for IFTHEN ceases for the current record - unless HIT=NEXT is specified.