Alongwith the Addition of the Delimiter I want to replace few fields
I want to replace Field3, Field 6, Field8. These fields have 2 possible values. When Field3 is SCIENCE then it will be replaced as ABCDEFG Else it will be replaced as GHIJKLM. When Field6 is X'00' then 0 Else 1. When Field8 is SUN THEN Relace with CAR ELSE REPLACE WITH BUS.
This can be done thrugh an OUTREC BUILD and IF THEN but I have more than 10 fields which I need to replace and can't repeat them with all the combinations.
Alongwith the Addition of the Delimiter I want to replace few fields
I want to replace Field3, Field 6, Field8. These fields have 2 possible values. When Field3 is SCIENCE then it will be replaced as ABCDEFG Else it will be replaced as GHIJKLM. When Field6 is X'00' then 0 Else 1. When Field8 is SUN THEN Relace with CAR ELSE REPLACE WITH BUS.
This can be done thrugh an OUTREC BUILD and IF THEN but I have more than 10 fields which I need to replace and can't repeat them with all the combinations.
Rule #1: try to assign meaningful names to any object of your code, rather then giving them stupid and useless names like FIELD1, STEP01, VAR3, etc.
Rule #2: try to add comments to any part of your code
Code:
//*=====================================================================
//* GENERATE TEST DATA IN REQUIRED FORMAT
//*=====================================================================
//FTOV EXEC PGM=IEBGENER
//SYSPRINT DD SYSOUT=*
//SYSIN DD DUMMY
//SYSUT1 DD *
1 11111111222233333334444445555677777888
2 111111112222SCIENCE4444445555 77777SUN
3 111111112222MATH 4444445555677777WED
//*-+----1----+----2----+----3----+----4----+----5----+----6----+----7
//*
//SYSUT2 DD DISP=(NEW,PASS),DSN=&&VFORMAT,
// SPACE=(TRK,(10,10),RLSE),
// RECFM=VB,LRECL=104,BLKSIZE=0
//*
//*=====================================================================
//* CONVERT INPUT RECFM=VB DATA TO CSV FORMAT, RECFM=FB
//*=====================================================================
//CSVDATA EXEC PGM=SORT
//SYSOUT DD SYSOUT=*
//*
//SYMNAMES DD *
RDW,1,4,BI RECFM=V DESCRIPTION WORD
* FIELDS ARE GOING ONE AFTER ONE; NO NEED TO CALCULATE POSITIONS!
ID,*,6,CH
FIELD1,*,8,CH
FIELD2,*,4,CH
FIELD3,*,7,CH
FIELD4,*,6,CH
FIELD5,*,4,CH
FIELD6,*,1,CH
FIELD7,*,5,CH
FIELD8,*,3,CH
* . . . . . . .
DELIMITER,C',' FIELD DELIMITER; SUBJECT TO CHANGE IN THE FUTURE
//*
//SORTIN DD DISP=(OLD,DELETE),DSN=&&VFORMAT
//SORTOUT DD SYSOUT=*,RECFM=FB,LRECL=100,BLKSIZE=0
//*
//SYSIN DD *
SORT FIELDS=COPY
OUTFIL FNAMES=SORTOUT,VTOF,
OUTREC=(ID,DELIMITER,
FIELD1,DELIMITER,
FIELD2,DELIMITER,
FIELD3,CHANGE=(7,C'SCIENCE',C'ABCDEFG'),
NOMATCH=(C'GHIJKLM'),
DELIMITER,
FIELD4,DELIMITER,
FIELD5,DELIMITER,
FIELD6,CHANGE=(1,X'00',C'0'),
NOMATCH=(C'1'),
DELIMITER,
FIELD7,DELIMITER,
FIELD8,CHANGE=(3,C'SUN',C'CAR'),
NOMATCH=(C'BUS'))
END
//*
//*=====================================================================
Code:
********************************* TOP OF DATA **********
1 ,11111111,2222,GHIJKLM,444444,5555,1,77777,BUS
2 ,11111111,2222,ABCDEFG,444444,5555,0,77777,CAR
3 ,11111111,2222,GHIJKLM,444444,5555,1,77777,BUS
******************************** BOTTOM OF DATA ********
Joined: 15 Aug 2015 Posts: 1329 Location: Bamberg, Germany
Learning from mistakes helps fairly often.
Symbols are a good choice to use when you have too much variables. I for myself find it easier to use mixed case for variable names. Even a type writer could distinguish between upper and lower case, and that was some time ago. ;)
I can do that with an INREC FINDREP on the entire record like below. But is there a simpler way to do that at Field Level i.e. I can apply that to only Field4 and Field7 so that it doesn't have to go through all the fields?
Code:
//*=====================================================================
//* GENERATE TEST DATA IN REQUIRED FORMAT
//*=====================================================================
//FTOV EXEC PGM=IEBGENER
//SYSPRINT DD SYSOUT=*
//SYSIN DD DUMMY
//SYSUT1 DD *
1 11111111222233333334444445555677777888
2 111111112222SCIENCE4 4 4 5555 7 7 7SUN
3 111111112222MATH ^4 4 455556 7 77WED
//*-+----1----+----2----+----3----+----4----+----5----+----6----+----7
//*
//SYSUT2 DD DISP=(NEW,PASS),DSN=&&VFORMAT,
// SPACE=(TRK,(10,10),RLSE),UNIT=SYSDA,
// RECFM=VB,LRECL=104,BLKSIZE=0
//*
//*=====================================================================
//* CONVERT INPUT RECFM=VB DATA TO CSV FORMAT, RECFM=FB
//*=====================================================================
//CSVDATA EXEC PGM=SORT
//SYSOUT DD SYSOUT=*
//*
//SYMNAMES DD *
RDW,1,4,BI RECFM=V DESCRIPTION WORD
* FIELDS ARE GOING ONE AFTER ONE; NO NEED TO CALCULATE POSITIONS!
ID,*,6,CH
FIELD1,*,8,CH
FIELD2,*,4,CH
FIELD3,*,7,CH
FIELD4,*,6,CH
FIELD5,*,4,CH
FIELD6,*,1,CH
FIELD7,*,5,CH
FIELD8,*,3,CH
DELIMITER,C',' FIELD DELIMITER; SUBJECT TO CHANGE IN THE FUTURE
//*
//SORTIN DD DISP=(OLD,DELETE),DSN=&&VFORMAT
//SORTOUT DD SYSOUT=*,RECFM=FB,LRECL=52,BLKSIZE=0
//*
//SYSIN DD *
SORT FIELDS=COPY
INREC FINDREP=(INOUT=(X'00',X'40',X'40',X'40',X'05',X'40',
X'B0',X'40',X'1A',X'40',X'3A',X'40',
X'01',X'40',X'41',X'40',X'13',X'40',
X'15',X'40',X'08',X'40',X'FF',X'40'))
OUTFIL FNAMES=SORTOUT,VTOF,
OUTREC=(ID,DELIMITER,
FIELD1,DELIMITER,
FIELD2,DELIMITER,
FIELD3,CHANGE=(7,C'SCIENCE',C'ABCDEFG'),
NOMATCH=(C'GHIJKLM'),
DELIMITER,
FIELD4,DELIMITER,
FIELD5,DELIMITER,
FIELD6,CHANGE=(1,X'00',C'0'),
NOMATCH=(C'1'),
DELIMITER,
FIELD7,DELIMITER,
FIELD8,CHANGE=(3,C'SUN',C'CAR'),
NOMATCH=(C'BUS'))
END
//*
//*==================================================================
Joined: 15 Aug 2015 Posts: 1329 Location: Bamberg, Germany
@sergeyken is absolutely right. ALTSEQ and TRAN are most of the time easier to handle for single bytes. CHANGE operator is good for single field replacements, and FINDREP finally, the ultimate weapon for multiple fields in a record.
Besides the SORT coding, any reason to use DISP=(OLD,DELETE) on SORTIN when you are passing the DSN? IMHO it should be DISP=(OLD,PASS)
Besides the SORT coding, any reason to use DISP=(OLD,DELETE) on SORTIN when you are passing the DSN? IMHO it should be DISP=(OLD,PASS)
This is a specific test-related update: the temporary data created exclusively by the previous step, in required format. In such case it is usually not needed later. But of course, it depends…
Thanks for the inputs. Both INREC FINDREP with INOUT parameters at all Field levels as well as the ALTSEQ CODE= and parameter TRAN=ALTSEQ at multiple field level with OUTREC worked well and didn't see much performance difference between these 2 options. So based on the requirement we can apply any of these I suppose. These worked when the combination of i/p and changed o/p of characters is same across all fields.
If different fields have different requirements then tried with INREC IFTHEN FINDREP with STARTPOS and ENDPOS. If there is any other approach for this then will like to know that.