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

Insert header record with record count of i/p file


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

New User


Joined: 25 May 2023
Posts: 18
Location: India

PostPosted: Mon May 29, 2023 7:29 pm
Reply with quote

Hi,

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
Back to top
View user's profile Send private message
sergeyken

Senior Member


Joined: 29 Apr 2008
Posts: 2141
Location: USA

PostPosted: Mon May 29, 2023 8:28 pm
Reply with quote

The short answer is: yes, it is possible, thou the requirement is as stupid, as a request to provide monthly totals at the first day of each month. icon_mad.gif

What have you tried so far? And what was wrong with your tests, up to the date?

Again: THIS IS A HELP FORUM, NOT “DO-MY-JOB-FOR-ME” FORUM.
Back to top
View user's profile Send private message
nupurbhui

New User


Joined: 25 May 2023
Posts: 18
Location: India

PostPosted: Mon May 29, 2023 9:43 pm
Reply with quote

Yes I've tried a code to do this in 2 steps.

Code:
//S1       EXEC PGM=ICEMAN                             
//SYSOUT   DD SYSOUT=*                                 
//SORTIN   DD DSN=i/p file,DISP=SHR     
//SORTOUT  DD DSN=&&S1,                                 
//            UNIT=SYSDA,SPACE=(TRK,(1,1)),DISP=(,PASS)
//SYSIN    DD *                                         
  OPTION COPY                                           
  OUTFIL REMOVECC,NODETAIL,                             
    TRAILER1=('MYCT,''',COUNT=(M11,LENGTH=5),'''')     
/*                                                     
//STEP02   EXEC PGM=ICEMAN                             
//SYSOUT   DD SYSOUT=*                                 
//SYMNAMES DD DSN=&&S1,DISP=(OLD,PASS)                 
//SORTIN   DD DSN=i/p file,DISP=SHR     
//SORTOUT  DD DSN=o/p file,DISP=SHR     
//SYSIN    DD    *                                     
  OPTION COPY                                           
  OUTFIL REMOVECC,                                     
    HEADER1=(7:MYCT)
/*   


I'm getting this error:
Code:
 DATA DICTIONARY SYMBOLS SUBSTITUTED :                             
 OPTION COPY                                                       
 OUTFIL REMOVECC,HEADER1=(7:MYCT)                                 
                        *                                           
WER813I  INSTALLATION OPTIONS IN MFX LOAD LIBRARY WILL BE USED     
WER268A  OUTFIL STATEMENT  : SYNTAX ERROR   
Back to top
View user's profile Send private message
sergeyken

Senior Member


Joined: 29 Apr 2008
Posts: 2141
Location: USA

PostPosted: Mon May 29, 2023 10:21 pm
Reply with quote

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?
Back to top
View user's profile Send private message
nupurbhui

New User


Joined: 25 May 2023
Posts: 18
Location: India

PostPosted: Tue May 30, 2023 11:43 am
Reply with quote

sergeyken wrote:
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.

code:
Code:
//COUNT    EXEC PGM=ICEMAN                             
//SYSOUT   DD SYSOUT=*                                 
//SORTIN   DD DSN=I/P FILE,DISP=SHR   
//SORTOUT  DD DSN=&&S1,                               
//            UNIT=SYSDA,SPACE=(TRK,(1,1)),DISP=(,PASS)
//SORTOUT@ DD SYSOUT=*                                 
//SYSIN    DD *                                       
  OPTION COPY                                         
  OUTFIL FNAMES=(SORTOUT,SORTOUT@),                   
    TRAILER1=('MYCT,''',COUNT=(M11,LENGTH=5),'''')     
/*                                                     
//REPORT   EXEC PGM=ICEMAN                             
//SYSOUT   DD SYSOUT=*                                 
//SYMNAMES DD DSN=&&S1,DISP=(OLD,PASS)                 
//SORTIN   DD DSN=I/P FILE,DISP=SHR   
//SORTOUT  DD DSN=O/P FILE,DISP=SHR   
//SYSIN    DD    *                                     
  OPTION COPY                                         
  OUTFIL REMOVECC, 
    HEADER1=(7:MYCT)
/*         



SYSOUT@ COUNT:
Code:
$A H           
Line 1A
Line 1B
Line 1C     
$U             
$A H           
Line 2A
Line 2B
Line 2C     
$U             
MYCT,'00010' 


Error message in SYSOUT REPORT:
Code:
 DATA DICTIONARY SYMBOLS SUBSTITUTED :                       
 OPTION COPY                                                 
 OUTFIL REMOVECC,HEADER1=(7:MYCT)                           
                        *                                     
WER813I  INSTALLATION OPTIONS IN MFX LOAD LIBRARY WILL BE USED
WER268A  OUTFIL STATEMENT  : SYNTAX ERROR       
Back to top
View user's profile Send private message
sergeyken

Senior Member


Joined: 29 Apr 2008
Posts: 2141
Location: USA

PostPosted: Tue May 30, 2023 5:51 pm
Reply with quote

nupurbhui wrote:

SYSOUT@ COUNT:
Code:
$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:
Group_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.
Back to top
View user's profile Send private message
nupurbhui

New User


Joined: 25 May 2023
Posts: 18
Location: India

PostPosted: Tue May 30, 2023 6:07 pm
Reply with quote

sergeyken wrote:
nupurbhui wrote:

SYSOUT@ COUNT:
Code:
$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.

Sorry for the lack of clarity.
Back to top
View user's profile Send private message
nupurbhui

New User


Joined: 25 May 2023
Posts: 18
Location: India

PostPosted: Tue May 30, 2023 6:39 pm
Reply with quote

nupurbhui wrote:
sergeyken wrote:
nupurbhui wrote:

SYSOUT@ COUNT:
Code:
$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 :
Code:
1234567890
000002


Sorry for the lack of clarity.
Back to top
View user's profile Send private message
sergeyken

Senior Member


Joined: 29 Apr 2008
Posts: 2141
Location: USA

PostPosted: Tue May 30, 2023 7:52 pm
Reply with quote

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.
Back to top
View user's profile Send private message
Joerg.Findeisen

Senior Member


Joined: 15 Aug 2015
Posts: 1335
Location: Bamberg, Germany

PostPosted: Tue May 30, 2023 11:11 pm
Reply with quote

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? icon_rolleyes.gif
Back to top
View user's profile Send private message
nupurbhui

New User


Joined: 25 May 2023
Posts: 18
Location: India

PostPosted: Wed May 31, 2023 3:42 pm
Reply with quote

sergeyken wrote:
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:
Code:
//STEP01   EXEC PGM=SORT                           
//SYSOUT   DD SYSOUT=*                             
//SORTIN   DD DSN=FILE1,DISP=SHR
//SORTOUT  DD DSN=FILE2, 
//             SPACE=(CYL,(1,1),RLSE),DCB=*.SORTIN,
//             DISP=(NEW,CATLG,DELETE)             
//SYSIN    DD *                                   
    SORT FIELDS=COPY                               
    INCLUDE COND=(5,2,CH,EQ,C'$A')                 
/*                                                 
//STEP02  EXEC PGM=ICETOOL                               
//TOOLMSG  DD  SYSOUT=*                                   
//DFSMSG   DD  SYSOUT=*                                   
//DD01     DD  DSN=FILE2,DISP=SHR
//DD02     DD  DSN=FILE2,DISP=SHR
//TOOLIN   DD  *                                         
  COUNT FROM(DD01) WRITE(DD02) DIGITS(6)                 
/*     


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?
Code:
//STEP03   EXEC PGM=SORT                                 
//SORTIN   DD DSN=FILE2,DISP=SHR
//              DD DSN=FILE1,DISP=SHR       
//SORTOUT  DD DSN=FILE1,DISP=SHR       
//SYSOUT   DD SYSOUT=*                                   
//SYSIN DD *                                             
  OUTFIL FNAMES=SORTOUT,FTOV                             
  SORT FIELDS=COPY                                       
/*           
Back to top
View user's profile Send private message
nupurbhui

New User


Joined: 25 May 2023
Posts: 18
Location: India

PostPosted: Wed May 31, 2023 4:22 pm
Reply with quote

Joerg.Findeisen wrote:
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? icon_rolleyes.gif


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?

My bad, I'm new to this portal. Still learning.
Back to top
View user's profile Send private message
Joerg.Findeisen

Senior Member


Joined: 15 Aug 2015
Posts: 1335
Location: Bamberg, Germany

PostPosted: Wed May 31, 2023 5:20 pm
Reply with quote

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                                                                 
/*
Back to top
View user's profile Send private message
nupurbhui

New User


Joined: 25 May 2023
Posts: 18
Location: India

PostPosted: Wed May 31, 2023 9:03 pm
Reply with quote

Joerg.Findeisen wrote:
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.
Code:
//STEP01   EXEC PGM=ICEMAN                                           
//SORTIN   DD DSN=FILE1,DISP=SHR             
//SORTOUT  DD DSN=FILE1,DISP=SHR             
//SYSOUT   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                                                                 
/*   


The error:
Code:
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.
Back to top
View user's profile Send private message
Joerg.Findeisen

Senior Member


Joined: 15 Aug 2015
Posts: 1335
Location: Bamberg, Germany

PostPosted: Wed May 31, 2023 11:07 pm
Reply with quote

And when you tried what I have posted, you've got something valid? This was provided to you to understand the logic.

PS: For variable Datasets (not files), you must consider/include the RDW.
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 Unable to interpret a hex value to De... COBOL Programming 7
No new posts Copy only TEXT or String from a record SYNCSORT 4
No new posts combine multiple unique records into ... DFSORT/ICETOOL 2
No new posts SORT on detail record, then repeat he... DFSORT/ICETOOL 3
No new posts how to complete the end of a record w... DFSORT/ICETOOL 2
Search our Forums:

Back to Top