Converting Easytrieve Data Definitions to Jazz

Contents

Converting Easytrieve Data Definitions to Jazz. 1

Introduction. 1

Easytrieve field definitions. 1

Jazz Field and File Names. 1

Redefinition. 1

Repeating groups. 1

ESDS, VSAM, and Key Fields. 1

Instream Tables. 1

External Tables. 1

Easytrieve Macros. 1

Macro Parameters. 1

Jazz Definitions – more features. 1

Appendices. 1

1       Example Test02.ext 1

2       Generated Jazz Definition. 1

 

Introduction

This Users’ Guide page shows you how you convert Easytrieve data definitions into the equivalent in Jazz, and how you can edit these to add missing information and make the definition more useful.  Here are parts of an Easytrieve program used to illustrate how Import from Easytrieve works (see Example Test02.ext for more complete text).  It contains two files and working data in its Library section, and also DEFINE statements and HEADING statements in the body of the JOB.  Details of the logic that are irrelevant to Import from Easytrieve have been omitted.

FILE LISTEX PRINTER

 

FILE EINGABE

 TEIL1             001       028   A

 DATUM-GE          001       007   N

*

 WSFLD1 W 5 A

 WSFLD2 W 3 N

 

FILE AUSGABE

 A-TEIL1           001       028   A

 A-VSNR            029       020   A

 A-VSNR1           029       001   A

*

 L-BETRAG-DM         W       008   N 2 MASK 'ZZZ.ZZ9,99'

 L-GEBUEHR-DM        W       005   N 2 MASK 'ZZ9,99'

 

JOB INPUT  EINGABE

*      Job EZTDEF Test

       DEFINE NAME 17 20 A

       DEFINE NAME2 W 20 A

       DEFINE NAME2A NAME2 1 A     

       DEFINE NAMEX * 20 A

REPORT LISTE1 LINESIZE 80 SPACE 1 PRINTER LISTEX

    HEADING DATUM-GE                 ('Datum' ' ')

    HEADING SL-UMSATZ                ('UA' ' ')

    HEADING VSNR13                   ('Versschein-' 'Nummer')

To convert this into a Jazz definition, start with the dialog New/Data/Import_from_Easytrieve.  First we locate the Easytrieve program with [Browse]: -

 

Then we click [Jazz Defn].  The whole EZT program is processed, using the EZT library section and DEFINE and HEADING statements from the program body.  This results in a definition called EZT-xxxx-DATA, in this case EZT-Test02-DATA which definition will contain DEFINE statements for each file, and one or more DEFINE statements for working data.  In this case the definition contains definitions for two files, and two working-storage definitions. 

