Converting Easytrieve Logic: Creating the Program Structure

Converting Easytrieve Logic: Creating the Program Structure  1

Introduction. 1

Creating the Program Structure. 1

JOB without SORT. 1

SORT and JOB.. 1

SORT to Another File with the Same Format 1

SORT not followed by JOB INPUT(file) 1

Selecting, Reformatting, and Printing Data with SORT. 1

NULL Input 1

Synchronized File Processing - Merging 2 Files. 1

Multiple Jobs and PROCESS statements. 1

An Example – Program MZAB910. 1

Step 1.  Create data definitions. 1

Step 2.  Create Initial Program Structure. 1

Step 3.  Convert Logic for the First Process. 1

Creating Separate Job Steps.  Step 4: Creating Program MSAP901A.. 1

Step 5.  Create Program MSAP901B.. 1

Step 6.   Create the Run JCL. 1

Creating a Single Program.. 1

Step 4A.  Logic of JOB INPUT(VIRCARD) 1

Converting JOB and SORT statements. 1

Introduction

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.

Creating the Program Structure

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.

JOB without SORT

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.

Other Options

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).

SORT and JOB

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

SORT to Another File with the Same Format

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.

SORT not followed by JOB INPUT(file)

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.

Selecting, Reformatting, and Printing Data with SORT

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;

NULL Input

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;

Synchronized File Processing - Merging 2 Files

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.KEY1BCOPY 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.  .

Merge with Sorting

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.EMPNbrCOPY 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.EMPNbrCOPY 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. 

Jazz MERGE logic compared to Easytrieve Synchronised File Processing

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 MATCHEDIF DUPLICATEIF 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,  

Multiple Jobs and PROCESS statements.

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.   

An Example – Program MZAB910

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.

Step 1.  Create data definitions

Dialog New/Data/Import from Easytrieve creates EZT-MSAB910-DATA, containing all the data definitions required

Step 2.  Create Initial Program Structure

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.

Step 3.  Convert Logic for the First Process

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.

Creating Separate Job Steps.  Step 4: Creating Program MSAP901A

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)

Step 5.  Create Program MSAP901B

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.

Step 6.   Create the Run JCL

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 a Single Program

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.

Step 4A.  Logic of JOB INPUT(VIRCARD)

(=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.

Converting JOB and SORT statements

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.

Adding a JOB without SORT

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

Adding a JOB with SORT

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.