I have a flat file (PS) which is FB 80 bytes and has records with delimiters. File does not have header. Is it possible to run this file through a sort step sum the total number of records and write whole file back out but now with a additional Header record with total record count at 7th column.
i/p: Here 1 record = from $A to $U
Code:
123456789012345
$A H
Line 1A
Line 1B
Line 1C
$U
$A H
Line 2A
Line 2B
Line 2C
$U
Expected o/p:
Code:
123456789012345
COUNT 000002
$A H
Line 1A
Line 1B
Line 1C
$U
$A H
Line 2A
Line 2B
Line 2C
$U
1. Rename //S1 to //COUNT
and
//STEP02 to //REPORT
2. Verify the result from //COUNT step
a) add debugging statement to //COUNT step:
Code:
//SORTOUT@ DD SYSOUT=*
b) add parameter to OUTFIL statement:
Code:
OUTFIL FNAMES=(SORTOUT,SORTOUT@), …
3. Analyze the debugging output, and try to guess: what may be wrong?
Based on the error message, your MYCT symbolic name is not defined properly. It is your own responsibility to find out: why?
1. Rename //S1 to //COUNT
and
//STEP02 to //REPORT
2. Verify the result from //COUNT step
a) add debugging statement to //COUNT step:
Code:
//SORTOUT@ DD SYSOUT=*
b) add parameter to OUTFIL statement:
Code:
OUTFIL FNAMES=(SORTOUT,SORTOUT@), …
3. Analyze the debugging output, and try to guess: what may be wrong?
Based on the error message, your MYCT symbolic name is not defined properly. It is your own responsibility to find out: why?
I did as suggested. But i can see the records are getting counted and saved in MYCT as shown in SYSOUT@ also.
$A H
Line 1A
Line 1B
Line 1C
$U
$A H
Line 2A
Line 2B
Line 2C
$U
MYCT,'00010'
Expected result must be:
Code:
MYCT,'00002'
Or even better:
Code:
Groups_Count,'00002'
Try to think a little bit: why your result is different?
Next step: try to think how to fix this problem?
P.S.
Ability to think is the major feature of any software developer, he is paid for.
My main requirement is to get the count in header. So firstly, I'm trying to get the records count in the header, however they are. Here as there are 10 lines in the i/p file, i'm trying to get the count 10 in header. Then I would try to add some condition to read records according to the delimiters if possible.
I intended to do the same in the code, to simply get the count in header first.
$A H
Line 1A
Line 1B
Line 1C
$U
$A H
Line 2A
Line 2B
Line 2C
$U
MYCT,'00010'
Expected result must be:
Code:
MYCT,'00002'
Or even better:
Code:
Groups_Count,'00002'
Try to think a little bit: why your result is different?
Next step: try to think how to fix this problem?
P.S.
Ability to think is the major feature of any software developer, he is paid for.
My main requirement is to get the count in header. So firstly, I'm trying to get the records count in the header, however they are. Here as there are 10 lines in the i/p file, i'm trying to get the count 10 in header. Then I would try to add some condition to read records according to the delimiters if possible.
I intended to do the same in the code, to simply get the count in header first.
Im able to get the nuber of records in a separate file as below :
Under ANY circumstances you CANNOT physically get the count of whatever from your input data BEFORE you have read that data in full. That's why two stages are needed anyway, whatever tool, and whatever approach you want to use.
In your case you need to get not "the number of records" (as you mentioned), but "the number of groups", or sections, or whatever you call it, BUT NOT NUMBER OF RECORDS, in no way!
If you really are able to get this number as '000002', what prevents you from getting the same as 'COUNT 000002'?
Please, demonstrate: how did you get your '000002'?
After you are able to create either '000002', or 'COUNT 000002' there should be no problem in combination those two separate parts as a single output.
There are many-many ways to combine the output as
Code:
COUNT 000002
$A H
Line 1A
Line 1B
Line 1C
$U
$A H
Line 2A
Line 2B
Line 2C
$U
Again, and again, and again: there is no physical possibility to produce the result you want in a single stage using the methods of sequential data processing. You need to touch your input data twice, anyway.
In case you were able to eliminate the stupid requirement to place the total count at the beginning of the report, the same could be done in one single stage.
Joined: 15 Aug 2015 Posts: 1335 Location: Bamberg, Germany
Basically it's not that difficult to achieve what's requested. It remains unclear if the number of groups, or the number of records are needed. For the number of groups, use IFTHEN=(WHEN=GROUP,.. to assign some ident number in a single stage. Condense, so only one line with the highest ID is left. Second stage is to combine existing data with the retrieved group count.
Once the logic is clear, you may be able to end up with very few lines of code.
BTW, Why is this posted to DFSORT, and not to SYNCSORT section?
Under ANY circumstances you CANNOT physically get the count of whatever from your input data BEFORE you have read that data in full. That's why two stages are needed anyway, whatever tool, and whatever approach you want to use.
In your case you need to get not "the number of records" (as you mentioned), but "the number of groups", or sections, or whatever you call it, BUT NOT NUMBER OF RECORDS, in no way!
If you really are able to get this number as '000002', what prevents you from getting the same as 'COUNT 000002'?
Please, demonstrate: how did you get your '000002'?
After you are able to create either '000002', or 'COUNT 000002' there should be no problem in combination those two separate parts as a single output.
There are many-many ways to combine the output as
Code:
COUNT 000002
$A H
Line 1A
Line 1B
Line 1C
$U
$A H
Line 2A
Line 2B
Line 2C
$U
Again, and again, and again: there is no physical possibility to produce the result you want in a single stage using the methods of sequential data processing. You need to touch your input data twice, anyway.
In case you were able to eliminate the stupid requirement to place the total count at the beginning of the report, the same could be done in one single stage.
For clarity:
FILE1:
Code:
$A H
Line 1A
Line 1B
Line 1C
$U
$A H
Line 2A
Line 2B
Line 2C
$U
FILE2:
Code:
1234567890
000002
I have used below code to get the count as 000002:
Is there any better way to get the count in a single step? Also, what is the best way to place the count I now have in FILE2 into the main i/p file having the original data, i.e., FILE1? Like this:
Code:
123456789012345
COUNT 000002
$A H
Line 1A
Line 1B
Line 1C
$U
$A H
Line 2A
Line 2B
Line 2C
$U
I tried to merge them with the code below, but in step02 the rec length of the file is changing from original 2004 to 6 as I have given DIGITS(06). So when I try to merge it with FILE1 of record length=2004, it throws error. How can I resolve that?
Basically it's not that difficult to achieve what's requested. It remains unclear if the number of groups, or the number of records are needed. For the number of groups, use IFTHEN=(WHEN=GROUP,.. to assign some ident number in a single stage. Condense, so only one line with the highest ID is left. Second stage is to combine existing data with the retrieved group count.
Once the logic is clear, you may be able to end up with very few lines of code.
BTW, Why is this posted to DFSORT, and not to SYNCSORT section?
Hi!
I've tried to learn and code using IFTHEN=(WHEN=GROUP.. to get the count but I'm unable to understand the syntax for it. Can you please help me with a simple code snippet. Or any good study materials.
Quote:
BTW, Why is this posted to DFSORT, and not to SYNCSORT section?
Joined: 15 Aug 2015 Posts: 1335 Location: Bamberg, Germany
Nothing is thrown in z/OS ever. Try the following to get the group count in one line:
Code:
//WHATEVER EXEC PGM=ICEMAN
//SORTIN DD *
123456789012345
$A H
Line 1A
Line 1B
Line 1C
$U
$A H
Line 2A
Line 2B
Line 2C
$U
/*
//SYSOUT DD SYSOUT=*
//SORTOUT DD SYSOUT=*
//SYSIN DD *
INREC IFTHEN=(WHEN=INIT,OVERLAY=(82:4Z)),
IFTHEN=(WHEN=GROUP,BEGIN=(1,3,CH,EQ,C'$A'),END=(1,3,CH,EQ,C'$U'),
PUSH=(86:ID=8),RECORDS=1),
IFTHEN=(WHEN=(86,8,FS,EQ,NUM),OVERLAY=(82:+1,BI,LENGTH=4))
SORT FIELDS=(81,1,CH,A)
SUM FIELDS=(82,4,BI)
OUTREC BUILD=(C'COUNT:',X,82,4,BI)
END
/*
Nothing is thrown in z/OS ever. Try the following to get the group count in one line:
Code:
//WHATEVER EXEC PGM=ICEMAN
//SORTIN DD *
123456789012345
$A H
Line 1A
Line 1B
Line 1C
$U
$A H
Line 2A
Line 2B
Line 2C
$U
/*
//SYSOUT DD SYSOUT=*
//SORTOUT DD SYSOUT=*
//SYSIN DD *
INREC IFTHEN=(WHEN=INIT,OVERLAY=(82:4Z)),
IFTHEN=(WHEN=GROUP,BEGIN=(1,3,CH,EQ,C'$A'),END=(1,3,CH,EQ,C'$U'),
PUSH=(86:ID=8),RECORDS=1),
IFTHEN=(WHEN=(86,8,FS,EQ,NUM),OVERLAY=(82:+1,BI,LENGTH=4))
SORT FIELDS=(81,1,CH,A)
SUM FIELDS=(82,4,BI)
OUTREC BUILD=(C'COUNT:',X,82,4,BI)
END
/*
I tried this code, but facing an abend ABENDU0016.
SORTIN : RECFM=VB ; LRECL= 2004; BLKSIZE= 27966
SORTIN : DSNAME=FILE1
INREC RECORD LENGTH = 2004
OUTREC RDW NOT INCLUDED
I should have mentioned it earlier, FILE1 is VB with record length=2004. I came across something as VB files column numbers are coded differently from FB. Not sure how to change the values in the code.