DEFINE EINGABE FB [Assumed] DATA(

DEFINE EZT-Test02-Data DATA(

DEFINE AUSGABE FB [Assumed] DATA(

and

DEFINE EZT-Test02-Data1 DATA(

See Generated Jazz Definition for the complete definition.   Here are some key points: -

DEFINE EINGABE FB [Assumed] DATA(

    GROUP1 GROUP,

        TEIL1 CHAR(28),

        End GROUP,

    GROUP2 GROUP REDEFINES EINGABE.GROUP1,

Redefinitions caused by overlapping EZT field are handled by using GROUP REDEFINES

        DATUM-GE PIC '9999999' HEADING 'Datum' ' ' ,

        FILLER CHAR(19),

        SL-UMSATZ PIC '99' HEADING 'UA' ' ' ,

        VSNR13 CHAR(13) HEADING 'Versschein-' 'Nummer' ,

HEADING statements are added to the field definition

        End GROUP,

    GROUP3 GROUP REDEFINES EINGABE.GROUP1,

        End GROUP);

DEFINE EZT-Test02-Data DATA(

    GROUP1 GROUP,

        WSFLD1 CHAR(5),

        WSFLD2 PIC '999',

        End GROUP);

DEFINE AUSGABE FB [Assumed] DATA(

* DEFINE NAMEX * 20 A Invalid in EZT Definitions

    GROUP1 GROUP,

        End GROUP,

    GROUP2 GROUP REDEFINES AUSGABE.GROUP1,

        FILLER CHAR(16),

        NAME CHAR(20),

The EZT program body contained a DEFINE statement with a position
      DEFINE NAME 17 20 A
This is added to the last file, and in this case requires a redefinition GROUP.

        A-VSNR9-10 CHAR(2),

        FILLER CHAR(179),

        End GROUP,

    GROUP3 GROUP REDEFINES AUSGABE.GROUP1,

        End GROUP);

DEFINE EZT-Test02-Data1 DATA(

    GROUP1 GROUP,

        End GROUP,

    GROUP2 GROUP REDEFINES EZT-Test02-Data1.GROUP1,

        End GROUP);

In the next section we’ll use this simpler EZT definition to discuss how each definition is converted

FILE PERSNL FB(150 1800)

  EMPNAME  17  8  A

  EMP#      9  5  N

  DEPT     98  3  N

  GROSS    94  4  P  2

  DEDUCTIONS  W  4  P  2

  NET-PAY     W  4  P  2

Easytrieve field definitions

  EMP#      9  5  N

defines field EMP#, starting at position 9 of the input record, length 5, format N.

·                    Easytrieve field names can contain #, $, or @, but these are invalid in COBOL, and (mostly) in Jazz.  They are converted to valid COBOL names by the substitutions specified in the Convert From Easytrieve dialog, so EMP# becomes EMPNbr.   If the name has to be changed, its original name is used for a column heading.

·                    Jazz definitions are like COBOL or PL/I definitions, using order, and FILLER when necessary, to position fields in a record, not a numeric position.  The field list is sorted into position order in an attempt to minimize the number of redefinitions.

·                     5 is the length of field EMP#, and N is its type, so EMPNbr becomes PIC '99999'.  Easytrieve has data types

A          Alphameric. Becomes CHAR.
B          Binary.  Becomes TINYINT(1 byte), SMALLINT (2 bytes) or INTEGER (4 bytes).
N          Numeric (Display form).  Becomes PIC.
P          Packed.  Becomes DECIMAL or MONEY.  DECIMAL and MONEY have the same data format, but MONEY will be printed with a currency symbol, e.g.
                       
MONEY:  $1,234.56
                       
DECIMAL: 1,234.56

U          Unsigned Packed.  Becomes USPCKD.  COBOL does not support unsigned packed data, and treats it like CHAR, so the conversion also creates a related field in working storage that has format DECIMAL, using the same field name prefixed with JZ-. For example, if DEPT above were defined
           
DEPT     98  3  U
this would become

DEFINE PERSNL DATA(

        DEPT USPCKD(3) [Unsigned Packed],

and a working-storage field would be defined: -

JZ-DEPT DECIMAL(7) HEADING 'DEPT',

By assigning the USPCKD field to the DECIMAL field

EZT-EZTU-Data.JZ-DEPT = PERSNL.DEPT;

the numeric value of the unsigned packed data is available for display and arithmetic.

An Easytrieve definition may include OCCURS, INDEX, HEADING, and MASK

·                    OCCURS defines a repeating field, e.g.
            I-MULTI            36   68 A OCCURS 4 INDEX IX-A
            becomes
            I-MULTI(4) CHAR(68),

·                    INDEX is ignored.  Jazz logic uses subscripts.

·                    HEADING is added to the field’s Jazz definition, replacing the default heading which is the field’s name extended to the column width with *--- and ---*. 

·                    MASK becomes DPIC ‘picture’.   DPIC means “Display Picture”, and can be used with numeric, DATE, and TIME fields.

Invalid Field and File Names

Easytrieve Field and File names don’t have to obey the rules of COBOL, and if an invalid name were passed unchanged to COBOL it would not compile.   MANASYS and Import from Easytrieve will handle most of these situations:

File names are truncated to 8 characters, and changed if they are COBOL reserved words or aren’t valid.  Thus
            OUTPUT becomes OUTPUT1   (OUTPUT is a COBOL reserved word)
            TEMP-1 becomes TEMP1           (COBOL file names must be valid for JCL)

Easytrieve field names can be up to 40 characters, but Jazz allows only 28 characters.   Longer names will be truncated.

Characters @, #, and $ are substituted as defined by the Import from Easytrieve dialog.

Easytrieve allows a name to start with a number, e.g. 2NDNAME is a valid Easytrieve name, but it is invalid in Jazz and COBOL.  Field (and file) names must start with a letter.

All these situations cause messages, but the last (2NDNAME) is not fixed for you and you should fix it by editing the Easytrieve before import and conversion.

Example: this Easytrieve Definition: -

FILE TestHsh FB(150 1800)

  Field1  1  8  A

  Field2#      9  5  N

  Field3@      14  5  N

  Field4$      19  5  N

  Field$5     24  3  N

  Fie@ld6     27  3  N

  F#ield7     30  3  N

  F#i$l@8     33  3  N

  @Field9     36  3  N

  #Field10    39  3  N

  $Field11    42  3  N

  2ndName     45  10 A

becomes this invalid Jazz definition: -

*# Converted from TestHsh.txt by Jazzusr at 11/02/2022 4:44:57 pm

DEFINE TestHsh FB DATA(

    GROUP1 GROUP,

        Field1 CHAR(8),

        Field2Nbr PIC '99999' HEADING 'Field2#',

        Field3At PIC '99999' HEADING 'Field3@',

        Field4Dlr PIC '99999' HEADING 'Field4$',

        FieldDlr5 PIC '999' HEADING 'Field$5',

        FieAtld6 PIC '999' HEADING 'Fie@ld6',

        FNbrield7 PIC '999' HEADING 'F#ield7',

        FNbriDlrlAt8 PIC '999' HEADING 'F#i$l@8',

        AtField9 PIC '999' HEADING '@Field9',

        NbrField10 PIC '999' HEADING '#Field10',

        DlrField11 PIC '999' HEADING '$Field11',

        2ndName CHAR(10),

    #007 S "2ndName" is invalid here

        FILLER CHAR(96),

        End GROUP);

#148 S Field 'CHAR' not validly defined

Missing Information

Generated definitions will need editing to add information that is not in the original: for example

·        The definition above does not include DSNAME so you need to add it of you want Jazz to generate complete JCL to run programs. 

·        Definitions need to define the file type, and define the key fields, so that Jazz knows how to access the data.  

·        It’s worth adding more information to make field descriptions more complete.  For example, if you change a field defined like this: -

SEX CHAR(1),

to this: -

SEX CHAR(1) CAPS CODES(M:Male,F:Female),

then SEX is not just a CHAR(1) field that can hold any single-character value, it is now a field that can only be “M” or “F” and will print as “Male” or “Female”.

Jazz definitions may define Sequential files (type F, FB, V, VB, and U), ESDS, VSAM (= KSDS), and SQL (assumed to be DB2), as well as XIO (External I/O, where data is processed through subprograms).  Jazz definitions may also define working data (like PERSNL-WS above), parameters, and various other types like screens and messages that are not relevant for batch programs.   Jazz has basic support for DL1, but does not support IDMS, ADABAS, or other pre-relational database formats.

The following sections deal with various situations that you may encounter with DATA/Import from Easytrieve.  Skip these sections unless they are relevant to you now.

Jazz Field and File Names

Jazz field names basically follow COBOL rules, and so names with $, #, and @ are usually invalid, although $ and @ are used by Jazz in some specific situations.  The Import From Easytrieve dialog sets defaults for these characters, which is why

  EMP#      9  5  N

becomes

    EMPNbr PIC '99999' HEADING 'EMP#',

Jazz field names (but not file names) may be COBOL reserved words.  Also, file names must not contain characters like hyphens that are invalid in names that must be known to z/OS.  Such names will be changed, e.g. “OUTPUT” to “OUTPUT1” (reserved word), “TEMP-1” to “TEMP1” (contains hyphen).  MANASYS makes these changes for you.

Redefinition

Fields may redefine earlier fields within the same file, either by specifying an overlapping position, or by naming the earlier field and (optional) an offset.  Here is an Easytrieve definition, with some added fields for demonstration.

FILE INFILE1 DISK VS (ES)

I-REC              01 1910 A

I-BINARY           01   06 U

I-DISP-23          05   23 A

I-DISP-23-Add I-DISP-23 +5 6 A

I-TYPE             05   01 A

I-BR-NO            06   02 N

I-PCODE            09   04 A

I-CLIENT-PRE       13   04 A

I-CLIENT           13   08 A

I-POLICY           21   06 A

I-FLAG             27   01 A

I-ID               30   02 A

I-MULTI            36   68 A OCCURS 4 INDEX IX-A

I-MULTI-POL I-MULTI +20 06 A

After-I-Multi       308 2 A

Add1 I-MULTI +10 05 A

Add2 I-MULTI +30 10 A

Add3 I-MULTI +30 20 A

Add4 I-MULTI 2 A

This file shows two forms of redefinition.   I-REC defines all 1910 bytes of the record, all the other non-highlighted fields give a position from 1 to 308, and so redefine I-REC.

The highlighted fields name a preceding field, plus (except for Add4) an offset.  Thus

I-DISP-23-Add I-DISP-23 +5 6 A

specifies that I-DISP-23-Add has starting position 5 bytes offset from I-DISP-23, i.e. 10.

Working-storage fields have position W, so redefinition of working-storage fields must use this second form, as you can’t refer to a numeric position.

Import From Easytrieve produces a Jazz definition.  Jazz puts as many fields as possible into GROUP1.  Having reached the end of the record with some fields still undefined, it creates GROUP2.  It continues with GROUP3, 4, and 5 until all fields have been handled so that a structure is created that can form valid COBOL, and defines the Easytrieve data with its correct position, length, and type.  The special handling of the redefinition of the repeating field I-MULTI(4)  is covered below.

*# Converted from INFILE1.txt by Jazzusr at 20/01/2022 2:27:08 pm

DEFINE INFILE1 ESDS DATA(

    GROUP1 GROUP,

        I-REC CHAR(1910),

        End GROUP,

    GROUP2 GROUP REDEFINES INFILE1.GROUP1,

        I-BINARY CHAR(6) [Unsigned Packed],

        FILLER CHAR(2),

        I-PCODE CHAR(4),

        I-CLIENT CHAR(8),

        I-POLICY CHAR(6),

        I-FLAG CHAR(1),

        FILLER CHAR(2),

        I-ID CHAR(2),

        FILLER CHAR(4),

        I-MULTI-GROUP GROUP,

            I-MULTI(4) CHAR(68),

            END GROUP,

        I-MULTI-REDEF (4) GROUP REDEFINES INFILE1.GROUP2.I-MULTI-GROUP,

            Add4 CHAR(2),

            FILLER CHAR(8),

            Add1 CHAR(5),

            FILLER CHAR(5),

            I-MULTI-POL CHAR(6),

            FILLER CHAR(4),

            Add3 CHAR(20),

            FILLER CHAR(18),

            END GROUP,

        I-MULTI-REDEF1 (4) GROUP REDEFINES INFILE1.GROUP2.I-MULTI-GROUP,

            FILLER CHAR(30),

            Add2 CHAR(10),

            FILLER CHAR(28),

            END GROUP,

        After-I-Multi CHAR(2),

        FILLER CHAR(1601),

        End GROUP,

    GROUP3 GROUP REDEFINES INFILE1.GROUP1,

        FILLER CHAR(4),

        I-DISP-23 CHAR(23),

        FILLER CHAR(1883),

        End GROUP,

    GROUP4 GROUP REDEFINES INFILE1.GROUP1,

        FILLER CHAR(4),

        I-TYPE CHAR(1),

        I-BR-NO PIC '99',

        FILLER CHAR(2),

        I-DISP-23-Add CHAR(6),

        FILLER CHAR(1895),

        End GROUP,

    GROUP5 GROUP REDEFINES INFILE1.GROUP1,

        FILLER CHAR(12),

        I-CLIENT-PRE CHAR(4),

        FILLER CHAR(1894),

        End GROUP);

Repeating groups

I-MULTI was defined in Easytrieve as

I-MULTI            36   68 A OCCURS 4 INDEX IX-A

This has become

        I-MULTI-GROUP GROUP,

            I-MULTI(4) CHAR(68),

            END GROUP,

It is put into a group to allow redefinition like
        I-MULTI-REDEF (4) GROUP REDEFINES INFILE1.GROUP2.I-MULTI-GROUP,

Otherwise REDEFINES INFILE1.GROUP2.I-MULTI would have produced a Jazz message, and a COBOL compile error.

I-MULTI(4) CHAR(68) defines 272 bytes of data, so After-I-Multi, defined
           
After-I-Multi       308 2 A
immediately follows I-MULTI-GROUP and its redefinitions.

The scalar groups GROUP2, GROUP3,… just ended when there were no more fields that they could contain, but when a repeating field like I-MULTI is redefined the redefinitions must all have the same length, in this case 68 bytes, so FILLER is included to ensure this.  Now the sections of the definition
                I-MULTI-REDEF (4) GROUP REDEFINES INFILE1.GROUP2.I-MULTI-GROUP,
and
                I-MULTI-REDEF1
(4) GROUP REDEFINES INFILE1.GROUP2.I-MULTI-GROUP,

ensure that references like INFILE1.Add4(JZ.IX1) refer to the first 2 bytes of I-MULTI, whatever the value of JZ.IX1.

 

Note also that INDEX IX-A has been ignored.  Jazz uses subscripts, not indexes, and besides, COBOL and Easytrieve use indexes differently, and using IX-A would lead to errors when Easytrieve procedural logic is converted to Jazz/COBOL.

ESDS, VSAM, and Key Fields

FILE INFILE1 DISK VS (ES)

made INFILE1 an ESDS file.   Other types of VS become VSAM, which is a KSDS, so this definition

FILE OUTPUT1 DISK VS (CREATE)

O-RECORD            1  15  A

O-CLIENT           01  08  A

O-POLICY           09  06  A

O-FLAG             15  01  A

becomes

DEFINE OUTPUT1 VSAM DATA(

    O-RECORD CHAR(15),

    GROUP2 GROUP REDEFINES OUTPUT1.O-RECORD,

        O-CLIENT CHAR(8),

        O-POLICY CHAR(6),

        O-FLAG CHAR(1),

        End GROUP);

#150 S Definition has no key field

Without a defined key, if COBOL were generated it would not compile.  There is no information in the Easytrieve definition to define the key, but from the Easytrieve procedural code I was able to deduce that the key was the first 14 characters of the record.  I added this: - 

        End GROUP,

GROUP3 GROUP REDEFINES GROUP1,

O-KEY CHAR(14) KEY,

FILLER CHAR(1),

END GROUP);

which [Check] turns into

        End GROUP,

    GROUP3 GROUP REDEFINES OUTPUT1.GROUP1,

        O-KEY CHAR(14) KEY,

    #647 W CAPS/LOWER option recommended

        FILLER CHAR(1),

        END GROUP);

Warning message #647: this is always produced if a CHAR field has property KEY, and it has neither CAPS nor LOWER.  This avoids errors, but ignore this warning if you want to distinguish case and treat key values like “Robert” and “ROBERT” as different records.

Instream Tables

Instream tables are used for relatively small tables that don’t change very often.   If the table changes, then the only way to change it is to change the Easytrieve program and recompile it.

 

An Instream Table is defined like this: -

FILE MTHTAB TABLE INSTREAM

  ARG                   01  02 N

  DESC                  04  15 A

01 January

02 February

03 March

04 April

05 May

06 June

07 July

08 August

09 September

10 October

11 November

12 December

ENDTABLE

If, as here, ARG has type N and all values from 1 to the number of values are given, then a definition like this is generated

DEFINE MTHTAB DATA(

    DESC PIC '99' CODES('January','February','March','April','May','June','July','August','September','October','November','December'));[Value Length = 15]

You can choose to split this after any comma if the value is too long to display neatly in the Jazz Workbench

DEFINE MTHTAB DATA(

    DESC PIC '99' CODES('January','February','March','April','May','June','July','August',

    'September','October','November','December'));[Value Length = 15]

 

If ARG has type A, or values are missing or out of sequence, then the CODES property is generated with paired values.  This is generated when ARG is changed to A: -

DEFINE MTHTAB DATA(

    DESC CHAR(2) CODES('01':'January','02':'February','03':'March','04':'April','05':'May','06':'June','07':'July',

    '08':'August','09':'September','10':'October','11':'November','12':'December'));[Value Length = 15]

#647 E CAPS/LOWER option recommended

Whichever form is generated, the value is decoded with a SEARCH statement. For example, this Easytrieve

FILE TEST TABLE INSTREAM

ARG 1 4 A

DESC 6 10 A

CHEM CHEMICAL

MCA  MASTERCOMP

MECH MECHANICAL

MTEC MTECHNOLGY

ENDTABLE

Became

DEFINE TEST1 DATA(

    DESC CHAR(4) CAPS CODES('CHEM':'CHEMICAL','MCA ':'MASTERCOMP',

                                                         'MECH':'MECHANICAL','MTEC':'MTECHNOLGY'));

(The table name is changed to TEST1 because TEST is a COBOL reserved word).  Now, with definition

DEFINE W DATA(

    WITH1 CHAR(4) VALUE 'MECH',

    GIVE1 CHAR(10));

You’d write a SEARCH statement like

            SEARCH TEST1 WITH WITH1 GIVING GIVE1;

Which MANASYS will change to

SEARCH(TEST1.DESC) WITH W.WITH1 GIVING W.GIVE1;

The generated logic will get the array value, by subscript for a single-value CODES, or search for paired-values.  In both cases, MANASYS logic will check that the code value is valid, and will assign asterisks, '**********', if the code is invalid.

External Tables

External tables are loaded from a file when the program is executed.  They are defined like this: -

FILE TABLE2 TABLE 20

ARG 1 4 A

DESC 6 10 A

FILE CLASSES TABLE (150)

ARG 1 4 A

DESC 10 40 A

From these two tables, the following Jazz definitions are created: -

DEFINE TABLE2 DATA(

    GROUP1(20) GROUP,

        ARG CHAR(4) TKEY,

        DESC CHAR(10),

        END GROUP);

DEFINE CLASSES DATA(

    GROUP1(150) GROUP,

        ARG CHAR(4) SKEY,

        DESC CHAR(40),

        END GROUP);

The first field in the array is the key, which will have property TKEY or SKEY, added when EZT external table definitions like TABLE2 and CLASSES are converted from EZT. ImportFromEasytrieve assigns property SKEY if the table size is greater than or equal to the size criteria, which by default is 50 (but can be changed by Configure/COBOL).  SEARCH ALL is a binary search: you should change the property to TKEY if the table is not in ascending sequence of the key field.

NOTE: in EZT it is valid to define a table with neither INSCREEN or an integer giving the number of entries.  In this case the table will be defined using the Options Table parameter TBLMAX.   However MANASYS does not have access to the Options Table, so it has been programmed to produce a message and use a default of 1000 when it encounters something like this: -

FILE TABLE3 TABLE

ARG 1 4 A

DESC 6 10 A

This results in

*TABLE3 Neither INSTREAM nor Number. 1000 assumed

DEFINE TABLE3 DATA(

    GROUP1(1000) GROUP,

        ARG CHAR(4) SKEY,

        DESC CHAR(10),

        END GROUP);

TKEY indicates that the field is a table key, but the table is not in any particular sequence.  TABLE2 was defined with

        ARG CHAR(4) TKEY,

so the Easytrieve SEARCH statement

            SEARCH TABLE2 WITH WITH1 GIVING GIVE1

becomes

SEARCH(TABLE2.GROUP1(*))WITH W.WITH1 GIVING W.GIVE1;

This will become a COBOL SEARCH statement.

Similarly,
           
SEARCH CLASSES WITH WITH1 GIVING GIVE1

becomes

SEARCH(CLASSES.GROUP1(*))WITH W.WITH1 GIVING W.GIVE1;

This will become a COBOL SEARCH ALL statement, using binary search logic, because CLASSES was defined with

ARG CHAR(4) SKEY,

SKEY indicates not only that ARG is a table key, but that the table is sequenced by ARG, so that binary search logic is possible.

Tables can also be defined manually.  For example,

W-TABLET  W 107 A  OCCURS 4500  INDEX TAB-INDE2

  T-TO  W-TABLET     4 A

  T-NAMT W-TABLET  +5 34 A

  T-99   W-TABLET  +39 1 A

  T-ADR1  W-TABLET  +41 34 A

  T-CT  W-TABLET  +75 20 A

  T-ST    W-TABLET  +95 2 A

  T-ZP   W-TABLET  +97 10 A

This converts to a Jazz definition

DEFINE EZT-LABEL01-Data DATA(

        W-TABLET-GROUP GROUP,

            W-TABLET(4500) CHAR(107),

            END GROUP,

        W-TABLET-REDEF (4500) GROUP REDEFINES EZT-LABEL01-Data.W-TABLET-GROUP,

            T-TO CHAR(4) SKEY,

            FILLER CHAR(1),

            T-NAMT CHAR(34),

            T-99 CHAR(1),

            FILLER CHAR(1),

            T-ADR1 CHAR(34),

            T-CT CHAR(20),

            T-ST CHAR(2),

            T-ZP CHAR(10),

            END GROUP,

SKEY has been added manually to the definition of T-TO.

External tables must be loaded before they are searched, typically by a PROC that is executed when your program starts. MANASYS Jazz can create these routines for you from the table and file definitions, both of which will be in your program (usually from the EZT-xxxxxx-Data definition created by Import from Easytrieve).  See https://www.jazzsoftware.co.nz/Docs/JazzWKLProc.htm to find out how to create these routines.

Easytrieve Macros

Easytrieve Source may contain macros.  Macros may appear in the Easytrieve Library, providing a convenient way of defining a record layout that you can reuse.  They can also appear later, defining not only further data but also calculations and other actions.  For information on EZT macro formats, refer to the CA-Easytrieve/Plus Reference Guide, Chapter 16.

To use a macro its name is written after %.  For example

MEMBER NAME PGM0002

*---------------------------------------------------------------------*

%COPY02

JOB INPUT RECORD2

COPY02 is a record layout that might be used in several programs.  To be used by Data/Import-From-Easytrieve it must exist in the same folder as the parent file, and have the same extension.  For example, if PGM0002 was found as PGM0002.ET, this same folder must also contain COPY02.ET.  The line

%COPY02

is replaced by the code of COPY02, which might be something like this: -

FILE RECORD2

     COL1  1  4 N

     COL2  1  2 A

     COL3  3  2 A

Thus in effect PGM0002 is the same as

MEMBER NAME PGM0002

*---------------------------------------------------------------------*

FILE RECORD2

     COL1  1  4 N

     COL2  1  2 A

     COL3  3  2 A

JOB INPUT RECORD2

Macro Parameters

Easytrieve macros can have parameters, which are substituted as the macro is replaced.  Parameters are defined by a MACRO statement, and may be positional or keyword.  If keyword parameters are included the number of positional parameters is given after the macro name. %COPY03 is an example which has one positional and one keyword parameter: -

MACRO 1 Filename Type FB

FILE &Filename &Type   

     COL1  1  4 N      

     COL2  1  2 A      

     COL3  3  2 A

The macro reference gives values for the parameters: -

MEMBER NAME PGM0003

*---------------------------------------------------------------------*

%COPY03 FILE1 TYPE FB

JOB INPUT FILE1

This is equivalent to

MEMBER NAME PGM0003

*---------------------------------------------------------------------*

FILE FILE1 FB   

     COL1  1  4 N      

     COL2  1  2 A      

     COL3  3  2 A

JOB INPUT FILE1

Parameter substitution ends at the end of the macro (e.g., the end of COPY03.ET in this case) or when a MEND statement is encountered, whichever comes first.

Jazz Definitions – more features

Convert-from-Easytrieve can produce basic Jazz definitions with formats DECIMAL, CHAR, and MONEY

Here is the definition of file IN1: -

DEFINE IN1 VB DATA(

    Region DECIMAL(3),

    District DECIMAL(3),

    Name CHAR(40),

    SalesThisMonth MONEY(7,2),

    SalesYTD MONEY(7,2),

    BillingCycle LIKE Types.Month,

    DateCommenced DATE DPIC 'dd mmm yyyy')

And here is the beginning of the report produced by Program IN1R

Region District *-----------------Name-----------------* *SalesThisMonth-* *----SalesYTD---* BillingCycle DateCommenced             

 

     1        1 REEDE, Phillip                                   $468.55         $4,685.50            Oct   28 Feb 2018             

Numeric Fields

Region, District, SalesThisMonth, and SalesYTD are all numeric fields, and so are printed right-aligned with their heading which, in the absence of a HEADING property in the DEFINE or PRINT statement, is the field name.

Region and District are 2-byte packed numbers:  in Jazz DECIMAL(3),  in COBOL PIC S9(3) COMP-3.  Allowing for a negative sign, 4 characters are needed to print these fields, but the column width needs to be wider to accommodate the heading.

SalesThisMonth and SalesYTD are also packed decimal, in COBOL PIC S9(5)V9(2) COMP-3, but have type MONEY so that they print with a leading currency sign.  Because they are totalled the column needs to be wide enough to allow for the maximum value so there’s space for extra digits and so the columns are quite wide, causing the headings to be formed by extending the field name with hyphens and then asterisks to mark the column boundaries.

Easytrieve 2 byte Binary fields are SMALLINT in Jazz, 4 byte Binary fields are INTEGER, which are also numeric fields handled like Region etc.  Single byte Binary fields become TINYINT fields, which can have values from 0 to 255 but can’t be negative.  Jazz has logic that allows TINYINT fields to be used as numbers in arithmetic as to COBOL a TINYINT field is stored as PIC X and arithmetic would not normally be possible.

Easytrieve Numeric fields, like DEPT 98 3 N, are display-form numbers, having type like PIC '999'.  They will be printed right-aligned, like other numeric fields.

String Fields

Name has type CHAR(40), in COBOL PIC X(40), in Easytrieve 40 A.   String fields are left aligned under their column heading, which, as before, is the field name extended with hyphens and blanks.

Other Field Types

MANASYS Jazz supports many more field types.  In1 shows two of these: -

DateCommenced DATE DPIC 'dd mmm yyyy'. DATE fields hold date values in format yyyymmdd, i.e. the 28th May 1963 would be a number with value 19630528.  You may encounter these when you are using MANASYS Jazz with data from DB2, which supports this format.  You will probably use DPIC to control the format with which they are displayed.

BillingCycle LIKE Types.Month illustrates both indirect definitions, and a field defined with CODES.  LIKE obviously means that BillingCycle has the same format as Types.Month, and the definition of IN1 will have been preceded by COPY Types;  If we look at the definition of Types we’ll see that Month is defined: -

Month CODES(Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec),

Month is a single-byte number with values in the range 0 to 255 (i.e. TINYINT), with 1 meaning Jan.  As you see from the report line, 10 is printed as Oct

You can define fields of any format with CODES.  For example

SEX CHAR(1) CODES(M:Male,F:Female),

Using this feature in the definition will avoid the need to write logic to convert the code value into its meaning.  Invalid code values will be printed as asterisks.

Explicit Display Formats

You can control the format of numbers and dates explicitly with DPIC, meaning “Display Picture”.  DPIC is basically a COBOL PICTURE, as is the Easytrieve MASK.   As far as I know, both Easytrieve and Jazz follow the same rules, but if not, you can easily edit the DPIC value into the correct format for Jazz.

Field Headings

When you don’t want the field name to be the field heading, use HEADING: -

    EMPNbr PIC '99999' HEADING 'EMP#',

Appendices

1             Example Test02.ext

This is a more complete listing of the program, with a complete library section, and all the HEADING statements of the original. However I’ve still omitted the procedural logic that is ignored by Import from Easytrieve

FILE LISTEX PRINTER

 

FILE EINGABE

 TEIL1             001       028   A

 DATUM-GE          001       007   N

 SL-UMSATZ         027       002   N

 VSNR              029       020   A

 VSNR13            029       013   A

 VSNR1-2       VSNR          002   A

 VSNR3         VSNR +2       001   A

 VSNR4-10      VSNR +3       007   A

 VSNR11        VSNR +10      001   A

 VSNR12-13     VSNR +11      002   A

 TEIL2             049       001   A

 SL-RETOURE        049       001   A

 BETRAG-DM         050       006   P 2

 GEBUEHR-DM        056       003   P 2

 BETRAG-EUR        059       006   P 2

 GEBUEHR-EUR       065       003   P 2

 TEIL3             068       132   A

 WKZ               068       003   A

*

 WSFLD1 W 5 A

 WSFLD2 W 3 N

 

FILE AUSGABE

 A-TEIL1           001       028   A

 A-VSNR            029       020   A

 A-VSNR1           029       001   A

 A-VSNR2-8         030       007   A

 A-VSNR9-10        037       002   A

 A-TEIL2           049       001   A

 A-BETRAG-DM-VZ    050       001   A

 A-BETRAG-DM       051       011   N 2

 A-GEBUEHR-DM-VZ   062       001   A

 A-GEBUEHR-DM      063       005   N 2

 A-BETRAG-EUR-VZ   068       001   A

 A-BETRAG-EUR      069       011   N 2

 A-GEBUEHR-EUR-VZ  080       001   A

 A-GEBUEHR-EUR     081       005   N 2

 A-TEIL3           086       132   A

*

 L-BETRAG-DM         W       008   N 2 MASK 'ZZZ.ZZ9,99'

 L-GEBUEHR-DM        W       005   N 2 MASK 'ZZ9,99'

 L-BETRAG-EUR        W       008   N 2 MASK 'ZZZ.ZZ9,99'

 L-GEBUEHR-EUR       W       005   N 2 MASK 'ZZ9,99'

 ZAEHLER             W       005   N   MASK 'ZZZZ9'

 GES-BETR-EUR-POS    W       008   N 2 MASK 'ZZZ.ZZ9,99' VALUE 0

 GES-GEBR-EUR-POS    W       005   N 2 MASK 'ZZ9,99'     VALUE 0

 GES-BETR-EUR-NEG    W       008   N 2 MASK 'ZZZ.ZZ9,99' VALUE 0

 GES-GEBR-EUR-NEG    W       005   N 2 MASK 'ZZ9,99'     VALUE 0

 L2-VZ1              W       001   A

 L2-VZ2              W       001   A

 L2-VZ3              W       001   A

 L2-VZ4              W       001   A

 

JOB INPUT  EINGABE

*

       ZAEHLER = ZAEHLER + 1

*      Job EZTDEF Test

       DEFINE NAME 17 20 A

       DEFINE NAME2 W 20 A

       DEFINE NAME2A NAME2 1 A     

       DEFINE NAMEX * 20 A

REPORT LISTE1 LINESIZE 80 SPACE 1 PRINTER LISTEX

    HEADING DATUM-GE                 ('Datum' ' ')

    HEADING SL-UMSATZ                ('UA' ' ')

    HEADING VSNR13                   ('Versschein-' 'Nummer')

    HEADING SL-RETOURE               ('R' ' ')

    HEADING A-BETRAG-DM-VZ           (' ')

    HEADING L-BETRAG-DM              ('   Betrag' '   in DM')

    HEADING A-GEBUEHR-DM-VZ          (' ')

    HEADING L-GEBUEHR-DM             ('Gebühr' 'in DM')

    HEADING A-BETRAG-EUR-VZ          (' ')

    HEADING L-BETRAG-EUR             ('   Betrag' '   in EUR')

    HEADING A-GEBUEHR-EUR-VZ         (' ')

    HEADING L-GEBUEHR-EUR            ('Gebühr' 'in EUR')

    HEADING WKZ                      ('WKZ' ' ')

REPORT LISTE2 LINESIZE 80 SPACE 4 PRINTER LISTEX

    HEADING ZAEHLER          ('Anzahl' ' ' ' ')

    HEADING GES-BETR-EUR-POS ('Gesamt-' 'betrag in EUR' 'positiv')

    HEADING GES-BETR-EUR-NEG ('Gesamt-' 'betrag in EUR' 'negativ')

2             Generated Jazz Definition

This is the complete definition generated for program Test02

*# Converted from Test02.ezt by JAZZUSR at 23/09/2022 9:44:35 AM

*-------------

*DEFINE LISTEX PRINTER

DEFINE EINGABE FB [Assumed] DATA(

    GROUP1 GROUP,

        TEIL1 CHAR(28),

        VSNR CHAR(20),

        TEIL2 CHAR(1),

        BETRAG-DM MONEY(11,2),

        GEBUEHR-DM MONEY(5,2),

        BETRAG-EUR MONEY(11,2),

        GEBUEHR-EUR MONEY(5,2),

        TEIL3 CHAR(132),

        End GROUP,

    GROUP2 GROUP REDEFINES EINGABE.GROUP1,

        DATUM-GE PIC '9999999' HEADING 'Datum' ' ' ,

        FILLER CHAR(19),

        SL-UMSATZ PIC '99' HEADING 'UA' ' ' ,

        VSNR13 CHAR(13) HEADING 'Versschein-' 'Nummer' ,

        FILLER CHAR(7),

        SL-RETOURE CHAR(1) HEADING 'R' ' ' ,

        FILLER CHAR(18),

        WKZ CHAR(3) HEADING 'WKZ' ' ' ,

        FILLER CHAR(129),

        End GROUP,

    GROUP3 GROUP REDEFINES EINGABE.GROUP1,

        FILLER CHAR(28),

        VSNR1-2 CHAR(2),

        VSNR3 CHAR(1),

        VSNR4-10 CHAR(7),

        VSNR11 CHAR(1),

        VSNR12-13 CHAR(2),

        FILLER CHAR(158),

        End GROUP);

DEFINE EZT-Test02-Data DATA(

    GROUP1 GROUP,

        WSFLD1 CHAR(5),

        WSFLD2 PIC '999',

        End GROUP);

DEFINE AUSGABE FB [Assumed] DATA(

* DEFINE NAMEX * 20 A Invalid in EZT Definitions

    GROUP1 GROUP,

        A-TEIL1 CHAR(28),

        A-VSNR CHAR(20),

        A-TEIL2 CHAR(1),

        A-BETRAG-DM-VZ CHAR(1) HEADING ' ' ,

        A-BETRAG-DM PIC '99999999999',

        A-GEBUEHR-DM-VZ CHAR(1) HEADING ' ' ,

        A-GEBUEHR-DM PIC '99999',

        A-BETRAG-EUR-VZ CHAR(1) HEADING ' ' ,

        A-BETRAG-EUR PIC '99999999999',

        A-GEBUEHR-EUR-VZ CHAR(1) HEADING ' ' ,

        A-GEBUEHR-EUR PIC '99999',

        A-TEIL3 CHAR(132),

        End GROUP,

    GROUP2 GROUP REDEFINES AUSGABE.GROUP1,

        FILLER CHAR(16),

        NAME CHAR(20),

        A-VSNR9-10 CHAR(2),

        FILLER CHAR(179),

        End GROUP,

    GROUP3 GROUP REDEFINES AUSGABE.GROUP1,

        FILLER CHAR(28),

        A-VSNR1 CHAR(1),

        A-VSNR2-8 CHAR(7),

        FILLER CHAR(181),

        End GROUP);

DEFINE EZT-Test02-Data1 DATA(

    GROUP1 GROUP,

        FILLER CHAR(8),

        L-BETRAG-DM PIC '99999999' DPIC 'ZZZ.ZZ9,99' HEADING '   Betrag' '   in DM' ,

        L-GEBUEHR-DM PIC '99999' DPIC 'ZZ9,99' HEADING 'Gebühr' 'in DM' ,

        L-BETRAG-EUR PIC '99999999' DPIC 'ZZZ.ZZ9,99' HEADING '   Betrag' '   in EUR' ,

        L-GEBUEHR-EUR PIC '99999' DPIC 'ZZ9,99' HEADING 'Gebühr' 'in EUR' ,

        ZAEHLER PIC '99999' DPIC 'ZZZZ9' HEADING 'Anzahl' ' ' ' ' ,

        GES-BETR-EUR-POS PIC '99999999' DPIC 'ZZZ.ZZ9,99' VALUE 0 HEADING 'Gesamt-' 'betrag in EUR' 'positiv' ,

        GES-GEBR-EUR-POS PIC '99999' DPIC 'ZZ9,99' VALUE 0,

        GES-BETR-EUR-NEG PIC '99999999' DPIC 'ZZZ.ZZ9,99' VALUE 0 HEADING 'Gesamt-' 'betrag in EUR' 'negativ' ,

        GES-GEBR-EUR-NEG PIC '99999' DPIC 'ZZ9,99' VALUE 0,

        L2-VZ1 CHAR(1),

        L2-VZ2 CHAR(1),

        L2-VZ3 CHAR(1),

        L2-VZ4 CHAR(1),

        NAME2 CHAR(20),

        End GROUP,

    GROUP2 GROUP REDEFINES EZT-Test02-Data1.GROUP1,

        FILLER CHAR(69),

        NAME2A CHAR(1),

        End GROUP);

#092 I GROUP2 is shorter than GROUP1