Converting Easytrieve Logic: Creating the Program Structure
Creating
the Program Structure
SORT to Another File with the Same Format
SORT not followed by JOB INPUT(file)
Selecting,
Reformatting, and Printing Data with SORT
Synchronized
File Processing - Merging 2 Files
Multiple
Jobs and PROCESS statements.
Step
1. Create data definitions
Step
2. Create Initial Program Structure
Step
3. Convert Logic for the First Process
Creating Separate Job Steps. Step 4: Creating Program MSAP901A
Step 5. Create
Program MSAP901B
Step 4A. Logic
of JOB INPUT(VIRCARD)
Converting
JOB and SORT statements
JazzUGEasytrieve provided just an initial
introduction to Easytrieve conversion. You will already have looked
at that Help page to get a basic understanding of the process of converting
Easytrieve to MANASYS Jazz and generating equivalent COBOL.
JazzUGEZTData gives detailed information about
creating Jazz definitions of the data
defined in Easytrieve programs. It deals with the conversion of the Easytrieve
“Library” – the part of the Easytrieve program from the beginning to the first SORT or JOB statement – where the
files and fields were defined – and also DEFINE and HEADING statements within the
body of your Easytrieve program.
Converting EZT data definitions into Jazz is a simple process that is
fully automated, and is the first stage of the three-stage EZT conversion
process.
Next you create an appropriate Jazz program to use this data, in two more stages. Stage 2 is to create the appropriate program
structure, which is the subject of this Help page, which concentrates on using
the dialog New/Logic/Batch program to create the appropriate program
structure. For this we’ll
focus on JOB and SORT statements. This may be all that
you need, as it may be sufficient to use the PRINT and COPY options to produce
the output that you require.
Usually however this is only the start. In all but the simplest
cases you’ll have logic within your program for
calculations, printing reports, etc that require your EZT logic within the JOB to be converted
to Jazz logic.
For this you will convert your EZT logic in chunks to Jazz
logic, using the Easytrieve Conversion Notepad.
This is Stage 3 of the EZT Conversion process, and the subject of the
next Help page, JazzUGEZTLogic2.
Finally, if your EZT program contains several JOB statements, then you
either need to create several separate programs and link them through JCL, or
create a program with several PROCESS statements. Dealing with this is described in Multiple Jobs and PROCESS statements.
This
section deals with creating a program structure to deal with a single JOB statement, and the
related SORT if there is one, using
Logic/Batch Program to create a program of the right structure as we did
in JazzUGEasytrieve.htm. Once
the program structure has been created, use the techniques discussed in JazzUGEZTLogic2 to
convert EZT logic into Jazz logic and insert it into
your program.
If
the Easytrieve program contains one JOB statement,
then it will become one Jazz program, but if
it contains several JOB statements then
you might create one or several programs.
See Multiple Jobs later to see how we deal
with these situations.
External tables are EZT tables that can be
searched once they have been loaded with data from an external source. They are described here. MANASYS will automatically
create logic to load these tables if they follow the format shown below. Each external table will have type ETABLE, and be immediately followed by the load file definition. Here is an example: -
DEFINE TABL1 ETABLE DATA(
GROUP1(20)
GROUP,
ARG CHAR(4) TKEY,
DESC CHAR(10),
END GROUP);
DEFINE JZTABL1 FB DATA(
ARG CHAR(4),
FILLER CHAR(1),
DESC CHAR(10)) DDNAME 'TABL1' DSNAME 'JAZZUSR.FILES.JZTABL1';
The ARG value will have property TKEY for small tables, and SKEY for large tables. Large or
small is defined by Configure/COBOL/Use Binary Search, which has a default of
50. TABL2, with 150 occurrences, will
have used property SKEY.
When the Logic/Batch Program recognizes this
pattern, it will generate the following code.
1. At the beginning of the program,
PERFORM LOAD-TABL1;
2.
At
the *#Copy Routines here ==> marker it will
generate a routine like this: -
ROUTINE LOAD-TABL1;
PROCESS
JZTABL1 COUNT JZ2.IXLD SID(27);
IF JZ2.IXLD>20;
DISPLAY('Table Limit(20) Exceeded. Load
TABL1 Terminated)');
COBOL.RETURN-CODE =
8;
CLOSE JZTABL1;
EXIT LOAD-TABL1;
END IF;
TABL1.GROUP1.ARG(JZ2.IXLD)=JZTABL1.ARG;
TABL1.GROUP1.DESC(JZ2.IXLD)=JZTABL1.DESC;
END
PROCESS JZTABL1;
CLOSE
JZTABL1;
JZ2.IXLD+= 1;
FOR
JZ2.IXL2 =
JZ2.IXLD TO 20;
TABL1.GROUP1.ARG(JZ2.IXL2) = HIGH-VALUES;
END
FOR;
END ROUTINE LOAD-TABL1;
For TABL2, with ARG CHAR(4) SKEY, caused
by 150 occurrences, ROUTINE LOAD-TABL2 is the same as above
except with 150 instead of 20, and
PROCESS JZTABL2 ORDER(JZTABL2.ARG) COUNT JZ2.IXLD SID(44);
This allows Jazz SEARCH to generate COBOL SEARCH ALL … The binary search logic of SEARCH ALL would not work unless the table is ordered in ascending order of ARG.
JOB INPUT
(VIRTFLE) START INIT FINISH LAST-REC
Start with the dialog
New/Logic/Batch, and give details like this: -
We have
checked Enable EZT Conversion, and given the names of the Start and Finish
procedures, we have not checked Order. Click [Finish] and this Jazz program is generated: -
PROGRAM Batch1 BATCH EZT;
* You may need to edit these statements
COPY VIRTFLE;
*# Copy Files here ==>
PERFORM INIT;
PROCESS VIRTFLE;
#346 W DSNAME option missing
*#Copy Process logic here ==>
END PROCESS VIRTFLE;
PERFORM LAST-REC;
*#Copy Routines here ==>
#476 S No ROUTINE for PERFORM LAST-REC
#476 S No ROUTINE for PERFORM INIT
Notes
1. The PROGRAM statement has the option EZT. This will make the Easytrieve Conversion
Notepad available, which we will use in Converting Easytrieve
Logic to Jazz Logic.
2. The program contains
markers *# Copy Files here ==>, *#Copy Process logic here ==>, and *#Copy Routines here ==> that show where any
further code should be placed
3. Because the dialog named
INIT and LAST-REC as the Start and Finish procedures, PERFORM statements are placed before and after the PROCESS loop. These procedures don’t exist yet, so message #476 is produced.
In this first example we haven’t checked any of ORDER[ ], WHERE[ ], and PRINT[ ].
As you’ll see later, we can check any or all of
these. We’ll
check WHERE when we want to process only some records, and we’ll
check ORDER if the records are needed in a different sequence. Also, we can check PRINT if we want to print
the records.
Checking any of these checkboxes
will invoke a dialog where we select the relevant fields. Thus by checking
PRINT we can print our data without having to convert the EZT REPORT
statements. The resulting printout is
displaying with the default MANASYS Jazz rules, not following the rules of your
EZT program, but this is a useful option if the precise report layout doesn’t matter to you.
If we want a copy of the input
record simply give a file name as Copy To.
The data read by our program, selected by WHERE if that’s
checked, and sequenced by ORDER if that’s checked,
will be written to this file. It we defined the file already then
the record format may change, but if we checked LIKE then the file is created
with exactly the same layout as the input (VIRTFLE).
If JOB is
preceded by SORT,
then the SORT becomes
an ORDER option of the PROCESS statement. It does not create a
separate PROCESS.
SORT VIRTFLE TO VIRTFLE USING +
(V-PT
V-COMP V-CENTER V-DATE V-EXTRA V-ACCOUNT)
JOB INPUT
(VIRTFLE) FINISH LAST-REC
The New/Logic/Batch dialog is as
above, except that we’ve checked
Order. In this case there’s no
Start procedure: -
Now, when we click [Finish], a
Select Data dialog appears, asking us to choose fields from
VIRTFLE. We locate fields V-PT, V-COMP etc in left to right
order. With each file we are asked whether we want descending order,
and whether we want the field to be used as a control
break. Here we’ve selected V-PT
with BREAK, and we’re selecting V-Comp without
break. Note that the fields that we seek may be within a Group, as
the definition may have needed redefinitions to convert the original Easytrieve
definition to a Jazz structure that is
compatible with COBOL. With the selection completed, here is the
generated program: -
*# Last Updated by Jazzusr at 24/01/2022 11:46:47 am
PROGRAM MSAB91C BATCH EZT;
* You may need to edit these statements
COPY VIRTFLE;
*# Copy Files here ==>
PROCESS VIRTFLE ORDER(VIRTFLE.V-PT,VIRTFLE.V-COMP,VIRTFLE.V-CENTER,VIRTFLE.V-DATE,VIRTFLE.V-EXTRA,VIRTFLE.V-ACCOUNT);
#346 W DSNAME option missing
*#Copy Process logic here ==>
END PROCESS VIRTFLE;
PERFORM LAST-REC;
*#Copy Routines here ==>
#476 S No ROUTINE for PERFORM LAST-REC
If the SORT copies the file in the same format, then
there is no need for both files. For example
SORT CARDFLE TO INFILE USING (C-COMP C-DATE
C-ACCOUNT-FULL C-CENTER +
C-DR-CR)
JOB
INPUT(INFILE)
Here CARDFLE and INFILE have the
same formats, and there are fields named I-COMP etc with the same
format and position. There is no need to create a copy of CARDFLE just to read
it back again, a better way to handle this is to treat this as if the SORT were like the
previous example,
SORT INFILE TO INFILE USING (I-COMP
…
resulting
in a program with
PROCESS INFILE ORDER(INFILE.I-COMP,…
The
Jazz program will be more efficient than the original Easytrieve, as only the
data required by the program (the sort fields and any other fields used in the
program) will be passed through the sort.
Sometimes the relevant logic
precedes it. An EZT program contained
logic
SORT TEMP
TO TEMP USING TF1-REC
JOB INPUT
NULL NAME(GENERATE-REPS)
PERFORM
L1AA-START
…
Here there is no file, so there’s no process loop to which an ORDER option can be
applied. However in this case the SORT statement was
preceded by logic creating TEMP
GET INFILE
DO WHILE NOT EOF INFILE
IF IP2-ORIG-ID = WP-ORIG-ID
PUT TEMP FROM INFILE
END-IF
GET INFILE
END-DO
STOP
*
SORT TEMP
TO TEMP USING TF1-REC
This had
been converted into
PROCESS INFILE SID(45) WHERE INFILE.IP2-ORIG-ID = EZT-AAP21BE-Data.WP-ORIG-ID;
WRITE TEMP FROM(INFILE);
#378 W Batch WRITE used - you may need to edit the JCL
END PROCESS INFILE;
INFILE and TEMP both defined 200 byte records, and fields IP2-REC and TF1-REC are the whole
INFILE and TEMP records respectively. We simply add
ORDER IP2-REC
to this PROCESS statement,
and now
PROCESS INFILE SID(45) WHERE INFILE.IP2-ORIG-ID = EZT-AAP21BE-Data.WP-ORIG-ID ORDER(INFILE.GROUP1.IP2-REC);
WRITE TEMP FROM(INFILE);
#378 W Batch WRITE used - you may need to edit the JCL
END PROCESS Infile;
creates TEMP in the correct
sequence. PROCESS conditions
are applied to INPUT so only the records we want are written to the SortWork files. We have eliminated the need for a
separate SORT, and this is more efficient than the EZT logic.
SORT is also used to select data, and sometimes to
reformat it. In Easytrieve, to sort only
some records or to modify the data you must write a SORT procedure. For example
FILE PERSNL FB(150 1800)
EMPNAME 17 16 A
DEPT 98 3 N
GROSS 94 4 P 2
FILE PAYSORT F(120) VIRTUAL
SORT-NAME 17 16 A
SORT-DEPT 98 3 N
SORT-GROSS 94 4 P 2
JOB INPUT PERSNL NAME ACT-1
SORT PERSNL TO PAYSORT USING (DEPT GROSS
D) +
BEFORE SELECT-REC NAME SORT-ACTIVITY
SELECT-REC. PROC
IF GROSS GE 500
SELECT
END-IF
END-PROC
JOB INPUT PAYSORT NAME ACT-2
PRINT RPT1
REPORT RPT1
LINE 1 SORT-NAME SORT-DEPT SORT-GROSS-PAY
This
seems very complicated. In Jazz, data selection is simply a matter
of adding a WHERE condition to the PROCESS statement (whether or not it
includes ORDER). And there is no need
to reformat data: MANASYS logic will recognize when only part of the record is
required and a shorter Sortwork record will
be created to maximize sort efficiency. Thus, to create the
equivalent program, we start with New/Logic/Batch, naming file PERSNL and
checking Order and Where. We also check Print. Each checkbox will result in a dialog where
we select the relevant fields or values: -
[Finish]
triggers various Select Data dialogs. First it opens in condition
mode to resolve the WHERE condition PERSNL.? = ? We select Gross: -
On
the next SELECT we don’t actually
select anything; we just type 500 into the output line and click
[Finish]. Note that we have now created a condition “WHERE GROSS =
500”, which is not quite what we want. We’ll edit
this later: -
Next Order.? triggers another Select Data
dialog. We select DEPT (with Break), and Gross (Descending, not
break).
Because
we checked Print, MANASYS has inserted PRINT (PERSNL.?) into the PROCESS loop. PERSNL.? triggers yet another Select Data dialog,
and we select the data that we want, in the order we want the fields printed
across the page.
After
all this selection, the following program results: -
PROGRAM RPT1 BATCH EZT;
* You may need to edit these statements
COPY PERSNL;
*# Copy Files here ==>
PROCESS PERSNL WHERE(PERSNL.GROSS = 500) ORDER(PERSNL.DEPT BREAK,PERSNL.GROSS DESC);
*#Copy Process logic here ==>
COPY JZSMth;
PRINT (PERSNL.GROUP1.EMPNAME,PERSNL.GROUP1.DEPT,PERSNL.GROUP1.GROSS) ;
END PROCESS PERSNL;
*#Copy Routines here ==>
It
needs editing: -
1. The condition is wrong:
Change = to >=.
2. Add SUM to PERSNL.GROSS
3. (Optional) remove
unwanted comments.
Here
is the edited program, with our editing changes highlighted. It is equivalent to the Easytrieve
program above, but more efficient as the equivalent of PAYSORT is only 23
bytes, not 120. And because we’ve used the
build-in PRINT logic of MANASYS Jazz, we don’t need to convert the printing logic of the EZT
program. The report layout will follow
default MANASYS standards so it will look different to the report that the EZT
program produced, but it will contain the same information.
PROGRAM RPT1 BATCH;
COPY PERSNL;
PROCESS PERSNL WHERE(PERSNL.GROSS >= 500) ORDER(PERSNL.DEPT BREAK,PERSNL.GROSS DESC);
COPY JZSMth;
PRINT (PERSNL.EMPNAME,PERSNL.DEPT,PERSNL.GROSS SUM) ;
END PROCESS PERSNL;
In
Easytrieve you may see code like this: -
JOB INPUT NULL
PRINT LISTE2
STOP
REPORT LISTE2 LINESIZE 80 SPACE 4 PRINTER LISTEX
TITLE 'CONTROL TOTALS'
LINE 1 TOTAL1 TOTAL2 TOTAL3
INPUT NULL inhibits automatic input, and creates logic that
will execute until terminated with STOP. Here the logic
is PRINT LISTE2, which prints data that has been accumulated in the
preceding JOB, a typical use of INPUT NULL. The logic
of LISTE2 is basically a single LINE statement with a
report TITLE, equivalent to a Jazz PRINT statement and a REPORT defined with a HEADING. Convert the
Easytrieve Report logic to Jazz (see Converting Easytrieve
Logic to Jazz Logic), and then put the PRINT statement into the Jazz program so that it follows
the PROCESS loop. If
there is a Finish procedure, it may be convenient to put the PRINT into this.
If JOB
INPUT NULL is
the only JOB statement, then you can generate a program
without a PROCESS loop by setting INPUT to
NULL in this
dialog: -
This
will result in a Jazz program structure like this, in
which the normal PROCESS loop is replaced with a FOR loop: -
*# Last Updated by
11JAZZUSR at 29/04/2024 11:13:20 AM
PROGRAM Test1
BATCH EZT;
COPY EZT-Test-DATA;
*# Copy Files here
==>
#762 W COPY code
produces 133 W and 0 I messages
FOR JZ2.IXNULL
= 1 UNTIL JZ2.FLAGNull;
*#Copy Process logic
here ==>
END FOR;
#783 W FOR loop may
not terminate
*#Copy Routines here
==>
This allows you to continue converting the logic of the JOB
INPUT NULL section. If you use
the logic FOR JZ2.IXNULL = 1 … that is
converted from JOB INPUT NULL, remember
that it is now up to you to ensure that the FOR loop terminates. You can do this by adding an UNTIL option on
either the FOR or
END
statements, or using an EXIT FOR; statement within the FOR loop.
However, don’t
just convert the EZT statements line-by-line without thinking about what you’re really trying to achieve. There are often better alternatives with
logic following JOB INPUT NULL. For example, an EZT GET statement may be
used read records sequentially, but GET is not converted
to Jazz GET because they have a different
meaning. GET is the equivalent of READ, and is used for direct
lookup of a VSAM or SQL record. This logic reads the first or only record from FTPIN.
JOB INPUT NULL
GET FTPIN
W-COUNT = I-RECORD
IF W-COUNT NE 12
RETURN-CODE = 12
END-IF
STOP.
Instead
of simply accepting JOB INPUT NULL, which generates FOR/END FOR
logic, handle this as usual with a PROCESS loop, but use EXIT to ensure that it
only reads one record.
PROCESS FTPIN COUNT JZ.IX1;
EZT-EZT1-Data.W-COUNT = FTPIN.I-RECORD;
IF EZT-EZT1-Data.W-COUNT <> 12;
JZ.RETURN-CODE = 12;
END IF;
END PROCESS FTPIN EXIT JZ.IX1 > 0;
JOB may specify two files, for
example
JOB INPUT(FILE1
KEY KEY1A +
FILE2 KEY
KEY2A)
Easytrieve
calls this “Synchronized File Processing”. The
two files, which must be in ascending order of their sequence keys, are merged
and processed together. You can handle this with MANASYS by creating
a Merge Process with the New/Logic/Batch Program dialog. Click the [Merge]
button and a panel appears where you name the second file and define the
sequence keys. These dialog settings produce the program structure that you
want for the JOB statement above: -
Click [Finish] and MANASYS
produces this Jazz program: -
PROGRAM Batch BATCH EZT;
COPY FILE1;
*# Copy Files here ==>
COPY FILE2;
PROCESS FILE1 MERGE FILE2 SKEYS (FILE1.KEY1A,FILE2.KEY1B) SID(20);
*#Copy Process logic here ==>
END PROCESS MERGE;
*#Copy Routines here ==>
If the purpose of the JOB is to
produce an output file that is a copy of FILE1 then name the file in Copy To: -
Now [Finish] adds COPY options to
the PROCESS and END PROCESS statements.
PROGRAM Batch BATCH EZT;
COPY FILE1;
DEFINE FILEOUT LIKE FILE1;
#492 I DSNAME 'JAZZUSER.FILES.FILEOUT'
*# Copy Files here ==>
COPY FILE2;
PROCESS FILE1 MERGE FILE2 SKEYS (FILE1.KEY1A,FILE2.KEY1B) COPY FILEOUT SID(21);
*#Copy Process logic here ==>
END PROCESS MERGE COPY FILEOUT;
*#Copy Routines here ==>
You
can write update logic within the loop, like
IF JZ.$CMergeOut = 0;
FILEOUT.BALANCE += FILE2.Payment;
END IF;
$CMerge and $CMergeOut are two Jazz fields
defining the result of a merge comparison. $CMerge compares FILE1 and FILE2, $CMergeOut compares FILEOUT and FILE2. 0 means that the two
files are equal, positive values mean that the key of the first file (FILE1.KEY1A) is higher than the key of the second file (FILE2.KEY1B), and negative values mean the
reverse. Updated FILEOUT records, including new records where
a FILE2.KEY1B value does not equal
any FILE1.KEY1A value, are written by END PROCESS MERGE COPY FILEOUT; when the value of FILEOUT.KEY1A changes.
For more information on merge
processing, and especially if this is your first MANASYS Jazz merge program,
see JazzUGMerge. .
For Merge (Synchronised
Processing) to work, the input files must already be in the correct
sequence. This may require one or both of the
files to be sorted before the merge. This is easy: just
check SORT when creating the program. For example, from
SORT
PERSNL TO SORTPER USING OLD-EMP#
JOB INPUT
(SORTPER KEY(UPD-EMP#) +
PERSUPD KEY(EMP#) )
we create a process merging PERSNL
with PERSUPD. PERSUPD is not sorted, so it must already be in the
correct order: -
Click [Finish]. This
program results: -
PROGRAM Sample2 BATCH EZT;
COPY EZT-Sample2-DATA;
DEFINE NEWPERS LIKE PERSNL;
#031 S Level 1 name NEWPERS already
exists
*# Copy Files here ==>
DEFINE IPERSNL
LIKE PERSNL MERGESORT;
DEFINE
PERSUPD-SEQCHECK DATA(
EMPNbr LIKE PERSUPD.GROUP1.EMPNbr);
PROCESS PERSNL SORT MERGE Persupd SEQCHECK SKEYS (PERSNL.OLD-EMPNbr,PERSUPD.EMPNbr) COPY Newpers SID(22);
#346 W DSNAME option missing
#263 S Definition inserted for IPERSNL. Click CHECK
again
#263 W Definition inserted for PERSUPD-SEQCHECK. Click
CHECK again
*#Copy Process logic here ==>
END PROCESS MERGE COPY NEWPERS;
*#Copy Routines here ==>
Right-click COPY and
edit EZT-Sample2-DATA: -
1 Remove the original definition of Newpers. COPY requires that
the file is defined LIKE the input file, and message #031 results because the old
definition is still present
2 Remove SORTPER – it is not wanted, as this program will
read PERSNL as the sorted file. The original unsorted file is read as IPERSNL.
3 Add DSNAME options
to the remaining files to avoid message #346, and to allow MANASYS to generate
JCL to run the job.
Click [Check] again: -
PROGRAM Sample2 BATCH EZT;
COPY EZT-Sample2-DATA;
DEFINE NEWPERS LIKE PERSNL;
#492 I DSNAME 'JAZZUSR.FILES.NEWPERS'
*# Copy Files here ==>
DEFINE IPERSNL LIKE PERSNL MERGESORT;
#492 W DSNAME FOR PERSNL changed to
&&PERSNL
#492 I DSNAME 'JAZZUSR.FILES.PERSNL'
DEFINE PERSUPD-SEQCHECK DATA(
EMPNbr LIKE PERSUPD.GROUP1.EMPNbr);
PROCESS PERSNL SORT MERGE PERSUPD SEQCHECK SKEYS (PERSNL.OLD-EMPNbr,PERSUPD.EMPNbr) COPY Newpers SID(22);
*#Copy Process logic here ==>
END PROCESS MERGE COPY NEWPERS;
*#Copy Routines here ==>
In the generated program the PROCESS logic will be
preceded with a SORT using IPERSNL giving PERSNL, which is now a temporary data
set that is in the correct sequence. We now have the
correct program structure so we’re ready for
Stage 3, handling the actual logic of the EZT Job.
There are significant differences
between Jazz and Easytrieve logic. Most importantly,
1. Records are automatically written out at END PROCESS MERGE COPY whenever
the key of the output record (FILEOUT.KEY1A) changes,
unless JZ.COPY-WANTED = false; has been
executed. Instead of deciding when to write a record and executing
a WRITE statement,
we will need logic to set COPY-WANTED = false when we DON’T want a record to be written.
2. EZT synchronized file processing has a
number of special conditions – IF MATCHED, IF DUPLICATE, IF
filename (e.g. IF PERSNL, IF
PERSUPD). These are usually replaced
by $CMerge or $CMergeOut tests: -
· IF MATCHED becomes IF $CMergeOut = 0;
· IF PERSNL (1st file) becomes IF $CMergeOut > 0;
· IF PERSUPD (2nd file) becomes IF $CMergeOut > 0;
· IF DUPLICATE is essentially the same in Jazz, but DUPLICATE condition
testing may give different results.
· Some options (like FIRST-DUP) have no
direct equivalent in Jazz either because they are unnecessary, or are replaced
by $CMerge or $CMergeOut tests.
For
more information about these conditions, see https://www.jazzsoftware.co.nz/Docs/JazzLRMConditions.htm
3. Jazz reports must be printed in the order
of their containing PROCESS loop,
which for PROCESS MERGE must
be ascending order of the SKEY fields. If
a report is printed in a different sequence (EZT SEQUENCE statement) then the relevant PRINT statement
is replaced with logic that writes to a work file, which is then read with
PROCESS Workfile ORDER(sequence field) REOPEN;
See MERGE Example 1 and MERGE Example 2 below for
examples of converting EZT synchronized file processing logic to Jazz PROCESS MERGE programs.
See https://www.jazzsoftware.co.nz/Docs/JazzUGmerge.htm for
more details on PROCESS MERGE logic,
Your EZT
program may contain several JOB statements, or it might contain include
loop logic that you convert into a PROCESS statement. Whatever the reason, you are going to end up
with Jazz logic with 2 or more PROCESS statements. There are two ways of handling this: -
a.
You
can create several separate Jazz programs and combine
these into a single run unit with JCL (z/OS) or a script (other operating
systems). Advantages are
i.
Each
step is cleanly separated
ii.
Files
are automatically opened and closed with each step
iii.
Each
step has available the full resources allocated to the job stream.
b.
You
can create a single program
i.
Everything
is kept together
ii.
It’s easy for one PROCESS to
calculate data that is used by a later logic
iii.
You
don’t have to edit the JCL to create multiple jobs
iv.
If
one PROCESS reads data written out earlier in the same program, then the PROCESS should use REOPEN, as in
PROCESS Workfile ORDER(sequence field) REOPEN;
You will
create a single program if a later PROCESS depends
on data calculated earlier in the program, otherwise passing the data from one PROCESS to another can be complicated. If no data is passed from one process to
another, you can choose either approach.
This program
is converted from 1411 lines of EZT.
Essential features of this EZT are shown here: -
FILE CARDFLE DISK F 180
…
FILE INFILE VIRTUAL FB(180
FULLTRK)
…
FILE VIRCARD VIRTUAL FB(180
FULLTRK)
…
FILE VIRTFLE VIRTUAL FB(181
FULLTRK)
…
SORT CARDFLE TO INFILE USING (C-COMP C-DATE
C-ACCOUNT-FULL C-CENTER +
C-DR-CR)
*
JOB INPUT(INFILE)
… Logic with
several PUT VIRCARD statements
…
JOB INPUT(VIRCARD)
…
Followed by several PROCs, many of which contain
PUT VIRTFLE
…
SORT VIRTFLE TO VIRTFLE USING +
(V-PT
V-COMP V-CENTER V-DATE V-EXTRA V-ACCOUNT)
JOB INPUT (VIRTFLE) FINISH LAST-REC
…
PRINT
HO-REPORT
…
REPORT HO-REPORT PRINTER REPORT1 DTLCTL EVERY SUMCTL
NONE NOADJUST
TITLE 1 'SCHEDULE OF INPUT FOR MSA GENERAL LEDGER -
MSAB910.'
LINE 1 O-RECORD-PRT
END
The first
three steps are the same, whichever approach we are going to take.
Dialog
New/Data/Import from Easytrieve creates EZT-MSAB910-DATA, containing all the
data definitions required
The first
EZT logic is
SORT CARDFLE TO INFILE USING (C-COMP C-DATE
C-ACCOUNT-FULL C-CENTER +
C-DR-CR)
JOB
INPUT(INFILE)
We use the
dialog New/Logic/Batch
When the
ORDER dialog prompts us we select fields like I-COMP
that are equivalents of C-COMP in CARDFLE.
The following program results.
*# Last Updated by
JAZZUSR at 8/08/2023 5:40:24 PM
PROGRAM MSAB910
BATCH EZT;
COPY EZT-MSAB910-DATA;
*# Copy Files here
==>
PROCESS INFILE
ORDER(INFILE.I-COMP,INFILE.I-DATE,INFILE.I-ACCOUNT-FULL,INFILE.I-CENTER,INFILE.I-DR-CR) SID(22);
*#Copy Process logic
here ==>
END PROCESS
INFILE;
*#Copy
Routines here ==>
We are never going to use the CARDFLE definition so we edit EZT-MSAB910-DATA to remove it.
Click
[EZT Conv] and convert the EZT logic following JOB
INPUT(INFILE) to SORT
VIRTFLE, not including
the JOB or SORT statements, and insert it into the Jazz
program. This was done in several
chunks, resulting in about 100 lines of Jazz code
being inserted at the *#Copy
Process logic here ==>
marker.
*# Last Updated by
JAZZUSR at 8/08/2023 5:40:24 PM
PROGRAM MSAB910
BATCH EZT;
COPY EZT-MSAB910-DATA;
*# Copy Files here
==>
PROCESS INFILE
ORDER(INFILE.I-COMP,INFILE.I-DATE,INFILE.I-ACCOUNT-FULL,INFILE.I-CENTER,INFILE.I-DR-CR) SID(22);
About 100 lines of Jazz code here, including
many WRITE VIRCARD; statements
*#Copy Process logic
here ==>
END PROCESS
INFILE;
*#Copy
Routines here ==>
As files are referenced message #346 will appear: -
#346 W DSNAME option missing
For INFILE, give the DSNAME to find CARDFLE. For VIRCARD, which is just a temporary file
passed from one step to the next, write DSNAME '&&VIRCARD';
to suppress message #346. When you’ve completed Jazz program
MSAB910, Process it to generate COBOL, and compile the
COBOL. Do not compile-and-run, but save
the generated JCL for the run step, which will be like this without the
definition for //CARDFLE as we removed it from EZT-MSAB910-DATA.
//JAZZUSER JOB ,CLASS=A,MSGCLASS=A
//GO EXEC PGM=MSAB910,TIME=(0,10)
//SYSOUT DD SYSOUT=*
//PRTERR DD SYSOUT=*
//SNAP DD SYSOUT=* USED BY JZSTXIT
//* Inserted DD statements based on program
//INFILE DD DSNAME=JAZZUSR.FILES.INFILE,DISP=SHR
//VIRCARD DD DSNAME=&&VIRCARD,DISP=(NEW,PASS)
//VIRTFLE DD DSNAME=&&VIRTFLE,DISP=(NEW,PASS)
//OUTPUT1 DD DSNAME=&&OUTPUT1,DISP=(NEW,PASS)
At
this stage we have a program that reads INFILE and writes VIRCARD. Now we have to make a decision: do we deal with the rest of the program by
creating separate job steps that we’ll link together
through JCL, or do we create a single program?
If the logic of this first stage saves any data in working storage, such
as a record count or saved or accumulated values of field values, then we’ll have to create a single program, but if not we can choose either approach.
First,
here’s how we’d manage this
conversion as a series of separate job steps.
If
we are going to implement EZT program MSAB901 as three separate job steps we
leave it here, and create program MSAB901A in the same way as we’ve just created MSAB901, but using the EZT logic from
JOB INPUT(VIRCARD)
…
Followed by several PROCs, many of which contain
PUT VIRTFLE
…
We
don’t need to recreate the data definition again as
MSAB901A. Instead
we use the New/Logic/Batch program as before, with name MSAB901A. As soon as we check [ü]
Enable EZT Conversion, the dialog inserts Copy Book name EZT-MSAB901A-DATA. Edit this to EZT-MSAB901-DATA, and set the
Input File to VIRCARD: -
This creates a program
outline like program MSAB901 created in Step 2. Create Initial Program Structure
PROGRAM MSAB910A
BATCH EZT;
COPY EZT-MSAB910-DATA;
*# Copy Files here
==>
PROCESS VIRCARD
SID(21);
*#Copy Process logic
here ==>
END PROCESS
VIRCARD;
*#Copy
Routines here ==>
Now we click [EZT Conv]
and use the Easytrieve conversion notepad to convert the logic following
JOB
INPUT(VIRCARD)
IF ACCOUNT = 5000 +
to the statement preceding the first PROC
END-IF
NEWPAGE
***********************************************************************
PROCESS-TWO. PROC
NOTE: if the highlighted EZT statement IF ACCOUNT = 5000 + corresponds
to the highlighted END-IF that is the end of the JOB logic then you should edit the
generated Jazz code to remove the Jazz IF statement, and make it’s condition a WHERE option of the PROCESS. This can be significantly
more efficient than the code directly converted from EZT, especially if the JOB is preceded by a SORT. However here the IF and END-IF DO NOT
correspond.
There’s a lot of logic here, so you’ll do this in chunks, as large or small as you wish provided that you convert complete logic units: e.g. if you
convert an IF statement, you should convert all the code down to (and
including) the matching END-IF.
Within this logic there are many PERFORM statements
referring to PROCs like PROCESS-TWO, so you’ll
now have a lot of error #476 messages like
#476
S No ROUTINE for PERFORM PROCESS-ASSESSORS-TRANSFER
You
can now convert these routines by converting all of
the code from (and including)
PROCESS-ASSESSORS-TRANSFER.
PROC
to END-PROC.
These
routines include many PUT
VIRTFLE
statements that become Jazz
WRITE VIRTFLE;
statements causing message #346
#346
W DSNAME option missing
We can see that this EZT program has
a third JOB, which processes VIRTFLE: -
SORT VIRTFLE TO VIRTFLE USING +
(V-PT V-COMP
V-CENTER V-DATE V-EXTRA V-ACCOUNT)
JOB INPUT (VIRTFLE) FINISH LAST-REC
so we know that VIRTFLE is a temporary
file. We get rid of the unwanted #346
messages by adding DSNAME '&&VIRTFLE';
to its definition in EZT-MSAB910-DATA.
When the logic for Jazz
program MSAB910A is completed, it is processed to produce COBOL and JCL, and
the COBOL is compiled,
As before, don’t compile-and-run. Save the JCL, which will be something like
this: -
//*** Run BATCH PROGRAM in IDE with Micro Focus Enterprise
Developer
//JAZZUSER JOB ,CLASS=A,MSGCLASS=A
//GO EXEC PGM=MSAB910A,TIME=(0,10)
//SYSOUT DD SYSOUT=*
//PRTERR DD SYSOUT=*
//SNAP DD SYSOUT=* USED BY JZSTXIT
//* Inserted DD statements based on program
//INFILE DD DSNAME=JAZZUSR.FILES.INFILE,DISP=SHR
//VIRCARD DD DSNAME=&&VIRCARD,DISP=(NEW,PASS)
//VIRTFLE DD DSNAME=&&VIRTFLE,DISP=(NEW,PASS)
//OUTPUT1 DD DSNAME=&&OUTPUT1,DISP=(NEW,PASS)
Repeat these steps to create another
program for the third step. First create
program MSAP901B with
With the outline of program MZAP901B
created, using the logic following
SORT VIRTFLE TO VIRTFLE USING +
(V-PT
V-COMP V-CENTER V-DATE V-EXTRA V-ACCOUNT)
JOB INPUT (VIRTFLE) FINISH LAST-REC
to the first PROC
statement to fill in the basic Jazz logic. Then convert all missing PROCs until there are no more #476 messages.
Now process the Jazz program
MSAP901B to produce COBOL. Compile the
COBOL and save the JCL. Do not
compile-and-run.
At this stage we’ve
successfully generated and compiled programs MSAP901, MSAP901A, and MSAP901B,
and we have three saved JCL objects, MSAP901.jcl, MSAP901A.jcl, and
MSAP901B.jcl. Combine these into a
single MZAP901.jcl by appending the other two JCL objects to it, and
1.
Removing the unwanted 2nd
and 3rd JOB statements
2.
Change the step names, e.g. to GO2,
GO3
3.
Change DISP parameters in steps GO2
and GO3 to DISP=(SHR,PASS)
4.
Optionally: add COND=(8,LT) to these two GO steps.
Creating the full logic of program MSAP901 in one
program is arguably simpler than creating it as separate steps. The logic that was separate program MSAP901A
above can simply be written following the earlier END PROCESS, by writing the 2nd and 3rd PROCESS statements yourself or (Build #308 or later) you can convert the EZT SORT and JOB statements with the Easytrieve
Conversion Notepad. These PROCESS statements will be exactly as they were generated for program MSAP901A
and MSAP901B except that, if they read data that was written out earlier you
must add REOPEN to the PROCESS
statement so that the file is closed and reopened so that PROCESS will start reading from the beginning.
See below for an example of converting
EZT SORT and JOB
statements.
(=Program
MSAB901A in Creating Separate Job Steps. Step 4: Creating Program MSAP901A)
By Step 3. Convert Logic
for the First Process we’d written a Jazz program that will read INFILE and write VIRCARD. The second job reads this back. We can continue program MSAB901 by writing
the 2nd PROCESS statement, either manually, or (Build #308 or later)
convert it from the [SORT and] JOB statement.
The PROCESS statement generated for MSAB901A was
PROCESS VIRCARD
SID(21);
*#Copy Process logic
here ==>
END PROCESS
VIRCARD;
We write similar logic, with the addition of REOPEN, and omitting SID: -
PROCESS
VIRCARD REOPEN;
END PROCESS VIRCARD;
Copy/paste
the previous marker *#Copy Process logic here ==> from its current location
to between the PROCESS VIRCARD and END PROCESS VIRCARD. Now click [Check] to analyse this code. It will be coloured, and SID will be added,
e.g.
PROCESS VIRCARD
REOPEN SID(nn);
*#Copy Process logic
here ==>
END PROCESS
VIRCARD;
SID, which means “Statement ID”, identifies this particular PROCESS statement. It is important in the generated COBOL that
this ID doesn’t change as you add or remove statements
in your Jazz program, as the number is fixed into
various data names used by the COBOL. The number must be assigned by Jazz, and
you will only rarely refer to it.
*#Copy
Process logic here ==> is where code that should be within
this PROCESS loop will be inserted from the EZT Conversion Notepad. There can only be one of these in your
program, otherwise converted EZT would be inserted in the earlier PROCESS loop.
You are
converting an EZT program that has more than one JOB statement. You will already have created the program
structure for the first JOB, so you have an initial program something like
this: -
*# Last Updated by 11JAZZUSR at 28/06/2024
2:19:52 PM
PROGRAM EZTJob2 BATCH EZT;
COPY In1;
#388 E FR.Region and IN1.Region have different types
COPY EZT-EZTJob2-Data;
*# Copy Files here ==>
PROCESS In1 TALLY SID(23);
*#Copy Process logic here ==>
PRINT (IN1.*) ;
END PROCESS In1;
*#Copy Next Process here ==>
*#Copy Routines here ==>
Program EZTJob2
is actually an artificial example, your programs will
probably have more logic, including routines.
The only point that matters is that you’ve already created an EZT program with
markers such as *#Copy Process logic here ==> to determine where code is placed
when you click [Exit] from the Easytrieve Conversion Notepad. By now you will be familiar with using the
EZT Notepad to convert chunks of code. You’re now at a stage where you want to add the next JOB to this program.
We copy the JOB statement into the Conversion Notepad
JOB INPUT PERSNL START JZ-010-INZIO
[Convert]
turns this into
*#JOB INPUT PERSNL START JZ-010-INIZIO;
PERFORM JZ-010-INIZIO;
PROCESS PERSNL REOPEN;
*#Copy Process logic here ==>
END PROCESS PERSNL;
*#JOBM PERSNL Marker
[Exit]
drops the highlighted code into our program.
Note that the previous *#Copy
Process logic here ==> has disappeared, being replaced by the new one.
*# Last Updated by 11JAZZUSR at 30/06/2024 4:53:31 PM
PROGRAM EZTJob2 BATCH EZT;
COPY In1;
#388 E FR.Region
and IN1.Region have different types
COPY EZT-EZTJob2-Data;
*# Copy Files here ==>
PROCESS In1 TALLY SID(23);
PRINT
(IN1.*)
;
END PROCESS In1;
*#JOB INPUT PERSNL
START JZ-010-INIZIO;
PERFORM JZ-010-INIZIO;
PROCESS PERSNL
REOPEN SID(31);
*#Copy Process
logic here ==>
END PROCESS
PERSNL;
*#Copy Next
Process here ==>
*#Copy Routines
here ==>
#476
S No ROUTINE for PERFORM JZ-010-INIZIO
We’re now
ready to convert the logic of this job, including routine JZ-010-INIZIO
As the
previous example shows, a JOB becomes a PROCESS/END PROCESS loop. If the JOB
is preceded by a SORT, then the SORT information is added to the PROCESS statement as ORDER and any BEFORE conditions are added as WHERE. To
make this happen we convert everything from the start of SORT to the end of JOB
together. Here’s
an example, again starting with program EZTJob2.
The example EZT is
SORT PERSNL
TO SORTWRK USING +
(NAME-LAST
NAME-FIRST) NAME MYSORT +
BEFORE
SCREENER
*
SCREENER.
PROC
IF SEX = 1,
2
SELECT
END-IF
END-PROC
*
JOB INPUT
SORTWRK NAME MYPROG +
FINISH FINISH-PROCEDURE
Copy this into the Conversion Notepad and click [Convert] =>
*#JOB INPUT SORTWRK NAME MYPROG FINISH FINISH-PROCEDURE;
PROCESS PERSNL
ORDER(NAME-LAST,NAME-FIRST)
WHERE SEX = 1, 2
REOPEN;
*#Copy Process logic here ==>
END PROCESS PERSNL;
PERFORM FINISH-PROCEDURE;
*#JOBM PERSNL Marker
Note that the SORT and all following statements before JOB have
disappeared. They have become the ORDER
and WHERE parts of the PROCESS statement.
[Exit] adds the highlighted statements to program EZTJob2: -
*# Last Updated by 11JAZZUSR at 30/06/2024 4:53:31 PM
PROGRAM EZTJob2 BATCH EZT;
COPY In1;
#388 E FR.Region
and IN1.Region have different types
COPY EZT-EZTJob2-Data;
*# Copy Files here ==>
PROCESS In1 TALLY SID(23);
PRINT
(IN1.*)
;
END PROCESS In1;
*#JOB INPUT
SORTWRK NAME MYPROG FINISH FINISH-PROCEDURE;
PROCESS PERSNL
ORDER(PERSNL.GROUP2.NAME-LAST,PERSNL.GROUP2.NAME-FIRST) WHERE PERSNL.GROUP1.SEX IN( 1, 2
REOPEN SID(31);
#522 S IN must
end with )
*#Copy Process
logic here ==>
END PROCESS
PERSNL;
PERFORM FINISH-PROCEDURE;
*#Copy Next
Process here ==>
*#Copy Routines
here ==>
#476
S No ROUTINE for PERFORM FINISH-PROCEDURE
As
before, a new PROCESS has been added at the *#Copy Next Process here ==> marker, and the *#Copy Process logic here ==> has been reset to the new PROCESS loop. But there is no separate
SORT, instead the SORT
statement has disappeared into the ORDER option, and the PROCESS statement reads PERSNL, not SORTWRK.
SORTWRK is not used anywhere, so if you want to you can make your
program slightly more efficient and slightly smaller by removing the definition
of SORTWRK from EZT-EZTJob2-Data.
EZT
conversion from SORT to JOB is very basic: -
1. The SORT statement is analyzed to determine its From
and To files, and ORDER fields are
determined from USING. NAME MYSORT is ignored, and the only function of BEFORE SCREENER is to alert the conversion to look
for a following IF.
2. The other EZT statements down to JOB are ignored except for IF, which is assumed to be within the BEFORE Proc, and to be used as here to
filter the input records. This IF becomes the WHERE option.
3.
Conversion
of the EZT condition to a valid Jazz condition is very
basic, and often unsuccessful. IF SEX = 1,
2 should have been
converted to WHERE SEX IN(1,2), but the closing ) was omitted and message #522 produced. Add it and the message disappears. If the comma is not present the condition
remains as WHERE PERSNL.GROUP1.SEX = 1 2 with message #029 E ‘2’ is invalid here, leaving it to you to edit the problem to the
correct form IN(1,2).
Other
With this
correction made, you’re now ready to go on with
further conversion, such as handling the logic of the PROCESS PERSNL loop and adding missing routines.