Joined: 14 Jun 2006 Posts: 331 Location: Jacksonville, FL
I have an ICETOOL program giving me unexpected results.
This is my input file:
Code:
----+----1----+----2----+----3----+----4----+----5
CRSUPP XX1234 JON FRON A F RTU
CRSUPP XX1235 MIKE SYKE A F R U
CRSUPP XX1236 CHAD BAD A F RTU
CRSUPP XX1237 ROGER DOGGER A F U
CRSUPP XX1238 GREG LEGG A F RTU
CRSUPP XX1239 RICK STICK A F R U
CRSUPP OGOPERA STC OGOPERA F T
CRSUPP OGOPERJ STC OGOPERJ T
CRSUPP OGOPERN STC OGOPERN F
CRSUPP OGOPERP STC OGOPERP F
CRSUPP OGOPERR STC OGOPERR R
CRSUPP OGOPERS STC OGOPERS T
CRSUPP OGOPERST STC OGOPERST F
CRSUPP OGOPERT STC OGOPERT T
CRSUPP OMOPERA STC OMOPERA T
CRSUPP OMOPERK STC OMOPERK T
I run with these contol cards against the above input file:
But I really want a new record for every IFTHEN/WHEN condition. When I add HIT=NEXT, so it will process each IFTHEN/WHEN and build a separate record base on the condition, I use these control cards:
Joined: 07 Dec 2007 Posts: 2205 Location: San Jose
Quote:
But I really want a new record for every IFTHEN/WHEN condition. When I add HIT=NEXT, so it will process each IFTHEN/WHEN and build a separate record base on the condition
A new record is created using / and hit=next makes sort validate the next IFTHEN.
Show me the desired output and I will show you a way to do it.
All of the IFTHEN clauses operate sequentially on an IFTHEN record. The IFTHEN record is created initially from the input record. Each IFTHEN clause tests and changes the IFTHEN record, as appropriate. Thus, changes made by earlier IFTHEN clauses are 'seen'; by later IFTHEN clauses.
I think the changes made by first IFTHEN make the condition false for the second IFTHEN so you are not getting 1 record for each condition.
Joined: 14 Jun 2006 Posts: 331 Location: Jacksonville, FL
This would be my expected output. Each record is interrogated for a non-blank character in positions 41-50 of the input record. If it finds a non-blank character, a record should be generated. If 41-50 were all non-blank, it should build 10 records. If 42 and 50 are blank, then it should build 8 records based on positions 41, & 43-49 having non-blank values.
Joined: 14 Jun 2006 Posts: 331 Location: Jacksonville, FL
What I'm doing is using one ICETOOL program (within a REXX program) to create control cards for another ICETOOL program (within the same REXX program). I usually run ICETOOL programs in batch mode until I get the expected output. I then CALL ICETOOL within a REXX program after converting the control cards from the batch job into REXX statements. Using this method, I can easily read, select, and manipulate upwards of a million records without exhausting machine storage for my TSO session.
From this one record:
Code:
----+----1----+----2----+----3----+----4----+----5
CRSUPP XX1234 JON FRON ABCDEFGHIJ
I would expect to see 10 records generated because positions 41-50 are all non-blank.
----+----1----+----2----+----3----+----4----+----5
CRSUPP XX1234 JON FRON
I would expect no output because 41-50 are all blank. In my program, at least one position between 41-50 would be valued.
From this comment:
Quote:
you are validating mulitple values ex 'R,U,C,A' shouldn't you be using SS format?
You are correct, I should be using SS and not CH like this example from the manual:
Code:
INCLUDE FORMAT=SS,COND=(11,6000,EQ,C’OK’,OR,5,3,EQ,C’J69,L92,J82’)
This example illustrates how to include only records in which: OK is found somewhere within bytes 11 through 6010 OR Bytes 5 through 7 contain J69, L92 or J82.
From this comment:
Quote:
Also I see that you have CONVERT parm. Is your input file a VB file?
No. I thought CONVERT was needed because I was going from a 50 byte input to an 80 byte output.
Joined: 07 Dec 2007 Posts: 2205 Location: San Jose
cpuhawg wrote:
If it finds a non-blank character, a record should be generated. If 41-50 were all non-blank, it should build 10 records. If 42 and 50 are blank, then it should build 8 records based on positions 41, & 43-49 having non-blank values.
When would I generate the extra record? from what I understood till now is that
Code:
If pos 41 for length of 9 bytes does NOT have spaces
GENERATE 10 RECORDS WITH INCLUDE COND
END-IF
If pos 41 for length of 9 bytes = all spaces
do nothing
END-IF
Joined: 14 Jun 2006 Posts: 331 Location: Jacksonville, FL
For each record on the input file:
The ICETOOL program checks position 41. If it is blank, don't generate a record. If it is non-blank, generated a record.
The ICETOOL program then checks position 42. If it is blank, don't generate a record. If it is non-blank, generated a record.
The ICETOOL program then checks position 43. If it is blank, don't generate a record. If it is non-blank, generated a record.
....and so on up to position 50.
If 41-50 doesn't have any blanks, it should generate 10 records.
If 41-50 has 3 blanks, it should generate 7 records.
If 41-50 has 8 blanks, it should generate 2 records.
Note that each generated output record has a different position based on which fields of positions 41-50 are valued.
If 41 is non-blank, this record should be generated:
Joined: 07 Dec 2007 Posts: 2205 Location: San Jose
cpuhawg,
The following DFSORT/ICETOOL JCL will give you the desired results.
Code:
//STEP0100 EXEC PGM=ICETOOL
//TOOLMSG DD SYSOUT=*
//DFSMSG DD SYSOUT=*
//IN DD *
CRSUPP XX1234 JON FRON A F RTU
CRSUPP XX1235 MIKE SYKE A F R U
CRSUPP XX1236 CHAD BAD A F RTU
CRSUPP XX1237 ROGER DOGGER A F U
CRSUPP XX1238 GREG LEGG A F RTU
CRSUPP XX1239 RICK STICK A F R U
CRSUPP OGOPERA STC OGOPERA F T
CRSUPP OGOPERJ STC OGOPERJ T
CRSUPP OGOPERN STC OGOPERN F
CRSUPP OGOPERP STC OGOPERP F
CRSUPP OGOPERR STC OGOPERR R
CRSUPP OGOPERS STC OGOPERS T
CRSUPP OGOPERST STC OGOPERST F
CRSUPP OGOPERT STC OGOPERT T
CRSUPP OMOPERA STC OMOPERA T
CRSUPP OMOPERK STC OMOPERK T
//T1 DD DSN=&&T1,DISP=(,PASS),SPACE=(CYL,(1,1),RLSE)
//FORMATD DD SYSOUT=*
//TOOLIN DD *
//FORMATD DD SYSOUT=*
//TOOLIN DD *
COPY FROM(IN) USING(CTL1)
COPY FROM(T1) USING(CTL2)
//CTL1CNTL DD *
OUTFIL FNAMES=T1,REPEAT=9,
IFTHEN=(WHEN=INIT,BUILD=(01:10,8,41,9)),
IFTHEN=(WHEN=INIT,OVERLAY=(18:C'(54,8,CH,EQ,C''',1,8,C'''',
C',AND,',SEQNUM,2,ZD,START=63,INCR=1,RESTART=(1,8),
C',1,SS,EQ,C''',C'R,U,C,A''',C'),OR,',
81:SEQNUM,1,ZD,RESTART=(1,8),C'D')),
IFTHEN=(WHEN=(81,1,ZD,EQ,1,AND,09,1,CH,GT,C' '),OVERLAY=(82:C'P')),
IFTHEN=(WHEN=(81,1,ZD,EQ,2,AND,10,1,CH,GT,C' '),OVERLAY=(82:C'P')),
IFTHEN=(WHEN=(81,1,ZD,EQ,3,AND,11,1,CH,GT,C' '),OVERLAY=(82:C'P')),
IFTHEN=(WHEN=(81,1,ZD,EQ,4,AND,12,1,CH,GT,C' '),OVERLAY=(82:C'P')),
IFTHEN=(WHEN=(81,1,ZD,EQ,5,AND,13,1,CH,GT,C' '),OVERLAY=(82:C'P')),
IFTHEN=(WHEN=(81,1,ZD,EQ,6,AND,14,1,CH,GT,C' '),OVERLAY=(82:C'P')),
IFTHEN=(WHEN=(81,1,ZD,EQ,7,AND,15,1,CH,GT,C' '),OVERLAY=(82:C'P')),
IFTHEN=(WHEN=(81,1,ZD,EQ,8,AND,16,1,CH,GT,C' '),OVERLAY=(82:C'P')),
IFTHEN=(WHEN=(81,1,ZD,EQ,9,AND,17,1,CH,GT,C' '),OVERLAY=(82:C'P'))
//CTL2CNTL DD *
INCLUDE COND=(82,1,CH,EQ,C'P')
OUTFIL FNAMES=FORMATD,BUILD=(17X,18,63)
//*
Joined: 14 Jun 2006 Posts: 331 Location: Jacksonville, FL
All I can say is WOW. Your code did exactly what I needed and is greatly appreciated. I don't think anyone other than an ICETOOL expert could have created such a solution.
I did remove these two redundant statements from your example:
Code:
//FORMATD DD SYSOUT=*
//TOOLIN DD *
I still don't quite understand why my original code that produced the correct results (albeit only one record ouput per each input record). When HIT=NEXT was added and no other changes, the output was totally off. I would guess it was probably related to the BUILD parameter in that you can use BUILD to build multiple records (with the addition of a slash /), but maybe when IFTHEN/WHENs are being used, you don't get a new record for each IFTHEN/WHEN true condition. Maybe an option to BUILD mutiple records could be considered as a future enhancement, the way WITHANY made it easier to splice records.
Again..thanks for the solution as it's evident you spent a considerable amount of time and effort. My solution would have been iterating through the file 10 times building records as I go.
Joined: 14 Jun 2006 Posts: 331 Location: Jacksonville, FL
I'm found one issue with the solution. The interrogated fields from the IN input file were from 41-50, 10 positions.
These are a few records from the T1 interim file:
Code:
CR0410 A F RTU(54,8,CH,EQ,C'CR0410 ',AND,70,1,SS,EQ,C'R,U,C,A'),OR,
CR0410 A F RTU(54,8,CH,EQ,C'CR0410 ',AND,71,1,SS,EQ,C'R,U,C,A'),OR,
CR0466 A F R U(54,8,CH,EQ,C'CR0466 ',AND,63,1,SS,EQ,C'R,U,C,A'),OR,
It looks like you moved positions 41-49 (9 positions) but left out position 50. I made some adjustments to handle the additional position and it appears to be working correctly.
Here is the final code:
Code:
//STEP0100 EXEC PGM=ICETOOL
//TOOLMSG DD SYSOUT=*
//DFSMSG DD SYSOUT=*
//IN DD *
CRSUPP XX1234 JON FRON A F RTU
CRSUPP XX1235 MIKE SYKE A F R U
CRSUPP XX1236 CHAD BAD A F RTU
CRSUPP XX1237 ROGER DOGGER A F U
CRSUPP XX1238 GREG LEGG A F RTU
CRSUPP XX1239 RICK STICK A F R U
CRSUPP OGOPERA STC OGOPERA F T
CRSUPP OGOPERJ STC OGOPERJ T
CRSUPP OGOPERN STC OGOPERN F
CRSUPP OGOPERP STC OGOPERP F
CRSUPP OGOPERR STC OGOPERR R
CRSUPP OGOPERS STC OGOPERS T
CRSUPP OGOPERST STC OGOPERST F
CRSUPP OGOPERT STC OGOPERT T
CRSUPP OMOPERA STC OMOPERA T
CRSUPP OMOPERK STC OMOPERK T
//T1 DD DSN=&&T1,DISP=(,PASS),SPACE=(CYL,(1,1),RLSE)
//FORMATD DD SYSOUT=*
//TOOLIN DD *
COPY FROM(IN) USING(CTL1)
COPY FROM(T1) USING(CTL2)
//CTL1CNTL DD *
OUTFIL FNAMES=T1,REPEAT=10,
IFTHEN=(WHEN=INIT,BUILD=(01:10,8,41,10)),
IFTHEN=(WHEN=INIT,OVERLAY=(19:C'(54,8,CH,EQ,C''',1,8,C'''',
C',AND,',SEQNUM,2,ZD,START=63,INCR=1,RESTART=(1,8),
C',1,SS,EQ,C''',C'R,U,C,A''',C'),OR,',
81:SEQNUM,1,ZD,RESTART=(1,8),C'D')),
IFTHEN=(WHEN=(81,1,ZD,EQ,1,AND,09,1,CH,GT,C' '),OVERLAY=(82:C'P')),
IFTHEN=(WHEN=(81,1,ZD,EQ,2,AND,10,1,CH,GT,C' '),OVERLAY=(82:C'P')),
IFTHEN=(WHEN=(81,1,ZD,EQ,3,AND,11,1,CH,GT,C' '),OVERLAY=(82:C'P')),
IFTHEN=(WHEN=(81,1,ZD,EQ,4,AND,12,1,CH,GT,C' '),OVERLAY=(82:C'P')),
IFTHEN=(WHEN=(81,1,ZD,EQ,5,AND,13,1,CH,GT,C' '),OVERLAY=(82:C'P')),
IFTHEN=(WHEN=(81,1,ZD,EQ,6,AND,14,1,CH,GT,C' '),OVERLAY=(82:C'P')),
IFTHEN=(WHEN=(81,1,ZD,EQ,7,AND,15,1,CH,GT,C' '),OVERLAY=(82:C'P')),
IFTHEN=(WHEN=(81,1,ZD,EQ,8,AND,16,1,CH,GT,C' '),OVERLAY=(82:C'P')),
IFTHEN=(WHEN=(81,1,ZD,EQ,9,AND,17,1,CH,GT,C' '),OVERLAY=(82:C'P')),
IFTHEN=(WHEN=(81,1,ZD,EQ,10,AND,18,1,CH,GT,C' '),OVERLAY=(82:C'P'))
//CTL2CNTL DD *
INCLUDE COND=(82,1,CH,EQ,C'P')
OUTFIL FNAMES=FORMATD,BUILD=(17X,19,62,80:C' ')
//*
Joined: 07 Dec 2007 Posts: 2205 Location: San Jose
cpuhawg wrote:
I'm found one issue with the solution. The interrogated fields from the IN input file were from 41-50, 10 positions.
sorry for NOT accounting the 10 bytes. However I would say you just got lucky with evaluating the 10th record. The seqnum at pos 81 being checked in the IFTHEN is just 1 byte and you are checking for the value of 10 . In this case DFSORT adjusted the value according to the length and hence you got the right results.
I was never comfortable with 2 passes of data and I wanted to club everything into a single pass and I was able to do. Here is the updated version of it in a single pass of data and much more efficient version.
Code:
//STEP0100 EXEC PGM=SORT
//SYSOUT DD SYSOUT=*
//SORTIN DD *
CRSUPP BLAHBLAH CPUHAWG ABCDEFGHIJ
CRSUPP XX1234 JON FRON A F RTU
CRSUPP XX1235 MIKE SYKE A F R U
CRSUPP XX1236 CHAD BAD A F RTU
CRSUPP XX1237 ROGER DOGGER A F U
CRSUPP XX1238 GREG LEGG A F RTU
CRSUPP XX1239 RICK STICK A F R U
CRSUPP OGOPERA STC OGOPERA F T
CRSUPP OGOPERJ STC OGOPERJ T
CRSUPP OGOPERN STC OGOPERN F
CRSUPP OGOPERP STC OGOPERP F
CRSUPP OGOPERR STC OGOPERR R
CRSUPP OGOPERS STC OGOPERS T
CRSUPP OGOPERST STC OGOPERST F
CRSUPP OGOPERT STC OGOPERT T
CRSUPP OMOPERA STC OMOPERA T
CRSUPP OMOPERK STC OMOPERK T
//SORTOUT DD SYSOUT=*
//SYSIN DD *
OMIT COND=(41,10,CH,EQ,C' ')
SORT FIELDS=COPY
INREC IFTHEN=(WHEN=INIT,BUILD=(10,8,41,10,C'10')),
IFTHEN=(WHEN=INIT,OVERLAY=(021:C'"',C'(54,8,CH,EQ,C''',1,8,C'''',
C',AND,63,1,SS,EQ,C''',C'R,U,C,A''',C'),OR,',4X,C'"')),
IFTHEN=(WHEN=INIT,OVERLAY=(081:21,60,21,60,21,60,21,60,21,60,
21,60,21,60,21,60,21,60)),
IFTHEN=(WHEN=INIT,OVERLAY=(110:C'64',170:C'65',230:C'66',
290:C'67',350:C'68',410:C'69',
470:C'70',530:C'71',590:C'72')),