This initial chapter of the Jazz Users’ Guide provides an introduction to the basic concepts of Jazz, and shows you how to create a simple Jazz program that will read data from an input file and print it on a report. You may like to start by viewing this 5-minute introductory video.
Installing
and Configuring the Jazz Workbench
Writing
your first Jazz program
External
definitions: the COPY statement
General form of DEFINE statements
Imperative Statements – Doing Something
MANASYS-Jazz is a revolutionary programming system for Mainframe (IBM z/OS) and mainframe simulations (Micro Focus Enterprise) that makes the programming of simple tasks vastly simpler than it would be with COBOL or similar tools, without making complex tasks more complex. Jazz itself operates in the Windows environment, with objects like COBOL programs, BMS maps, Database definitions, Web Service Descriptions (JSON) etc being passed to/from the target environment. Jazz will also interact with other development tools like Eclipse and VS (Microsoft’s Visual Studio) to create and coordinate web services, allowing you to build systems in which functions are distributed across the web and across a range of technologies.
For example, here is a simple report program written with
the Jazz Workbench: -
Click [Process] and Jazz will generate the equivalent 553 line COBOL program, submit it to z/OS where it will be compiled
and run, and the results (including the report) returned back to the workbench.
Jazz is written using the Jazz Workbench, a Windows™ program that interprets your program. If you open a Jazz program with a basic editor like Notepad you’ll see something like this: -
*# Last Updated by robertb
at 30/11/2013 10:24:19 a.m.
PROGRAM AAnExmpl
BATCH;
COPY IN1;
COPY FR;
PROCESS IN1 WHERE (IN1.Region > 5)
ORDER(IN1.Region, IN1.District, IN1.Name);
GET FR WHERE (FR.Region
= IN1.Region);
PRINT(IN1.Region, Fr.Name,
IN1.SalesThisMonth SUM, IN1.SalesYTD SUM)
BREAK(IN1.Region, IN1.District);
END PROCESS IN1;
When you open it with the Jazz Workbench you see this:-
*# Last Updated by IBMUSER at 7/12/2015 5:15:40 p.m.
PROGRAM
AAnExmpl BATCH;
COPY
IN1;
COPY
FR;
PROCESS
IN1 WHERE (IN1.Region > 5) ORDER(IN1.Region, IN1.District, IN1.Name) INDEX;
#082 W Default
name 'JZ-INDEX' used for INDEX option
GET FR WHERE (FR.Region
= in1.region) ;
PRINT
(JZ.JZ-INDEX, in1.region, FR.Name, in1.district, IN1.Name, in1.district, IN1.BillingCycle,
IN1.SalesThisMonth
SUM,IN1.SalesYTD SUM)
BREAK(in1.region, in1.district);
END
PROCESS IN1;
Keywords and fields have been identified by colour, and the code has been indented to show its logical structure. Also, when your program is checked Jazz will produce information, warning, error, and severe error messages when various situations are found: -
IN1.SalesThisMonth
= IN1.Name
+ 5;
#168 E
Operator invalid for preceding item
#031 E
"+" is invalid here
When you write unqualified references like “SalesThisMonth” and “Name” Jazz will find the fields and qualify the references for you, providing visual confirmation that the field exists and a helpful hint enabling you to check that you have the field that you want. “?” can be used to get selection lists: for example PRINT(IN1.?) produces a list of the fields defined in record IN1: -
To install the Jazz Workbench you need only visit the JazzSoftware web site, www.jazzsoftware.co.nz, register, and
obtain a trial or full licence. You then install the workbench by clicking the
[Run Jazz] button on the web page. This downloads and starts the workbench as a
Microsoft ClickOnce program: it runs in its own
environment and cannot interfere with your other Windows programs.
Once installed, for first use you’ll need to configure the
workbench with your own preferences, such as the names of folders in your
Windows system that will contain your Jazz programs, the names of the libraries
in the z/OS environment that will hold your COBOL source, your JCL, and so on.
Just click the workbench’s [Configure] button and follow the dialogs. Initial set-up and
configuration is described in more detail here.
You can write batch programs to produce reports and update records in VSAM or SQL databases. You can write classical (3270-type) CICS transactions: simple and complex enquiries, and update programs. You can write mainframe programs that invoke web services, and you can write web services that can be invoked from Web or Windows programs through the internet. You can define data, 3270-type screen layouts, and you can import existing COBOL record definitions and SQL table definitions into Jazz. All these activities follow basic Jazz principles, so let’s start by looking at the program above to see the structure and rules of all Jazz programs.
You’ll see
that the program starts with a comment: -
*# Last Updated by robertb at 25/07/2013
6:12:24 p.m.
This
comment is automatically inserted by Jazz, but we can write our own comments
anywhere we like. Jazz will colour all comments green[1]. Any line starting with “*” is a comment. Also
we can write a comment on a normal line anywhere where a blank would be valid
by enclosing the comment text in [ and ], or [ to the end of a line. Thus all
the green text here is comment: -
*# Last Updated by robertb at 25/07/2013
6:12:24 p.m.
PROGRAM
AAnExmpl BATCH; [Our first example
program
DEFINE
IN1 [main input
file] TYPE(VB) DATA(
Comments
that start with *# are automatic comments. Don’t start your own comments with
“*#”: if you do you might find Jazz attempting to replace or edit them. Apart
from that, you can write whatever you like in a comment.
When we
click [New] or take the New option from the File menu the Jazz workbench
responds with a dialog like this: -
Click [+]
to expand the nodes until we find the one we want, then click this. This time
we’ll select “New Batch Program”, and the dialog will ask us for the program
name and create the PROGRAM statement for us.
We show
Jazz programs and data definitions here in colour, indented, and with statement
keywords highlighted. This formatting is inserted by the Jazz workbench. For
example, here we are starting to write a Jazz record definition: -
When we
click [Check] Jazz formats it for us: -
If we make
mistakes Jazz will produce error messages: -
Very often
one error will lead to many error messages, and sometimes an “error cascade”
where Jazz can’t interpret the following statements correctly. If you get
errors, correct them from the top, and don’t worry about the errors that you
don’t understand: they may well disappear.
By the way, help is only a right-click away:-
You can get
help by right-clicking part of the workbench: -
·
Right-click
on any statement except COPY
and the relevant page of the language reference manual will open. For example,
with the cursor positioned on the PROCESS statement a right-click produces this.
·
Right-click
with the cursor positioned on an error message and an explanation of the error
is given: -
·
Right-click
on a COPY statement
and another workbench opens, displaying the imported definition and allowing
you to edit it. For example, clicking on
COPY In1;
displays: -
Just in case you want to see the definition of
a COPY
statement these 2nd-level workbench sessions have a button [Show COPY
Help]. Click [Exit] to return to the
parent session. If the COPY code
includes further COPY
statements then you may open further levels of workbench session.
·
In
many situations you can write a question mark, and the workbench will respond
with a data list from which you can select the fields that you want. For
example, writing
PRINT
?;
here: -
causes this window to be displayed when you
click [Check]: -
You can expand the nodes for the records IN1 or
FR and click on the fields that you want to print. As you select fields, they are added to the
data list: when you are through, click [Finish] to return to the program.
Ignoring comments, you can see that the program contains several statements. Almost every statement starts with a keyword like PROGRAM, DEFINE, PROCESS, etc., and ends with a semicolon. Jazz has coloured the statement keyword blue and used BOLD type. Other keywords are also blue, but are not bold. A statement may extend over several lines. For example, the DEFINE statement starts with
DEFINE
IN1 VB DATA(
and
finishes several lines later with
DateCommenced CHAR(10));
Jazz indents the text to emphasise the logical relationship of various lines.
There is one kind of statement that does not start with a keyword, the assignment statement, which assigns (moves or computes) one value to another. It simply starts with a field (or record or group) name: -
R1.B = R1.C;
There
are no assignment statements in the program above.
Just
as Jazz coloured keywords blue, references to fields are coloured turquoise.
The first
statement above is: -
PROGRAM
AAnExmpl BATCH;
The
point of this is to:
1.
Tell
Jazz that this is a program. Alternative first statements might be SUBPROGRAM, or DEFINE, creating different kinds of
objects
2.
Give
the program a name: AAnExmpl in this case
3.
Tell
Jazz what kind of program this is. Currently the types available are BATCH, CICS, or WEBSERVICE.
The program name follows the rules of Jazz External Names, which are names that are known by the operating system as well as within your program. These rules are: -
1. It cannot be longer than 8 characters
2. It must start with a letter, and contain only letters and numbers
3. If may not contain a hyphen
4. It must not be a COBOL reserved word
5. If must also follow the general rules for Jazz Names, which means that it may not start with “JZ” or “$”.
Click here for a full description of the PROGRAM
statement.
Data
definitions are a very important part of Jazz, so we’ll spend some time looking
at the DEFINE
statements in the example program. Our COPY statements brought in these
definitions: -
DEFINE
IN1 VB DATA(
Region
DECIMAL(3),
District
DECIMAL(3),
Name CHAR(15),
SalesThisMonth MONEY(7,2),
SalesYTD MONEY(7,2),
Cardholder
CHAR(1),
DateCommenced CHAR(10));
DEFINE
FR VSAM DATA(
Region
PIC '999' KEY,
Name CHAR(30) Value('No Record found')
HEADING 'Region
Name',
Fill CHAR(47));
DEFINE statements supply Jazz with the information it
needs about the data used in a program. Obviously if one program creates a
record and another uses it the two programs must use the same description; if
the first program has NAME defined as 30 characters long, and the second
defines it as 20 characters the two programs will have trouble sharing the
file. It therefore makes good sense to write definitions separately, then use COPY
to include this definition in each programs.
The
advantages are obvious: you only write this once and EVERY program using it has
the same definition and so will be consistent.
COPY
is obviously very similar to COBOL’s COPY statement, although there are some
differences making it more flexible. The
most important of these: COPY xxx; is
harmlessly discarded if there is a preceding COPY
xxx; in the program. This makes it easy
to write definitions that depend on other definitions like this: -
COPY
CustRec;
COPY
Order;
DEFINE
Savearea DATA(
LastCustID LIKE Custrec.Custid,
LastOrder LIKE Order.*);
Now
it doesn’t matter if the program already includes COPY
CustRec or COPY
Order: the second COPY statement is
simply ignored. Click here to see more about the COPY statement.
Often we will be writing Jazz programs using files that have already been defined for pre-existing COBOL programs. A very quick way of creating the Jazz definitions that we want is to convert these to Jazz, and then add the extra Jazz features like validation rules, file type, and DSName: -
1.
Select the option “Import from COBOL”. Jazz will access the mainframe copy library
that you defined when you configured Jazz, and show you a list of members in
it.
2. Select the definition that you want to download. Here I’ve selected PROGINFO. This is downloaded as PROGINFO.CBL, and the [Convert] button becomes active: -
3.
Click the [Convert] button and this is converted
to Jazz as Proginfo.jzc, and the downloaded
PROGINFO.CBL is deleted unless we unchecked the option “Delete Downloaded
COBOL” This does not affect the
mainframe library of course. Now we see
the converted definition: -
There may be messages produced (as here) if Jazz detects errors. The conversion expects to be given a data
definition starting with an 01 name, but there may be several records, and in
fact this could be a complete COBOL program.
Any statements other than data-division statements starting with a level
number will be ignored.
4. You can now edit the Jazz definition to add validation and display options like HEADING and CODES, define the file type, and add a DSNAME option.
DEFINE statements
have this general form: -
DEFINE
name type DATA(
field,
field,
…
last field);
Each field is
FieldName Format [Other attributes]
Here we
have defined two records, IN1 and FR. Definition names must be unique, so that
it would have been an error if either of these definitions had the same name as
the program, or if the second were also called “IN1”. Definitions with TYPE(VB) or TYPE(VSAM) are
also external names, like the program name AAnExmpl,
so must follow the rules above.
If there is no TYPE option, or if it has another TYPE, then the definition name follows the general Jazz name rules: -
1.
The name may be up to 25 characters long
2.
It must start with a letter
3.
It may not start with “JZ” or “$”
4.
It may contain letters, numbers, and hyphens
5.
The last character of the name may not be a hyphen
Note that
these rules DO NOT say that you may not use Jazz keywords, or COBOL reserved
words, although it is recommended that you avoid them if you can.
By the way,
don’t bother learning these rules. Jazz will tell you when you break them.
IN1 has
been defined with type VB. This means that it is “Variable Blocked”, which is one of 5
types of “Physical Sequential” files. Others are F, FB, V, and U, meaning
Fixed, Fixed Blocked, Variable, and Undefined. A Physical Sequential file can
only be read in sequence (front to back), you cannot use direct access to read
a record with a particular key value. In Jazz you can only use these files with
a PROCESS statement in BATCH programs.
FR has type VSAM (Virtual Storage Access Method), which is an organization that
allows us to read the records both sequentially and by key. Just as with a
Physical Sequential file we could use a PROCESS statement to
read some or all of the records sequentially, but we can also use GET statements
to read particular records. VSAM files can be used in both BATCH and CICS programs.
If there is
no type then WORK is assumed. This means that the record defines some working data
in our program which is not read from or written to files. Since all data in
Jazz must be defined within a record, many programs will contain a DEFINE statement
like
DEFINE WD
DATA(
field , …
defining a
record WD containing some of the program’s working data.
There are
also other definition types, which we will meet as we need them. Click here for a full description of the TYPE option.
Fields in
IN1 are: -
Region
DECIMAL(3),
District
DECIMAL(3),
Name CHAR(15),
SalesThisMonth MONEY(7,2),
SalesYTD MONEY(7,2),
Cardholder
CHAR(1),
DateCommenced CHAR(10)
Each field
definition gives the field name, which follows the general
Jazz name rules, and then give the field format – DECIMAL(3), CHAR(15), MONEY(7,2), and so on.
DECIMAL and MONEY are called “Packed” or “COMP-3” in COBOL, Fixed
Decimal in PL/I, and are a format that is designed to hold decimal numbers.
Thus DECIMAL(3) holds values from +999 to -999,
while MONEY(7,2) holds values from +99999.99 to
-99999.99. The only difference between DECIMAL
and MONEY is that MONEY
will display with currency symbols on screens and reports. DECIMAL and MONEY are numeric formats so you can calculate with
them. Other numeric formats are the
integer formats TINYINT, SMALLINT, INTEGER, and BIGINT,
floating point formats FLOAT and LONG, and PIC which
is numeric data held in character format. You can assign data from one numeric
format to another.
CHAR fields hold character
string values, and are equivalent to PIC X(length) in COBOL. Jazz also provides
VARCHAR format. You can assign between CHAR and VARCHAR
fields, but not to/from numeric variables
Fields defined in FR are:
-
Region
PIC '999' KEY,
Name CHAR(30) Value('No Record found') HEADING 'Region Name',
Fill CHAR(47)
Region and
Name show examples of optional field properties: Region is described with KEY, while Name is given a default VALUE and a HEADING. As mentioned
above, it is always better to give this sort of information in DEFINE
statements, rather than coding
it into the logic of particular programs. By putting it in a definition which
you COPY you
ensure consistency, but you create no overhead as the details are ignored when
they are irrelevant.
A
powerful way of using flexibility of COPY
and DEFINE statements is to define your
own data types for fields that are used in standard ways within your
application. Start by writing DEFINE xxx TYPE(SYSTEM) DATA(
Then
define your special data types: -
DEFINE
MyTypes TYPE(SYSTEM) DATA(
State CHAR(2)
CODES (AL:Alabama,AK:Alaska,AR:Arkansa,AZ:Arizona ...),
PhoneNbr
GROUP,
AreaCode DECIMAL
(3),
Number
DECIMAL (7),
END GROUP,
Customer GROUP,
Title CHAR(5) VALIDVALUES ('Mr', 'Mrs', 'Ms', 'Miss', 'Dr' ...),
GivenName CHAR(20),
FamilyName CHAR(20),
Gender
CODES(Male, Female),
Address1
CHAR(30),
Address2
CHAR(30),
CustState LIKE
mytypes.State,
CustPhoneNbr LIKE
mytypes.PhoneNbr,
END GROUP);
Now records can be defined like this: -
COPY MyTypes;
DEFINE CustRec TYPE(VSAM) DATA(
Custid INTEGER KEY,
Customer like MyTypes.Customer,
CurrentSales MONEY(7,2),
…);
Duplicate COPY
Mytypes; cause no problem, and DEFINE MyTypes;
creates no overhead as it is only used to define other fields. So, without any overhead, we’ve ensured
consistency, made our programs more robust, and made them easier to change.
Note the strong principle
in Jazz: give as much information as possible in the data definition, as this
reduces what you need to write in individual programs. Putting this information into the definition
has many advantages. CODES fields in particular are efficient and precise:
-
·
In
appropriate circumstances such as accepting data from an input screen Jazz will
validate the input value, and produce error messages if its value is invalid,
·
If
we display it, either on a screen or printed in a report, it will be displayed
as “Enquiry” etc,
·
Within
our Jazz programs we refer to the interpreted value, not the code. Thus we
write
IF Function =
Enquiry …
not
IF Function = 'E' … .
· Jazz will not allow us to assign a value to Function that could be invalid.
·
However there is no overhead from this: for example
although you wrote
IF Function = Enquiry
…
in
the generated program this tests the code value, 'E',
directly.
· A field like Gender, defined with CODES but no format code, is carried as a one-byte hexadecimal character.
Gender CODES(Male, Female),
Value
x’01’ means “Male” and x’02’ means “Female”.
Note also the use of LIKE to
define SaveArea. Here we wanted a program area to
save a value of the Order record. By using LIKE we
not only save work but we avoid future errors because Jazz now ensures that Savearea and the Order record are defined the same way.
Should we change the definition of Order, for example adding another field then
when we regenerate the program containing SaveArea its definition will automatically change to
match the new format of Order.
Another
example: FR.Name has HEADING 'Region
Name' which only applies if you PRINT FR.Name, or drag the field on to a screen. By making this part of
the definition you again guarantee consistency at no cost. You’ll see more
examples later.
Click here for a full description of field definitions
and the Data option.
So far with
PROGRAM
and DEFINE we’ve
set the scene, but we haven’t actually given any orders to do anything. But now
comes the last five lines of our program, starting with the first of our
imperative statements, PROCESS:
-
PROCESS IN1
WHERE (IN1.Region > 5) ORDER(IN1.Region, IN1.District, IN1.Name);
GET FR WHERE (FR.Region
= IN1.Region);
PRINT(IN1.Region, Fr.Name, IN1.SalesThisMonth
SUM, IN1.SalesYTD SUM)
BREAK(IN1.Region, IN1.District);
END
PROCESS IN1;
PROCESS statements
form the heart of BATCH programs.
There may be a little bit of logic that is done at the beginning before you
start, and there may be a little bit of logic at the end, but most of the
program logic is between PROCESS
file …; and the corresponding END
PROCESS file;
PROCESS statements create an I/O loop. Thus
PROCESS
IN1 WHERE …
statements
END
PROCESS IN1;
reads each
record in turn from file IN1. If the
record meets the WHERE criteria, then the record is passed to the statements between PROCESS and
END PROCESS
for further action. Here IN1 is defined with type VB. It could have been defined, like FR, with VSAM, or if it had been a table in a DB2
database it would have been defined as SQL. The PROCESS statement is basically the same whatever the data organization,
although with SQL there are some additional options.
In this case the
statement includes the WHERE option
PROCESS
IN1 WHERE (IN1.Region > 5)
As each record is read it
is tested to see if IN1.Region is greater
than 5. If not, the record is discarded and the next one read. When all records have been read then the
statements after END PROCESS IN1 would be
executed, if there were any. We could, for example, write
…
END
PROCESS IN1;
PRINT('End of Report');
to have this print after
all the selected records have been printed. However since Jazz does this for us
anyway there’s little point in having it printed twice.
File IN1 was defined with
VB so the records are
in no particular order. If we want to produce a report with subtotals then we
need to ensure that the file is in the correct sequence, so we add an ORDER option to our PROCESS statement: -
PROCESS IN1
WHERE (IN1.Region > 5) ORDER(IN1.Region, IN1.District, IN1.Name);
This ensures that
we process all the records for IN1.Region = 1 before IN1.Region = 2, and so on. Within one Region, District will be in ascending
order, and within one Region and District, Name will be in ascending
order. Even when we believe that the
records are already in the correct order we should ensure that this is so with
an ORDER option.
If we want to
count the returned records we can add an INDEX option to the PROCSS statement.
The next statement is: -
GET
FR WHERE (FR.Region
= IN1.Region);
GET reads a
particular record. The file must have an organization type that supports direct
access: it must have type VSAM or SQL.
What if the
record you want can’t be found? For example
one of the input records in my test file has value IN1.Region = 9, but
there is no record in FR with FR.Region =
9. Jazz creates a dummy record for you
in memory: it will have value FR.Region = 9, other fields
in FR will be blank or zero unless they have a VALUE clause in their
definition. Because Name was defined
Name CHAR(30) Value('No Record found')…
then its
value will be set to 'No Record found' if Jazz has to create a dummy record.
With default
values like this there is usually no need to test for absent records, but if
necessary you can test $Found with logic like this: -
IF FR.$Found = False THEN
…
END IF;
Click
here for more information about GET, and here for
more information about IF.
We’re now at the point in the program where we’re processing a wanted record from IN1, having ensured that we’re reading the records in ascending order of Region, District, and Name, and we have matched this with a corresponding record from FR so that we have a region name in field Fr.Name. Now we have this PRINT statement: -
PRINT(IN1.Region, Fr.Name, IN1.SalesThisMonth
SUM, IN1.SalesYTD SUM)
BREAK(IN1.Region, IN1.District);
The PRINT statement starts by giving a list
of fields, with SUM added
to the fields that we want totalled. BREAK(IN1.Region,
IN1.District)
specifies the control breaks to trigger subtotal printing. BREAK must name all or a left subset of the fields of the ORDER option of the PROCESS Statement. For more about PRINT statements, click here.
Our program
is completed with the END PROCESS
IN1; statement.
Here is our
completed program: -
Clicking
the [Process] button causes the Jazz workbench to check our program, generate
COBOL, generate JCL to compile the program, and submit the program. As the workbench waits for the results
various messages appear at the bottom showing the progress of the job: when it
is finished the button [Job Results] is highlighted and it can be clicked to
display the job output.
Here is the COBOL program
generated from this brief Jazz program, and here is [part of] the report that this produces: -
Printed at 24
Apr 2016, 20:01:18
Report1 Page 1
JZ-INDEX Region
*--------Region Name---------* District *----Name-----* District BillingCycle SalesThisMonth *SalesYTD*
1
6
2
6
3
6
District
Subtotals
2,002.94 10,336.87
4
6
5
6
6
6
Several lines
removed
29
6
30
6
31
6
32
6
33
6
District
Subtotals
1,728.59 12,666.13
34
6
District
Subtotals
194.34 390.98
Region
Subtotals
16,003.34 20,161.57
Here we’ve
introduced the key concepts of Jazz.
·
MANASYS
Jazz is a programming tool that operates in the Windows™ environment, creating
programs and other objects for other environments, particular zOS™ and Micro Focus Enterprise Developer™.
·
The
Jazz workbench analyses the program that you write, reporting errors, colouring
it and indenting it to emphasis the way the syntax has been interpreted.
·
An
objective is to describe the business problem to solve as simply as possible,
without the need to state implementation details that are implied by the
problem statement. Jazz gets closer to this ideal than other programming
systems.
·
Jazz
data definitions provide a powerful tool to reduce redundancy, increase
consistency, and increase productivity. An objective is “Say it once”, so a
definition may give information like validation criteria and display formats
that may be ignored in one program (and hence cause no overhead) but are vital
in another. In the next chapter of this users’ guide you’ll see that they are
used to define interfaces with subprograms, and later you’ll see their use to
define interfaces with web services. You can define one field, group, or record
LIKE another, again ensuring consistency.
·
MANASYS
Jazz functions by creating COBOL, but users don’t normally need to work with
the COBOL any more than COBOL programmers need to work with the Assembler
Language that their COBOL program may provide.
Now return
to the Jazz Users Guide Table of Contents to learn
more about Jazz.