Here is how to copy all PDS members to a single dataset. Find below the REXX code. The tool can be executed both in front end and batch.
REXX code :
/* REXX */
PARSE UPPER PULL DSN
PARSE UPPER PULL TDS
DUMMY = OUTTRAP("MEMB.","*")
ADDRESS TSO
"LISTDS '"DSN"' MEMBERS"
DUMMY = OUTTRAP("OFF")
T = 0
DO I = 7 TO MEMB.0
DSN1 = "'"DSN"("SPACE(MEMB.I,0)")'"
/* READ PDS MEMBER */
ADDRESS TSO
"ALLOC F(IN) DS("DSN1") SHR"
"EXECIO * DISKR IN (FINIS STEM IN."
"FREE F(IN)"
DO S = 1 TO IN.0
T = T + 1
OUT.T = IN.S
END
END
OUT.0 = T
DSN2 = "'"TDS"'"
/* WRITE TO PS */
ADDRESS TSO
"ALLOC F(OUT) DS("DSN2") SHR"
"EXECIO * DISKW OUT (FINIS STEM OUT."
"FREE F(OUT)"
EXIT
REXX code :
/* REXX */
PARSE UPPER PULL DSN
PARSE UPPER PULL TDS
DUMMY = OUTTRAP("MEMB.","*")
ADDRESS TSO
"LISTDS '"DSN"' MEMBERS"
DUMMY = OUTTRAP("OFF")
T = 0
DO I = 7 TO MEMB.0
DSN1 = "'"DSN"("SPACE(MEMB.I,0)")'"
/* READ PDS MEMBER */
ADDRESS TSO
"ALLOC F(IN) DS("DSN1") SHR"
"EXECIO * DISKR IN (FINIS STEM IN."
"FREE F(IN)"
DO S = 1 TO IN.0
T = T + 1
OUT.T = IN.S
END
END
OUT.0 = T
DSN2 = "'"TDS"'"
/* WRITE TO PS */
ADDRESS TSO
"ALLOC F(OUT) DS("DSN2") SHR"
"EXECIO * DISKW OUT (FINIS STEM OUT."
"FREE F(OUT)"
EXIT
JCL step to excute the tool in batch :
//STEP1 EXEC PGM=IKJEFT01,PARM='PDS2PS'
//*
//* PDS2PS CONTAINS THE REXX CODE
//*
//SYSTSIN DD *
ABCD79.S1234.TT3
ABCD79.S1234.TT4
/*
//* ABCD79.S1234.TT3 IS A PDS
//* ABCD79.S1234.TT4 IS A PS
//*
//SYSTSPRT DD SYSOUT=*
//*
//SYSEXEC DD DSN=N123DF.REXX.CODE,DISP=SHR
//* N123DF.REXX.CODE CONTAINS MEMBER PDS2PS
//*
//* PDS2PS CONTAINS THE REXX CODE
//*
//SYSTSIN DD *
ABCD79.S1234.TT3
ABCD79.S1234.TT4
/*
//* ABCD79.S1234.TT3 IS A PDS
//* ABCD79.S1234.TT4 IS A PS
//*
//SYSTSPRT DD SYSOUT=*
//*
//SYSEXEC DD DSN=N123DF.REXX.CODE,DISP=SHR
//* N123DF.REXX.CODE CONTAINS MEMBER PDS2PS
Whats wrong with a simple PTPCH, like this:
ReplyDelete000100 //UTB00X JOB NOTIFY=&SYSUID
000200 //STEG1 EXEC PGM=IEBPTPCH
000300 //SYSPRINT DD SYSOUT=*
000400 //SYSUT1 DD DSN=yourpds,DISP=SHR
000500 //SYSUT2 DD DSN=yournewps,DISP=(,CATLG),
000600 // SPACE=(TRK,(10,5)),LRECL=80,RECFM=FB
000700 //SYSIN DD *
000800 PUNCH TYPORG=PO,MAXFLDS=1
000900 RECORD FIELD=(72)
IEBCOPY: PROCEDURE
ReplyDeleteARG ARGA, ARGB, MEMBER1, MEMBER2
IF MEMBER2 = '' THEM MEMBER2 = MEMBER1
"ALLOC FI(SYSPRINT) DSN('NULLFILE')"
"ALLOCATE FI(SYSIN) UNIT(SYSDA) LRECL(80)",
"SPACE (10 1) BLKSIZE(3200) RECFM(F,B) NEW REUSE"
"ALLOCATE FI(SYSUT1) DSN('"ARGA"') SHR REUSE"
"ALLOCATE FI(SYSUT2) DSN('"ARGB"') SHR REUSE"
QUEUE ' COPY INDD=SYSUT1,OUTDD=SYSUT2'
QUEUE ' SELECT MEMBER=((MEMBER1,MEMBER2,R))'
QUEUE ''
"EXECIO * DISKW SYSIN (FINIS"
"TSOEXEC CALL 'SYS1.LINKLIB(IEBCOPY)'"
"FREE FILE(SYSPRINT)"
"FREE FILE(SYSUT1)"
"FREE FILE(SYSUT2)"
"FREE FILE(SYSIN)"
RETURN
This is a superior method to using execio. You retain your ispf stats and conforms to jcl standards for copying data. Plus, you do not have memory constraints that execio has.
ReplyDeleteConsider duplicating this procedure to perform other iebcopy functions, such as pds compression.
Joseph Caughman
Naspa author and CBT contributer
Corrections to above:
DeleteIF MEMBER2 = '' THEN MEMBER2 = MEMBER1
QUEUE " SELECT MEMBER=(("MEMBER1","MEMBER2",R))"
RETURN SYSCMDRC