Problem:
Resolution:
The effect of SPLIT1R=nnn is to split the input data across a number of output datasets, placing nnn records in each dataset, with the last dataset in the group receiving any remaining records.
So, for example, if 4 datasets are specifed using OUTFIL FNAMES=(OUT1,OUT2,OUT3,OUT4), and SPLIT1R=2 is coded, then the first 2 records will be written to OUT1, records 3 and 4 to OUT2, records 5 and 6 to OUT3, and the remaining records to OUT4.
The customer's requirement was to split a file of unknown size into 4 equal subsets, maintaining the original record sequence, and placing any extra records (i.e. the 1 to 3 records remaining after 4 equal subsets have been created) in the 4th dataset.
Their orginal job achieved this on the mainframe using ICETOOL, and SPLIT1R:
//METHOD1 EXEC PGM=ICETOOL
//TOOLMSG DD SYSOUT=*
//DFSMSG DD SYSOUT=*
//IN DD DSN=MYDATA.SORTIN,DISP=SHR
//T1 DD DSN=&&T1,SPACE=(TRK,(1,1)),DISP=(,PASS)
//C1 DD DSN=&&C1,SPACE=(TRK,(1,1)),DISP=(,PASS)
//TOOLIN DD *
COPY FROM(IN) USING(CTL1)
COPY FROM(T1) TO(C1) USING(CTL2)
COPY FROM(IN) USING(CTL3)
/*
//CTL1CNTL DD *
OUTFIL FNAMES=T1,REMOVECC,NODETAIL,
TRAILER1=(COUNT=(M11,LENGTH=8)) <<== Create one record containing a count of the input data records
/*
//CTL2CNTL DD *
OUTREC BUILD=(2X,C' SPLIT1R=', <<== Generate a SPLIT1R=nnn control statement, where nnn = count/4
1,8,ZD,DIV, 04,TO=ZD,LENGTH=8,80:X)
/*
//CTL3CNTL DD *
OUTFIL FNAMES=(OUT1,OUT2,OUT3,OUT4), <<== Split the data across 4 files
// DD DSN=*.C1,DISP=(OLD,PASS) <<== using the SPLIT1R=nnn control statement created above
//*
//OUT1 DD DSN=MFDATA.OUTPUT.PART1,DISP=(,CATLG),SPACE=(TRK,1)
//OUT2 DD DSN=MFDATA.OUTPUT.PART2,DISP=(,CATLG),SPACE=(TRK,1)
//OUT3 DD DSN=MFDATA.OUTPUT.PART3,DISP=(,CATLG),SPACE=(TRK,1)
//OUT4 DD DSN=MFDATA.OUTPUT.PART4,DISP=(,CATLG),SPACE=(TRK,1)
The workaround for this was to use ICETOOL to create control statements for IDCAMS, which would then perform the data splitting, using the COUNT and SKIP options to control the placement of data records into the 4 output files:-
//METHOD2 EXEC PGM=ICETOOL
//TOOLMSG DD SYSOUT=*
//DFSMSG DD SYSOUT=*
//IN DD DSN=MYDATA.SORTIN,DISP=SHR
//T1 DD DSN=&&T1,UNIT=SYSDA,SPACE=(TRK,(1,1)),DISP=(,PASS)
//U1 DD DSN=&&U1,UNIT=SYSDA,SPACE=(TRK,(1,1)),DISP=(MOD,PASS)
//V1 DD DSN=&&V1,UNIT=SYSDA,SPACE=(TRK,(1,1)),DISP=(,PASS)
//C1 DD DSN=&&C1,UNIT=SYSDA,SPACE=(TRK,(1,1)),DISP=(MOD,PASS)
//TOOLIN DD *
COPY FROM(IN) TO(T1) USING(CTL1)
COPY FROM(T1) TO(U1) USING(CTL2)
COPY FROM(T1) TO(U1) USING(CTL3)
COPY FROM(T1) TO(U1) USING(CTL4)
COPY FROM(U1) TO(V1) USING(CTL5)
COPY FROM(V1) TO(C1) USING(CTL6)
COPY FROM(V1) TO(C1) USING(CTL7)
COPY FROM(V1) TO(C1) USING(CTL8)
COPY FROM(V1) TO(C1) USING(CTL9)
/*
//CTL1CNTL DD *
SORT FIELDS=(1,1,CH,A) <<== Dummy SORT to allow the use of SUM
INREC FIELDS=(C' 00000025') <<== Set up input field of 1/4
SUM FIELDS=(2,8,ZD) <<== Generate a count/4 field: nnn
/*
//CTL2CNTL DD *
INREC FIELDS=(C' 000000000000',2,6) <<== Generate 3 count fields: zero, zero, nnn
/*
//CTL3CNTL DD *
INREC FIELDS=(C' 000000',2,6,2,6) <<== Generate 3 count fields: zero, nnn, nnn
/*
//CTL4CNTL DD *
INREC FIELDS=(C' ',2,6,2,6,2,6) <<== Generate 3 count fields: nnn, nnn, nnn
/*
//CTL5CNTL DD *
SORT FIELDS=(1,1,CH,A) <<== Dummy SORT to allow the use of SUM
SUM FIELDS=(2,6,ZD,8,6,ZD,14,6,ZD) <<== Generate 3 count fields: nnn, nnn * 2, nnn * 3
/*
//CTL6CNTL DD *
OUTREC FIELDS=(2X,C'REPRO INFILE(IN) OUTFILE(OUT1)'
C' COUNT(',2,4,C')',80:X) <<== Generate "COUNT(nnn)"
/*
//CTL7CNTL DD *
OUTREC FIELDS=(2X,C'REPRO INFILE(IN) OUTFILE(OUT2)'
C' COUNT(',2,4,C') SKIP(',2,4,C')',80:X) <<== Generate "COUNT(nnn) SKIP(nnn)"
/*
//CTL8CNTL DD *
OUTREC FIELDS=(2X,C'REPRO INFILE(IN) OUTFILE(OUT3)'
C' COUNT(',2,4,C') SKIP(',8,4,C')',80:X) <<== Generate "COUNT(nnn) SKIP(nnn * 2)"
/*
//CTL9CNTL DD *
OUTREC FIELDS=(2X,C'REPRO INFILE(IN) OUTFILE(OUT4) ',
C' SKIP(',14,4,C')',80:X) <<== Generate "SKIP(nnn * 3)"
/*
//METHOD2B EXEC PGM=IDCAMS,COND=(0,NE)
//SYSPRINT DD SYSOUT=*,HOLD=Y
//SYSIN DD DSN=&&C1,DISP=(OLD,PASS) <<== Copy 4 subsets of data records
//IN DD DSN=MFISVR.FLOWFILE.INPUT,DISP=SHR
//OUT1 DD DSN=MFDATA.OUTPUT.PART1,DISP=(,CATLG),SPACE=(TRK,1)
//OUT2 DD DSN=MFDATA.OUTPUT.PART2,DISP=(,CATLG),SPACE=(TRK,1)
//OUT3 DD DSN=MFDATA.OUTPUT.PART3,DISP=(,CATLG),SPACE=(TRK,1)
//OUT4 DD DSN=MFDATA.OUTPUT.PART4,DISP=(,CATLG),SPACE=(TRK,1)
#StudioEnterpriseEdition
#COBOL
#netexpress
#ServerExpress
#Enterprise
#EnterpriseServer
#Server