IBM Mainframe Forum Index
 
Log In
 
IBM Mainframe Forum Index Mainframe: Search IBM Mainframe Forum: FAQ Register
 

Update Group Headers with Record Counts


IBM Mainframe Forums -> DFSORT/ICETOOL
Post new topic   Reply to topic
View previous topic :: View next topic  
Author Message
Christopher Horowitz

New User


Joined: 09 Jul 2015
Posts: 7
Location: United States

PostPosted: Fri Jul 10, 2015 8:32 pm
Reply with quote

Hi,
I have an input file that has numerous groups (number of groups varies). Each group has a header and a trailer. I want to put the number of records in each group on the group header record. I've seen it done for a single file header, and I've seen it done for group trailers, but I can't figure out how to do it for group headers.

Input:
Code:
CHD 000001801           
23232       12345-0001 
23232       12345-0002 
CFT 000001801           
CHD 000773322           
56565       11122-0001 
56565       11122-0002 
56565       11122-0003 
56565       11122-0004 
CFT 000773322           


Desired output:
Code:
CHD 000001801 00000002
23232       12345-0001
23232       12345-0002
CFT 000001801         
CHD 000773322 00000004
56565       11122-0001
56565       11122-0002
56565       11122-0003
56565       11122-0004
CFT 000773322
Back to top
View user's profile Send private message
Bill Woodger

Moderator Emeritus


Joined: 09 Mar 2011
Posts: 7309
Location: Inside the Matrix

PostPosted: Fri Jul 10, 2015 9:39 pm
Reply with quote

Basically it'll be a variation of getting the number of records onto the file-header.

JOINKEYS, with the same DSN for both intput files. Specify SORTED,NOSEQCK on the JOINKEYS statement for F1.

