Passing symbol value using DFSORT to file - jcl

Statement: Earlier files were fetched from remote server location to mainframe. Then
those files content were get and saved at mainframe in a sequential file. But
sometime, some file names contained spaces. Due to this job fails while getting its
content.
Now to solve this problem, we fetched all files from server and separated good files
and bad files. Now we fetch only good file contents.
Problem: While renaming the files, we add prefix Process_ and Odate(fetched from Control M) to file name.
But earlier it was done in jcl as below through unix code.
Pseudo code:
print "rename " $1 " " "Process_" %%DAT "_" $1
We are fetching ODATE from a software control-M.
Jcl code:
//JOBNAME JOB (DEE),'Job Desc',CLASS=P,MSGCLASS=J,
// MSGLEVEL=(1,1),COND=(0,NE)
//* %%SET %%DAT = %%$ODATE
//STEP01 EXEC PROC1
PROC1 code:
//STEP02 EXEC PGM=SORT
//SORTIN DD DSN=DS.FILE1,
// DISP=SHR
//SORTOUT DD DSN=DS.FILE2,
// UNIT=SYSSF,
// DCB=(RECFM=FB,LRECL=80,BLKSIZE=0),
// SPACE=(27920,(29,6),RLSE),
// DISP=(NEW,CATLG,DELETE)
//SYSIN DD DSN=DS.PARM(PARM03),DISP=SHR
PARM03 contains:
Here I am creating unix code to rename file:
SORT FIELDS=COPY
OUTFIL BUILD=(1:C'print "get " r_fi',18:SEQNUM, -
3,ZD,22:C'" //DD:upload"',/,1:C'print "rename " r_fi', -
21:SEQNUM,3,ZD,24:C' ', -
25:C' " " "Process_" %%DAT "_" r_fi',53:SEQNUM,3,ZD,80:X)
/*
The unix code which I am creating dynamically:
Here depending on the number of files p_fi01, p_fi02, p_fi03..... is generated.
I am saving the unix code in a dataset and passing it as instream to run.
The problem is, it is not able to get the value in DAT variable.
Is there any way, I can pass the value of D from jcl to proc and append it with
"Process_" using sort card in proc.
Example data:
File File1.csv contents are fetched and then renamed as Process_20140101_File1.csv

Assuming that the rest of your code is OK, it is fairly simple with DFSORT, using JPn, which is a special DFSORT symbol which allows the separate values of up to 10 parameters to be used in control cards.
Here is an example:
// SET INPARM='ABC'
//*
//STEP0100 EXEC PGM=SORT,PARM='JP0"&INPARM"'
//SYSOUT DD SYSOUT=*
//SYMNOUT DD SYSOUT=*
//SORTOUT DD SYSOUT=*
//SYSIN DD *
OPTION COPY
INREC BUILD=(JP0)
//SORTIN DD *
IRRELEVANT DATA, JUST AN EXAMPLE
I have used SET to create a JCL symbol, but you have yours already from CONTROL-M, so just replace &INPARM on the PARM with your CONTROL-M symbol.
JPn means JP0 through JP9. Three separate pieces of data could look like this:
//STEP0100 EXEC PGM=SORT,PARM='JP0"&INPARM1",JP1"&INPARM2",JP2"&INPARM3"'
The SYMNOUNT DD is optional, but very, very useful, as it will show you the translated values of the symbols.
Assuming that the rest of your code is correct, you would make this change:
25:C' " " "Process_"',JP0,C'"_" r_fi',53:SEQNUM,3,ZD,80:X)
And include a PARM on the EXEC card, PARM='JP0"[yourControl-M-symbol]"'
SyncSort does not have JPn, so that is lucky for you that you have DFSORT. A different technique would be required for SyncSort.

Related

Is is possible to dump the contents of a JCL SYSOUT to a z/OS flat file?

I'm interested in knowing if it is possible to get the contents of a JCL SYSOUT into a z/OS flat file; either in the same JCL step or in a JCL step executed later in the same JCL.
Attention¡, I do not mean the other way round; which is generate the SYSOUT directy in a z/OS file and, after, in another JCL step dump it onto SYSOUT.
For example; in the following JCL step I'm interested in getting the contents of SYSOUT=2 in a flat file.
May anyone shed light in this issue?.
Many thanks in advance.
//WNMPRAD5 EXEC PGM=WNMPRAD5,COND=(4,LT)
//SYSPRINT DD SYSOUT=1
//SYSDBOUT DD SYSOUT=1
//ENTRADA DD DSN=WNMT.SCADUC.WGPT022.ZXDALMA.UNLDBI,DISP=OLD
//SORTIDA DD DSN=WNMT.SCADUC.WGPT022.ZXDALMA.OUTPUT.V02,
// DISP=(NEW,CATLG,DELETE),UNIT=DISK,
// DCB=(RECFM=FB,LRECL=278),
// SPACE=(27998,(2500,2500),RLSE)
//SYSOUT DD SYSOUT=2
//SYSIN DD *
N0100
/*
SYSOUT is no different than any other DD but is used by convention for output. You can create a DD like this in the STEP that creates the file:
//SYSOUT DD DSN=MY.SYSOUT,
// DISP=(NEW,CATLG,DELETE),UNIT=DISK,
// DCB=(RECFM=FBA,LRECL=133,BLKSIZE=0),
// SPACE=(27998,(2500,2500),RLSE)
The DCB will vary depending but 133 (assuming ASA character) is common. No need for a different step.
If you want, you could in a following step use IEBGENER to copy the Disk to another SYSOUT to store the contents in the JOB. Its not possible, as far as I know, to easily grab a SYSOUT in the next step and copy to disk.
Yes. You have to get the LRECL and RECFM correct, but you can get those from the source code to the program you're executing. Most standard reports are 133 and FB or 132 and FBA. I seem to remember IDCAMS was 121 and VBA.
//WNMPRAD5 EXEC PGM=WNMPRAD5,COND=(4,LT)
//SYSPRINT DD SYSOUT=1
//SYSDBOUT DD SYSOUT=1
//ENTRADA DD DSN=WNMT.SCADUC.WGPT022.ZXDALMA.UNLDBI,DISP=OLD
//SORTIDA DD DSN=WNMT.SCADUC.WGPT022.ZXDALMA.OUTPUT.V02,
// DISP=(NEW,CATLG,DELETE),UNIT=DISK,
// DCB=(RECFM=FB,LRECL=278),
// SPACE=(27998,(2500,2500),RLSE)
//SYSOUT DD DISP=(NEW,CATLG,DELETE),
// DSN=&SYSUID..STEPNAME.SYSOUT,
// AVGREC=K,
// LRECL=133,
// RECFM=FB,
// SPACE=(500,(10,10))
//SYSIN DD *
N0100
/*
Provide the disposition parameter and dataset name in the sysout. So, it will be something like
//sysout dd dsn=abc.xyz,disp=(as per your choice)

Syncsort - Write UNPAIRED records to SORTOUT file, and PAIRED records to PAIRED file

I'm able to save the UNPAIRED records to SORTOUT (this is what I want) using the following:
//SORT EXEC PGM=SORT,PARM='DYNALLOC=(SYSDA,255)'
//SORTMSGS DD SYSOUT=*
//SORTJNF1 DD DSN=FILE1,
// DISP=OLD,DCB=BUFNO=255
//SORTJNF2 DD DSN=FILE2,
// DISP=OLD,DCB=BUFNO=255
//SORTOUT DD DSN=FILEOUT,
// DISP=(NEW,CATLG,DELETE),
// UNIT=(SYSDA,59),
// SPACE=(CYL,(500,100),RLSE)
//SYSIN DD *
SORT FIELDS=COPY
JOINKEYS FILE=F1,FIELDS=(25,4,A,115,20,A,135,4,A,140,4,A,5,20,A)
JOINKEYS FILE=F2,FIELDS=(5,4,A,9,20,A,29,4,A,33,4,A,37,20,A)
JOIN UNPAIRED,F2,ONLY
but I need to save the PAIRED records to a separate file. I tried the following statement but the PAIRED records don't get saved in my PAIRED file:
//SORT EXEC PGM=SORT,PARM='DYNALLOC=(SYSDA,255)'
//SORTMSGS DD SYSOUT=*
//SORTJNF1 DD DSN=FILE.F1,
// DISP=OLD,DCB=BUFNO=255
//SORTJNF2 DD DSN=FILE.F2,
// DISP=OLD,DCB=BUFNO=255
//SORTOUT DD DSN=FILE.SORTOUT,
// DISP=(NEW,CATLG,DELETE),
// UNIT=(SYSDA,59),
// SPACE=(CYL,(500,100),RLSE)
//PAIRED DD DSN=FILE.PAIRED,
// DISP=(NEW,CATLG,DELETE),
// UNIT=(SYSDA,59),
// SPACE=(CYL,(500,100),RLSE)
//SYSIN DD *
SORT FIELDS=COPY
JOINKEYS FILE=F1,FIELDS=(25,4,A,115,20,A,135,4,A,140,4,A,5,20,A)
JOINKEYS FILE=F2,FIELDS=(5,4,A,9,20,A,29,4,A,33,4,A,37,20,A)
JOIN UNPAIRED,F2,ONLY
OUTFIL FNAMES=SORTOUT
OUTFIL FNAMES=PAIRED,SAVE
Edit 1: OP has mentioned (in the comments section of this answer), "I only want to keep the UNPAIRED records (F2 only) in my main SORTOUT dataset, and the PAIRED records (F2 only) in my PAIRED dataset." Paired records mean both F1 & F2. OP is basically looking for RIGHT JOIN. The SORT statements provided below are edited as per OP's requirement. Note that a REFORMAT statement is required unless a JOIN statement with the ONLY operand is specified.
You must use a method in Syncsort (which is called as indicator method in dfsort), to acheive what you're expecting. See below SORT statements.
SORT FIELDS=COPY
JOINKEYS FILE=F1,FIELDS=(25,4,A,115,20,A,135,4,A,140,4,A,5,20,A)
JOINKEYS FILE=F2,FIELDS=(5,4,A,9,20,A,29,4,A,33,4,A,37,20,A)
REFORMAT FIELDS=(F1:p,l,F2:p,l,?)
JOIN UNPAIRED,F2
OUTFIL FNAMES=BOTH,INCLUDE=(53,1,CH,EQ,C'B'),BUILD=(Build the columns you need from F1/F2)
OUTFIL FNAMES=UNPAIRED,INCLUDE=(53,1,CH,EQ,C'2'),BUILD=(Build the columns you need from F2)
where,
p - The position value indicates the first byte of the field relative to the beginning of the input record.
l - The length value indicates the length of the field.
Observe the ? in the REFORMAT FIELDS statement.
Quote from Syncsort for z/OS Programmer's guide:
?
This symbol is used to place a one-byte indicator in the reformatted
record that indicates whether the reformatted record is a paired or an
unpaired joined record. The indicator will be set to one of three
different printable values:
“B” if the reformatted record is a paired
record
“1” if the reformatted record is an unpaired record created
from the F1 file
“2” if the reformatted record is an unpaired record
created from the F2 file
More details:
Paired and unpaired F1/F2 records (indicator method).
Syncsort for z/OS Programmer's guide.
Hope this helps!

Adding amounts present in the character format

I have a PS with LRECL = 500 and RECFM=FB and in positions 70 through 82, I have the below amount fields in character format.
-000000042.99
-000000001.50
-000000003.00
-000000001.50
-000000042.99
+000000025.00
+000000019.52
+000000058.36
How can I convert this to Packed Decimal? My intention is I need to sum up the amounts field.Any ideas?
We have DFSORT. These amount fields are not in Packed decimal or numeric format. This file comes from an external system and I would like to sum all the amounts in this file through a JCL. I have to know the amount. For obvious reasons I do not wish to export this file to an excel and find the total there. I do not want to sum the totals based on a key. I just want to sum all the amounts in that file in that column.
//SORTA EXEC PGM=SORT
//SYSOUT DD SYSOUT=*
//SORTOUT DD SYSOUT=*
//SYSIN DD *
OPTION COPY
OUTFIL REMOVECC,
TRAILER1=(TOTAL=(1,13,SFF,
EDIT=(SIIIIIIIIT.TT),
SIGNS=(+,-),
LENGTH=13))
//SORTIN DD *
-000000010.10
-000000020.20
+000000005.88
Now I am getting the desired output
-000000010.10
-000000020.20
+000000005.88
-24.42
It is a simple task using OUTFIL and its reporting functions:
//TOTALREP EXEC PGM=SORT
//SYSOUT DD SYSOUT=*
//SORTOUT DD SYSOUT=*
//SYSIN DD *
OPTION COPY
OUTFIL REMOVECC,
TRAILER1=(TOTAL=(1,13,SFF,
EDIT=(SIIIIIIIIT.TT),
SIGNS=(+,-),
LENGTH=13))
//SORTIN DD *
-000000042.99
-000000001.50
-000000003.00
-000000001.50
-000000042.99
+000000025.00
+000000019.52
+000000058.36
SORTOUT contains:
-000000042.99
-000000001.50
-000000003.00
-000000001.50
-000000042.99
+000000025.00
+000000019.52
+000000058.36
+3.86
REMOVECC says don't include a printer Control Code, TRAILER1 is actioned at the end of the OUTFIL group, TOTAL (or TOT) says give a total of the position (here 1) length (13) and type (FS) (which you should look up in the DFSORT Application Programming Guide, which, for your version of DFSORT, can be found here: http://www-01.ibm.com/support/docview.wss?uid=isg3T7000080 . The EDIT, SIGNS and LENGTH dictate how the TOTAL value is going to appear.
UFF is Unsighed Free Format - This will strip out all non-numeric digits and process the result
SFF is Signed Free Format - This will strip out all non-numeric digits and process the result based on the presence, anywhere in the field, and that means anywhere, of one or more -If - is located, value will be negative otherwise positive.
FS
CSF These two are synonymous and can handle leading signs, but not decimal points. In the original example, the presence of the decimal point caused the number to be treated as only the decimal part. Everything in front of the decimal point was ignored, including the sign.

copy a member from one pds to another? using the jcl statement

How can i use the IEBGENER utilty to copy a member from one pds to another.
something similar to this:
//myjob job1
// exec pg=eibgener
??
don't know the the rest.
Assuming the output PDS has already been created and contains
sufficient space, you
could try something like:
//jobname your-jobcard-info
//stepname EXEC PGM=IEBGENER
//SYSUT1 DD DSN=input-pds(member),DISP=OLD
//SYSUT2 DD DSN=output-pds(member),DISP=OLD
//SYSPRINT DD SYSOUT=*
//SYSIN DD DUMMY
//*
I think IDCAMS REPRO is more commonly used for this sort of thing these days.
Most folks use IEBCOPY for copying members from one PDS(E) to another. Sample JCL is available by following the link.

Symbolic JCL Confusion

I am a bit confused on how to create a symbolic variable in JCL for an assignment I am doing in my COBOL class.
For example, I am supposed to "Specify a symbolic parameter for the PARM option and specify TEST and APOST as the default."
How do I designate the "PARM" option to be a symbolic parameter?
EDIT: Forgive the oversight; it seems that I forgot to mention what OS I am running in. I am writing this JCL file in z/OS.
Thanks in advance!
EDIT:
#avisser:
So, what you're saying is that I can just call it "&PARM='TEST,APOST'" and, if I wanted to change that parameter when I run this proc with another JCL statement, the parms listed can be changed from the calling JCL?
EDIT:
#avisser:
Yeah, sorry, I really need to work on being more specific... In my COBOL JCL, I am calling the COBOL compiler (IGYCRCTL), the Linkage Editor (HEWL) and a program fetch (EXEC PGM=).
EDIT:
Perhaps it would help to see what my output is. I really do appreciate all those who have tried to help so far.
Output:
------ JES2 JOB STATISTICS ------
37 CARDS READ
61 SYSOUT PRINT RECORDS
0 SYSOUT PUNCH RECORDS
3 SYSOUT SPOOL KBYTES
0.00 MINUTES EXECUTION TIME
!! END OF JES SPOOL FILE !!
1 //KC03CEFA JOB ,'MATT R',MSGCLASS=H,TYPRUN=SCAN JOB07731
//*
2 //STEP01 EXEC PGM=IGYCRCTL,&REGION=248K,
// &PARM='TEST,APOST'
3 //STEPLIB DD DSN=IGY340.SIGYCOMP,DISP=SHR
/*
4 //SYSLIN DD &DSN=&&OBJSET,UNIT=DISK,SPACE=(TRK,(3,3)),
// &DISP=(NEW,PASS,DELETE)
5 //SYSPRINT DD SYSOUT=*
6 //SYSUT1 DD UNIT=DISK,SPACE=(CYL,(1,1))
7 //SYSUT2 DD UNIT=DISK,SPACE=(CYL,(1,1))
8 //SYSUT3 DD UNIT=DISK,SPACE=(CYL,(1,1))
9 //SYSUT4 DD UNIT=DISK,SPACE=(CYL,(1,1))
10 //SYSUT5 DD UNIT=DISK,SPACE=(CYL,(1,1))
11 //SYSUT6 DD UNIT=DISK,SPACE=(CYL,(1,1))
12 //SYSUT7 DD UNIT=DISK,SPACE=(CYL,(1,1))
//*
//*
13 //STEP02 EXEC PGM=HEWL,&COND=,&REAGION=2048K,
// &PARM=
14 //SYSLIB DD DSN=CEE.SCEELKED,DISP=SHR
15 //SYSLIN DD &DSN=&&OBJSET,&DISP=(OLD,DELETE)
16 //SYSLMOD DD DSN=&&TEMPLIB(PGM6),
// SPACE=(1024,(50,20,1)),UNIT=DISK,
// DISP=(NEW,CATLG,DELETE)
17 //SYSPRINT DD SYSOUT=*
18 //PRINTER DD SYSOUT=*
19 //SYSUT1 DD UNIT=DISK,SPACE=(TRK,(10,10))
//*
//*
20 //STEP01 EXEC PGM=PGM6,&PARM=TERMTHDACT(DUMP)
21 //STEPLIB DD DSN=&&TEMPLIB,DISP=SHR
22 //CEEDUMP
23 //SYSUDUMP
24 //PRINTER DD SYSOUT=*
25 //PRODUCTS DD DSN=KC02322.CSCI465.SP09(DATA1),DISP=SHR
26 //SYSIN DD *
!! END OF JES SPOOL FILE !!
STMT NO. MESSAGE
2 IEFC630I UNIDENTIFIED KEYWORD &REGION
2 IEFC630I UNIDENTIFIED KEYWORD &PARM
4 IEFC630I UNIDENTIFIED KEYWORD &DSN
4 IEFC630I UNIDENTIFIED KEYWORD &DISP
13 IEFC630I UNIDENTIFIED KEYWORD &COND
13 IEFC630I UNIDENTIFIED KEYWORD &REAGION
13 IEFC630I UNIDENTIFIED KEYWORD &PARM
15 IEFC630I UNIDENTIFIED KEYWORD &DSN
15 IEFC630I UNIDENTIFIED KEYWORD &DISP
20 IEFC630I UNIDENTIFIED KEYWORD &PARM
22 IEFC605I UNIDENTIFIED OPERATION FIELD
23 IEFC605I UNIDENTIFIED OPERATION FIELD
!! END OF JES SPOOL FILE !!
symbolic parameters are names preceded by an ampersand. When used in a JCL statement, at runtime they get converted into the supplied value. One way of creating them (on z/OS) is using a
// SET name = value
declaration.
If you use a PARM, you should design your program so that it can work with one. Perhaps the assignment is about how to do that (hint: linkage section). Or is JCL a part of your COBOL class?
TEST and APOST look to me like compiler directives. I don't know if you can specify them in your program, at my workplace we only supply them when calling the compiler.
EDIT:
Ok this is a bit unusual to me, as we tend to compile and run our programs in separate JCL streams. But anyway.
Taking your second statement:
2 //STEP01 EXEC PGM=IGYCRCTL,&REGION=248K,
// &PARM='TEST,APOST'
REGION and PARM are so-called positional parameters and they are keywords, not really meant to be presented as symbolic names, although you're free to do so (this will explain the "UNIDENTIFIED KEYWORD" messages).
The common use - when applicable - is to provide symbolic names for the operands of
such parameters. And obviously you have to define a value for them first, e.g:
// SET OPTIONS='TEST,APOST'
//STEP01 EXEC PGM=IGYCRCTL,REGION=248K,
// PARM=&OPTIONS
Ok, I did some digging, and, with the guidance that avisser gave me, I was able to figure out what I had to do. So, for future reference for anyone who might have this question (or one similar), here is what I figured out:
Step 1: Create a "PROC" with the variables you will be using.
ex. I wanted to use variables for the "PARM" in my COBOL compiler that had the default values of "TEST" and "APOST", so I wrote something like:
//PROC1 PROC CPARM='TEST,APOST',
Step 2: Use those newly defined symbolic parameters in your actual JCL step. The "&" character shows that whatever follows it is a symbolic parameter.
ex. I used the aforementioned "CPARM" for my COBOL compile step:
//COB EXEC PGM=IGYCRCTL,REGION=&CREGION,
// PARM='&CPARM'
Step 3: End your "PROC" with a "PEND" statement after your actual step.
ex. After I listed all of my variables and I listed all the steps for compilation (compiler name, where the compiler can be found, and, as can be seen right before the PEND statement, the SYSUT1-SYSUT7 statements), place your PEND keyword:
//SYSUT7 DD UNIT=DISK,SPACE=(CYL,(1,1))
// PEND
Step 4: Add any additional JCL steps and/or code to your source file and you're off!
Notes:
-You can have more than one PROC statement in a single JCL file. I had three: one for COBOL compilation, one for the linkage editor and one for the program fetch. I also have COBOL code in the same file that my PROC statements are in.
-This took place on an IBM Mainframe running z/OS.
-Above, it can be seen that my "CPARM" variable is set to the default of 'TEST,APOST'. It is possible to have a variable be null by default by simply leaving the field blank (ex. CPARM=,).
-You may have noticed that after the CPARM definition, there is a comma; this is because I have more variables after it. Please remember that the last symbolic parameter you create for any given PROC should have nothing following it (ie. no comma). You can, of course, place a comment line (//*), another PROC or actual code afterward, but the last symbolic parameter should have nothing following it on the same line.