On JNF1CNTL, extend the record (what that means exactly depends on whether fixed-length (easiest) or variable-length records) to include a GROUP ID (BEGIN = C'CHD' END = C'CFT' PUSH=(extendingplace:ID=N, where N is large enough to account for all your groups (N=number of digits)).

ON JNF2CNTL, extend to include the ID as above and the SEQ. If the current record is not a C'CFT', set the ID to binary-zeros (NZ). F2 will be sorted by default by the JOINKEYS for F2, and all the binary-zeros will be sorted together (and they will mismatch to F1).

Code:
  JOIN MATCHED,F1

This will give all the matches, which will be the original trailers from F2 with the count, and all the unmatched F1s (which will be all the other data records).

In the main task, update the matched records (adjusting the count by two for group header and trailer) so that the header has the correct value.

That's approximately it.

If unsure, do it stage by stage (with test-data going to SYSOUT) and understand what changes are happening.

EDIT: Replace invented keywords by the actually existing ones.
Back to top
View user's profile Send private message
magesh23586

Active User


Joined: 06 Jul 2009
Posts: 213
Location: Chennai

PostPosted: Sat Jul 11, 2015 10:43 pm
Reply with quote

Bill Woodger wrote:
JOINKEYS, with the same DSN for both intput files. Specify UNSORTED,NOSEQCK on the JOINKEYS statement for F1.


I dont think we have UNSORTED in DFSORT.

Bill Woodger wrote:

Code:

 JOIN UNMATCHED,F1



And also i dont think we have UNMATCHED with DFsort.

Here is the code. As Bill stated, use same DSN for both SORTJNF1 and SORTJNF2

Code:

//S1   EXEC  PGM=SORT       
//SYSOUT DD SYSOUT=*       
//SORTJNF1 DD *             
CHD 000001801               
23232       12345-0001     
23232       12345-0002     
CFT 000001801               
CHD 000773322               
56565       11122-0001     
56565       11122-0002     
56565       11122-0003     
56565       11122-0004     
CFT 000773322               
//SORTJNF2 DD *             
CHD 000001801               
23232       12345-0001     
23232       12345-0002     
CFT 000001801               
CHD 000773322               
56565       11122-0001     
56565       11122-0002
CFT 000773322                                                       
//SORTOUT DD SYSOUT=*                                               
//SYSIN    DD *                                                     
  OPTION COPY                                                       
  JOINKEYS FILE=F1,FIELDS=(23,8,A),SORTED,NOSEQCK                   
  JOINKEYS FILE=F2,FIELDS=(1,8,A)                                   
  REFORMAT FIELDS=(F1:1,22,F2:9,8,?)                                 
  JOIN UNPAIRED,F1                                                   
  OUTFIL IFTHEN=(WHEN=(31,1,CH,EQ,C'B'),                             
                 BUILD=(1,13,X,(23,8,ZD,SUB,+2),EDIT=(TTTTTTTT))),   
         IFTHEN=(WHEN=NONE,BUILD=(1,22))                             
//JNF1CNTL DD *                                                     
  INREC IFTHEN=(WHEN=GROUP,BEGIN=(1,3,CH,EQ,C'CHD'),                 
               END=(1,3,CH,EQ,C'CFT'),PUSH=(23:ID=8)),               
        IFTHEN=(WHEN=(1,3,CH,NE,C'CHD'),OVERLAY=(23:8X))             
//JNF2CNTL DD *                                                     
  INREC IFTHEN=(WHEN=GROUP,BEGIN=(1,3,CH,EQ,C'CHD'),                 
               END=(1,3,CH,EQ,C'CFT'),PUSH=(23:ID=8,SEQ=8)),   
        IFTHEN=(WHEN=(1,3,CH,EQ,C'CFT'),BUILD=(23,16)),         
        IFTHEN=(WHEN=NONE,BUILD=(16X))
Back to top
View user's profile Send private message
Christopher Horowitz

New User


Joined: 09 Jul 2015
Posts: 7
Location: United States

PostPosted: Sun Jul 12, 2015 5:25 am
Reply with quote

Thanks so much!!!

I had to modify it to 'extend' the files since data could appear anywhere in the 80 characters of the record. After much trial and error I ended up with:

Code:

//SYSIN     DD *
  OPTION COPY
  JOINKEYS FILE=F1,FIELDS=(81,8,A),SORTED,NOSEQCK
  JOINKEYS FILE=F2,FIELDS=(1,8,A)
  REFORMAT FIELDS=(F1:1,80,F2:9,8,?)
  JOIN UNPAIRED,F1
  OUTFIL IFTHEN=(WHEN=(89,1,CH,EQ,C'B'),
                 BUILD=(1,22,X,(81,8,ZD,SUB,+2),EDIT=(TTTTTTTT))),
         IFTHEN=(WHEN=NONE,BUILD=(1,80))
//*
//JNF1CNTL DD *
  INREC IFTHEN=(WHEN=GROUP,BEGIN=(1,3,CH,EQ,C'CHD'),
               END=(1,3,CH,EQ,C'CFT'),PUSH=(81:ID=8)),
        IFTHEN=(WHEN=(1,3,CH,NE,C'CHD'),OVERLAY=(81:8X))
//JNF2CNTL DD *
  INREC IFTHEN=(WHEN=GROUP,BEGIN=(1,3,CH,EQ,C'CHD'),
               END=(1,3,CH,EQ,C'CFT'),PUSH=(81:ID=8,SEQ=8)),
        IFTHEN=(WHEN=(1,3,CH,EQ,C'CFT'),BUILD=(81,16)),
        IFTHEN=(WHEN=NONE,BUILD=(16X))


I have a follow-up question. The file itself has a header record ('MHD') that I would like to add a count of the group headers to. Can that be included in the above sysin (so it is done in one pass) or would I need to do this separately?
Back to top
View user's profile Send private message
Bill Woodger

Moderator Emeritus


Joined: 09 Mar 2011
Posts: 7309
Location: Inside the Matrix

PostPosted: Sun Jul 12, 2015 5:54 pm
Reply with quote

I've no idea how I came up with UNSORTED or UNMATCHED, thanks magesh23586.

Christopher Horowitz,

If you already have a trailer on your file, then it is a simple application of a second count and similar application to the trailer.

If you don't already have a file trailer, you temporarily make one.

You need a new step, very short:

Code:
  OPTION COPY,STOPAFT=1
  INREC OVERLAY=(C'something unique to indicate trailer')


Output file to specify a little space, no DCB information (SORT will fill that in from the input dataset).

This new step can be run as part of the job, to a temporary dataset, or run as as a once-off to a permanent dataset which is regenerated when the RECFM/LRECL of the dataset changes.

This way you don't need to "hard-code" any record lengths.

In the processing you set the "key" to match your actual header, and use the count (adjusting per header/trailer number of records as necessary).

If you need to count the groups, or count only the data records (likely), that can be achieved also.
Back to top
View user's profile Send private message
Christopher Horowitz

New User


Joined: 09 Jul 2015
Posts: 7
Location: United States

PostPosted: Sun Jul 12, 2015 6:51 pm
Reply with quote

Thanks Bill.

I actually do just want the count of groups. My thought was to include the ID in the REFORMAT, and then use the ID value of the last CFT record and put it in the BUILD. I just couldn't get it to work.
Back to top
View user's profile Send private message
Bill Woodger

Moderator Emeritus


Joined: 09 Mar 2011
Posts: 7309
Location: Inside the Matrix

PostPosted: Sun Jul 12, 2015 7:42 pm
Reply with quote

If you use WHEN=GROUP to identify the group trailer, and PUSH the ID-previoyusly-specified by identifying each group-trailer and use RECORDS=2, when you get the file trailer, you will have the final ID from the groups, which is the count of the groups.

If you have a problem with that, post the code you have and we can knock it into shape. We'll assume RECFM=FB and LRECL=80.
Back to top
View user's profile Send private message
Christopher Horowitz

New User


Joined: 09 Jul 2015
Posts: 7
Location: United States

PostPosted: Mon Jul 13, 2015 12:02 am
Reply with quote

Thanks Bill,
I've been trying to get it to work. I feel like I'm close. Here's what I have for code:
Code:

//SYSIN     DD *
  OPTION COPY
  JOINKEYS FILE=F1,FIELDS=(81,8,A),SORTED,NOSEQCK
  JOINKEYS FILE=F2,FIELDS=(1,8,A)
  REFORMAT FIELDS=(F1:1,80,F2:1,16,?)
  JOIN UNPAIRED,F1
  OUTFIL IFTHEN=(WHEN=(97,1,CH,EQ,C'B',AND,1,3,CH,EQ,C'CHD'),
                 BUILD=(1,22,X,(89,8,ZD,SUB,+2),EDIT=(TTTTTTTT))),
         IFTHEN=(WHEN=(97,1,CH,EQ,C'B',AND,1,3,CH,EQ,C'MHD'),
                 BUILD=(1,32,X,(81,8,ZD),EDIT=(TTTTTTTT))),
         IFTHEN=(WHEN=NONE,BUILD=(1,80))
//*
//JNF1CNTL DD *
  INREC  IFTHEN=(WHEN=GROUP,BEGIN=(1,3,CH,EQ,C'MHD'),
                 RECORDS=2,PUSH=(81:ID=8)),
         IFTHEN=(WHEN=GROUP,BEGIN=(1,3,CH,EQ,C'CHD'),
                 END=(1,3,CH,EQ,C'CFT'),PUSH=(81:ID=8)),
         IFTHEN=(WHEN=(1,3,CH,NE,C'CHD',AND,1,3,CH,NE,C'MHD'),
                 OVERLAY=(81:8X))
//JNF2CNTL DD *
  INREC  IFTHEN=(WHEN=GROUP,BEGIN=(1,3,CH,EQ,C'MHD'),
                 RECORDS=2,PUSH=(81:ID=8,SEQ=8)),
         IFTHEN=(WHEN=GROUP,BEGIN=(1,3,CH,EQ,C'CHD'),
                 END=(1,3,CH,EQ,C'CFT'),PUSH=(81:ID=8,SEQ=8)),
         IFTHEN=(WHEN=(1,3,CH,EQ,C'CFT'),BUILD=(81,16)),
         IFTHEN=(WHEN=NONE,BUILD=(16X))


This is my input file:
Code:

MHD MAY25FILE1 20150525 00000002                         
CHD 000001801 00000006                                   
23232       123-45-0001      AAAAAAAAAAAAAAAAAAAAAAAA   
23232       123-45-0002      AAAAAAAAAAAAAAAAAAAAAAAA   
23232       123-45-0003      AAAAAAAAAAAAAAAAAAAAAAAA   
23232       123-45-0004      AAAAAAAAAAAAAAAAAAAAAAAA   
23232       123-45-0005      AAAAAAAAAAAAAAAAAAAAAAAA   
23232       123-45-0006      AAAAAAAAAAAAAAAAAAAAAAAA   
CFT 000001801                                           
CHD 000773322 00000008                                   
56565       111-22-0001      AAAAAAAAAAAAAAAAAAAAAAAA   
56565       111-22-0002      AAAAAAAAAAAAAAAAAAAAAAAA   
56565       111-22-0003      AAAAAAAAAAAAAAAAAAAAAAAA   
56565       111-22-0004      AAAAAAAAAAAAAAAAAAAAAAAA   
56565       111-22-0005      AAAAAAAAAAAAAAAAAAAAAAAA   
56565       111-22-0006      AAAAAAAAAAAAAAAAAAAAAAAA   
56565       111-22-0007      AAAAAAAAAAAAAAAAAAAAAAAA   
56565       111-22-0008      AAAAAAAAAAAAAAAAAAAAAAAA   
CFT 000773322                                           
MFT MAY25FILE1 2015052           


This is what I'm getting for output. Everything is correct except that the counter in cols 34-40 on MHD should be 2, not 1.
Code:

MHD MAY25FILE1 20150525 00000002 00000001
CHD 000001801 00000006 00000006
23232       123-45-0001      AAAAAAAAAAAAAAAAAAAAAAAA
23232       123-45-0002      AAAAAAAAAAAAAAAAAAAAAAAA
23232       123-45-0003      AAAAAAAAAAAAAAAAAAAAAAAA
23232       123-45-0004      AAAAAAAAAAAAAAAAAAAAAAAA
23232       123-45-0005      AAAAAAAAAAAAAAAAAAAAAAAA
23232       123-45-0006      AAAAAAAAAAAAAAAAAAAAAAAA
CFT 000001801
CHD 000773322 00000008 00000008
56565       111-22-0001      AAAAAAAAAAAAAAAAAAAAAAAA
56565       111-22-0002      AAAAAAAAAAAAAAAAAAAAAAAA
56565       111-22-0003      AAAAAAAAAAAAAAAAAAAAAAAA
56565       111-22-0004      AAAAAAAAAAAAAAAAAAAAAAAA
56565       111-22-0005      AAAAAAAAAAAAAAAAAAAAAAAA
56565       111-22-0006      AAAAAAAAAAAAAAAAAAAAAAAA
56565       111-22-0007      AAAAAAAAAAAAAAAAAAAAAAAA
56565       111-22-0008      AAAAAAAAAAAAAAAAAAAAAAAA
CFT 000773322
MFT MAY25FILE1 2015052                               
Back to top
View user's profile Send private message
Bill Woodger

Moderator Emeritus


Joined: 09 Mar 2011
Posts: 7309
Location: Inside the Matrix

PostPosted: Mon Jul 13, 2015 8:02 pm
Reply with quote

This should do what you want:

Code:
   OPTION COPY
   JOINKEYS FILE=F1,FIELDS=(81,8,A),SORTED,NOSEQCK
   JOINKEYS FILE=F2,FIELDS=(1,8,A)
   REFORMAT FIELDS=(F1:1,80,F2:1,16)
   JOIN UNPAIRED,F1
   OUTFIL IFTHEN=(WHEN=(1,3,CH,EQ,C'CHD'),
                  BUILD=(1,22,X,(89,8,ZD,SUB,+2),EDIT=(TTTTTTTT))),
          IFTHEN=(WHEN=(1,3,CH,EQ,C'MHD'),
                  BUILD=(1,32,X,(89,8,ZD),EDIT=(TTTTTTTT))),
          IFTHEN=(WHEN=NONE,BUILD=(1,80))
 //*
 //JNF1CNTL DD *
   INREC  IFTHEN=(WHEN=GROUP,BEGIN=(1,3,CH,EQ,C'CHD'),
                  END=(1,3,CH,EQ,C'CFT'),PUSH=(81:ID=8)),
          IFTHEN=(WHEN=(1,3,CH,EQ,C'MHD'),
                  OVERLAY=(81:8Z)),
          IFTHEN=(WHEN=(1,3,CH,NE,C'CHD'),
                  OVERLAY=(81:8X))
 //JNF2CNTL DD *
   INREC  IFTHEN=(WHEN=GROUP,BEGIN=(1,3,CH,EQ,C'CHD'),
                  END=(1,3,CH,EQ,C'CFT'),PUSH=(81:ID=8,SEQ=8)),
          IFTHEN=(WHEN=GROUP,BEGIN=(1,3,CH,EQ,C'CFT'),
                  PUSH=(81:81,8),RECORDS=2),
          IFTHEN=(WHEN=(1,3,CH,EQ,C'CFT'),BUILD=(81,16)),
          IFTHEN=(WHEN=(1,3,CH,EQ,C'MFT'),BUILD=(8Z,81,8)),
          IFTHEN=(WHEN=NONE,BUILD=(16X))



The 8Z gives you eight binary zeros, which is used to match to the file header. I've simplified the conditions where possible. IFTHEN=(WHEN=(logicalexpression) operates like a COBOL EVALUATE. So when an IFTHEN=(WHEN=(logicalexpression) is true, no futher IFHTHEN=(WHEN=(logicalexpression) will be tested for that record, so some of your NEs disappear. You don't need the match-marker (the ? on the REFORMAT statement) for this task. The only unmatched records are data-records. All the Matched records (the Bs) are header records of one type or the other. So simply test for the type of header.
Back to top
View user's profile Send private message
Christopher Horowitz

New User


Joined: 09 Jul 2015
Posts: 7
Location: United States

PostPosted: Mon Jul 13, 2015 8:24 pm
Reply with quote

Thank you so much!!!

That did indeed work. I'm especially grateful for the explanation. I understand it more than I ever have.

Thanks again.
Back to top
View user's profile Send private message
View previous topic :: :: View next topic  
Post new topic   Reply to topic View Bookmarks
All times are GMT + 6 Hours
Forum Index -> DFSORT/ICETOOL

 


Similar Topics
Topic Forum Replies
No new posts How to split large record length file... DFSORT/ICETOOL 10
No new posts SFTP Issue - destination file record ... All Other Mainframe Topics 2
No new posts FINDREP - Only first record from give... DFSORT/ICETOOL 3
No new posts To find whether record count are true... DFSORT/ICETOOL 6
No new posts Validating record count of a file is ... DFSORT/ICETOOL 13
Search our Forums:

Back to Top