Jazz On Line Programming: Introduction
Automatic processing – at start
Default processing of AID keys
Writing an On-line Enquiry Program
Alternate
Indexes: DKEY and UKEY
Generic
keys and Wildcard characters
Next:
Complex Enquiries and Updating Files
One other thing – Displaying and Entering Coded
Fields
Prerequisite reading: Introduction to
Jazz.
Although
Jazz minimizes the differences, there remain substantial differences between
on-line and batch programming, and some new concepts will need to be learned so
we start with a general introduction to On-Line Processing Concepts. This
chapter should be read before the later sections dealing with more complex
enquiries and record updating are read.
Even if you are going to start straight away with Web Services and
Service Oriented Architecture and are never going to write Classical CICS
programs – i.e. using 3270-type screens – it is worth
quickly reading this chapter first. The
heavier stuff – more detail on handling 3270 screens and dealing with record
updating – is covered in the next few chapters, and I’ve tried to leave most of
this detail out of this chapter so that those who are going straight to SOA can
just get the minimum understanding that they need.
The most
obvious difference from batch programming is that an on-line program
communicates with a terminal. This has several important effects on the program
structure.
Firstly, terminal
communication is used to control the program. An on-line program establishes a
dialogue with the operator and is, in effect, continually asking the operator
what to do next. For example, a system may start by displaying a screen such
as:
XYZ COMPANY INVENTORY SYSTEM
CHOOSE
FUNCTION REQUIRED FROM LIST BELOW:
1. INSPECT INVENTORY
2. ORDER PART
3. MAKE UP CUSTOMER ORDER
4. INSPECT ACTIVITY FILE
SELECTION _
Depending
on the response from the operator, the program then continues along a
particular path. This may involve many further responses and operator
decisions. Typically the program spends microseconds
doing processing, and minutes waiting for a response: almost all of its time is
spent waiting. A terminal is a very slow device since its speed is that of its
human operator: even a simple interaction will require the operator to read the
screen, think about what they’ve read, and press a key in response. A more
complex transaction may require that the operator think about potential
responses, look up instructions and check information, perhaps with a customer
on the phone, while the terminal waits for the response. A complete transaction
such as making an airline booking may involve many interactions and may be
spread out over many minutes.
In
contrast, batch programs are written to process many transactions with minimal
operator intervention. A typical batch program will read a file and produce a
report: once started it will spend significant time doing its processing before
its output is ready to be read, and any waiting time (for the next record) is
minimal. The processing/waiting ratio is minutes/microseconds, the reverse of
the on line situation.
This makes
the structure of on-line and batch systems very different. For example, an
on-line system must be capable of changing rapidly from one task to another,
usually doing very little in each task. Since there may be an enormous number
of possible permutations of task sequence, an efficient mechanism for passing
control from one task to another is important.
Secondly,
an on line system may have hundreds or even thousands
of users using the system at the same time. Imagine a travel agent making an
airline reservation, a process that may take up to half a
hour as the travel agent discusses flight options with the customer in front of
them or on the phone. In the meantime, other agents around the world are also
making reservations, possibly on the same flight. An on-line system must be
written so that this is taken into account. Each user must be able to use the
system as if they were its only user. While waiting for the response from one
user, the system goes on with servicing others. When the response is received,
the system must be able to continue as if uninterrupted. In the meantime, other
users may have updated information in files accessed by the first user. The
on-line system must therefore be able to cope with potential problems which
arise when two or more users attempt to update the same record.
The on-line
system must also cope with the problems of potential system failure. What
happens if the system fails while several users are in the middle of
transactions which can update files? With a batch system the job can be rerun
using the original inputs. Only with unusually long processes or very large
databases is it necessary to provide a specific recovery mechanism other than
restoring files to their initial state and rerunning. Contrast this with an
on-line system where actions may have been taken and decisions made on the
basis of inputs which no longer exist.
These
problems are common to all on-line systems, and so a standard solution is
supplied by IBM. Instead of each application programmer having to individually
code logic for rapid task switching, data sharing, recovery, and all the other
common features of on-line systems, it is taken care of by a standard
teleprocessing system, CICS. On-line programs are therefore written as tasks
for this system, whether they are “green screen” applications typical of
1970-style systems, or web services supplying data to clients which might be
Windows programs, web pages, or mobile apps.
We’ll illustrate the process with a few very
simple programs. The simplest way of
creating an On-Line Jazz program is to click the [New] button, select the
program type and set a few other details, and have Jazz create it for you. We’ll do this as we create a menu program
that invokes one of three other programs, a Customer Enquiry, Customer Update,
or Order enquiry/update. This is about
as simple as it’s possible to get: the menu doesn’t have to look up files, let
alone edit them. All it has to do is to show a screen offering choices, and
then do something depending on the operator’s choice. At the start we have neither the program, nor
the screen: we’ll develop both.
1. Click the [JazzGen] button: -
After prompting you to save the current program, Jazz responds with the
“New” screen. Expand the categories at the left until you find what you’re
looking for, which in this case is “New CICS Program”: -
2.
Click “New CICS program”. Jazz
responds with a screen with options for this kind of object: -
We
a.
Give
the program name. You’d check the
Replace checkbox if it already existed and you wanted to replace it. In this case we’ll call the program MENU1
b.
The
screen name and commarea name will be given by
default by adding “S” and “C” to the program name. We may as well accept these
defaults.
c.
Enter
a transaction code (TRANSID) that will initiate this program.
d.
Select
the program type: we want Basic.
e.
Select
the screen type: 3270 or Web page. Since (in 2015) the only option is 3270,
we’ll choose that.
f.
Click
[Finish]
That’s it!
Jazz will first create the Commarea, then it
creates the screen, and then the program.
The next thing that we see is the generated program: -
The first thing that we do is to edit
MENU1C, the COMMAREA definition.
Right-click on the keyword COMMAREA to see: -
Menu1 will have three alternatives, and
we’ll be asking the user to enter a number 1, 2, or 3. We add a definition for a suitable field: -
DEFINE
MENU1C COMMAREA
DATA(
Function PIC '9' RANGE(1:3),
JZ-XCTL CHAR(1) BOOLEAN);
The other field, JZ-XCTL, is a CHAR(1) field that may have value “Y” or “N”.
It is used by Jazz, so you should not remove it.
Now we return to our program and click
[Screen]. We can see that Jazz has
generated a screen, but it’s essentially empty, so we edit it to provide the
menu function that we want. Mostly this
is just typing text on to the screen, until we get to the point where we want
to put the function code on to the screen.
To put this field into the screen we
1.
Expand the MENU1C definition
2.
Drag the field Function from this definition on to the screen
Note that when we dragged Function on to the
screen the drag-and-drop created three fields: a constant “Function” that is
the field’s name (or HEADING) from its
definition, an input field with the correct format, and an asterisk. When the program is running the asterisk is
normally hidden, but it will become visible if a user enters an invalid
function value.
Any of these constants or fields can be dragged
around the screen if we’ve put them in the wrong position. Swipe the area you want to move: -
then hold down <ctrl> while clicking on
one of the objects in the selected area.
The selected items are highlighted: -
and can now be dragged to any empty area of the
screen. (“Empty” includes the current
position of the selected items, so you can easily drag them a character or two
left or right).
When we’ve got the screen edited to our
satisfaction we click [Save] or [Process] to return to our program. [Save] saves the screen locally, creating a
screen description that we can re-edit at any time. [Process] also does this, but for ZOS users
it also submits a job to the zOS system to compile
our screen (CICS calls it a “map”), a necessary step before we can use it. If we click [Process] then as we continue
with the next step, editing the program logic, you’ll see the job submission messages
appear at the bottom of the Jazz workbench until [Job
Results] turns green. When this happens
you can inspect the returned job, which will be a BMS assembly. If you’re not a ZOS user but are using Micro
Focus [Save] is sufficient, and the screen will be compiled when you build your
COBOL project in Visual Studio.
Returning to our program we write the logic to
do what we want: -
1.
We
start by writing “Accept (Function);” which Jazz
changes to ACCEPT
(MENU1S.Function); when the program is checked. This moves Function from
the screen to MENU1C, but even more importantly it checks it – that it is
numeric, and in the range 1 to 3. If an
invalid value is entered then the “*” becomes visible and a message such as
“Function Not Numeric” will be put in the error field at the bottom of the
screen.
2.
Now
all we need to write is logic to invoke the various programs for options 1, 2,
and 3. The CASE statement is ideally
suited to this kind of logic.
I wrote my program like this: -
*# Last Updated by IBMUSER at 5/1132014 10:05:10 am
PROGRAM MENU1 CICS INSCREEN(MENU1S) TRANSID(MNU1)
COMMAREA(MENU1C) ;
Accept Function;
Case Function;
When 1
exit to CICS1;
when 2
exit to CICS2;
when 3
exit to CICS3;
end case;
On clicking [Check] MANASYS qualified names, inserted missing punctuation, and identified keywords and fields: -
Click [Process] and the program is submitted to
zOS to be compiled.
If we have also processed the screen then we’re almost ready to test our
first CICS program. Before we look at
this, we should take a little time out to look at what’s going on.
In contrast to batch programs where the heart
of the logic is a PROCESS
statement controlling an I/O loop, on-line
program logic is executed once: basically
Process
the Input data. “Input” is the input
screen and the Commarea (if any)
SEND
a response
Once we have sent a response the system has to
wait for a reply. Even when the user is
very fast this will take many seconds, and it might take minutes. We don’t want our program waiting for a reply
because this will lock up resources that other users may need, so Jazz CICS programs are “pseudo-conversational”. In other
words, the program terminates as soon as it displays another screen (SEND) or exits (EXIT). If you want to save any data for
later you must save it explicitly by putting it into a special area called
COMMAREA. We may not need to bother with this as Jazz may handle this
automatically as it does here, but later we’ll see examples where COMMAREA
needs to be used explicitly.
We started our program with
PROGRAM
MENU1 CICS INSCREEN(MENU1S) COMMAREA(MENU1C) TRANSID(MNU1);
INSCREEN
means that when this program initiated it
expects an input screen, described by the layout (“Map” in CICS) MENU1S. Jazz
therefore automatically creates logic to read this screen. However
what if the screen hasn’t been sent?
This will be the case if program MENU1 was initiated from an empty screen with just a CICS transaction code?
The program therefore tests that there is something in the screen, sending a
blank MENU1S screen to itself if there is not. It also sends this blank screen
if the user presses the PF3 button. In effect our program starts with
IF
EIBCALEN =
0 THEN
SEND MENU1S ERASE;
END IF;
However this is not visible in our Jazz
program (we’d have to look at the generated COBOL). If the logic gets past this
initial test then the program will read the screen.
All this is automatically generated into your
program because you included INSCREEN(…) in your PROGRAM statement, so you don’t need to worry about it. From the first
statement that you write you can assume that there is some data in the INSCREEN record. Of course this
doesn’t mean that every field in this record has data, or that the data is valid.
Another thing that we might need to think
about: what if the user doesn’t press [Enter].
Normally we’d expect them to enter some data into the screen and press
[Enter], but they may press a function key:
PF1 to F12 or Clear. Keys other
than [Enter] are called “AID” keys, and you may want your program to do
something special if they’re clicked. If
you don’t think about this Jazz will provide defaults: -
PF3
= “Return”. The initial screen will be
redisplayed as if you hadn’t pressed Enter
PF12
= “Exit”. The program will be
terminated, either back to a clear screen or to the CICS program that invoked
this one.
Clear. The screen will be cleared except for a
message “Enter transaction code” and you can start again.
When relevant, Jazz will also provide defaults
for PF7 (up), PF8 (down), PF10(Previous), and PF11(Next).
Other Aid keys will cause a response: -
“Invalid
Key Pressed”
and the user can try again.
If you want to provide particular handling for
an AID key you simply write a HANDLE statement. For example
HANDLE PF4 PF5;
MENU1S.ERROR = 'PF4 or 5 pressed';
SEND SCREEN MENU1S ALARM;
HANDLE ENTRY;
Write
your normal logic here
At the logical
end of our program Jazz generates appropriate logic to terminate the program and
return control back to CICS. Our program will almost always terminate through
its “Normal Exit”, and probably do something like sending a message back to the
user. However every time that a Jazz program uses a
CICS command or an I/O command it will check to see that everything worked
normally. If an error has occurred the
program will exit through its “Abnormal Exit” where messages will be displayed
before the program terminates.
Situations
like: record can’t be found, input data is not valid, and so on are routine and
will be handled by logic such as IF
CUSTF.$Found THEN … and within the logic handled by ACCEPT
statements. These are not “Abnormal
Errors”, and the program exits normally.
The logic that we write will be between these
two automatic parts. We will write logic to handle the normal return from the
screen – when the user enters some data into the screen and presses Enter – but
we’ll also want to deal with various other situations also such as dealing with
keys other than [Enter]. Typical CICS logic therefore tests for a number of
response situations.
With a batch program Jazz could generate the
necessary JCL (Job Control Language) for the GO step and so when we submitted
our job it just ran, producing the report or output file or whatever it was
supposed to do. With a CICS program
there is still slightly more that we need to do before we can try out our
program. The first time that you do this
you may need a little help from your system programmer as your local rules may
be a little different to mine. You may
be using z/OS directly, or using a simulated z/OS system such as Micro Focus,
and if so the details will differ, although the
general principles will be the same. In
these sections I’ll describe the basic z/OS procedure. Consult the Users’ Guide section on Micro Focus for information about this
environment.
Firstly, you need to know how to start, use,
and stop your CICS test system. Your
system may be different, but with my basic z/OS system: -
1.
To
start CICS I log into zOS/TSO. I go to ISPF option SD, enter command /S
CICSTS51,START=INITIAL This will respond with “NO RESPONSE
RECEIVED” but if I check with the ST command I see that task CICSTS51 is
running.
2.
To
use CICS I start another z/OS TN3270 emulator session and select “CICS”. A splash screen is displayed, I clear this,
and I can then enter CICS commands (transaction codes) like CEMT, CEDA, etc,
plus any transaction codes that I’ve defined for my application. Initially of course there are only the CICS
commands.
3.
To
stop CICS, from the CICS session enter transaction CEMT P SHUT,IMM
So far our program
MENU1 and its screen MENU1S have been compiled into our CICSLOAD library. For me this is IBMUSER.MANAJAZZ.CICSLOAD. To start using them with CICS we must define
them to CICS. We do this with CICS
command CEDA. I entered these CEDA commands: -
·
DEF
PROGRAM(MENU1) GROUP(MANAJAZZ)
·
DEF
MAPSET(MENU1S) GROUP(MANAJAZZ)
·
DEF
TRANS(MNU1) PROGRAM(MENU1) GROUP(MANAJAZZ)
·
DEF
LIBRARY(MANAJAZZ) DSNAME(IBMUSER.MANAJAZZ.LOADCICS)
GROUP(MANAJAZZ)
·
INSTALL
GROUP(MANAJAZZ)
When you configured MANASYS Jazz you would have
downloaded and compiled several subprograms into the CICS library – JZBR14,
JZMSAD, etc. See JazzSetupSupportRoutines.htm for the current list of these
modules. You should add DEF PROGRAM….
Statements for all the CICS programs that you might need, which includes
JZABNDC, JZABNDW*, JZBR14, JZDT01, JZDT02, JZDTAR, JZDTVL, JZDTVL2, JZDTVS,
JZHASH*, JZLIKE, JZNXTKY, and JZTRIM.
JZABNDW and JZHASH are only needed for CICS web services, JZDTxx are only needed for various DATE functions, and
JZLIKE, JZNXTKY, and JZTRIM are used for particular types of logic, but it is
harmless to include them in the group when they are not wanted, and definitely
not harmless to omit them when they are needed.
If the program or layout (mapset)
has already been defined to CICS for this group then you’ll get error messages
from the CEDA step. See Re-Testing our CICS Program below.
CEDA operands can be abbreviated: DEF is short
for “DEFINE” and “TRANS” is short for “TRANSACTION”. You only need to write enough of the operand
to make it unique: I could have written “GR” for “GROUP”, “MA” for “MAPSET”,
“PROG” for “PROGRAM”, “LIB” for “LIBRARY”, and “I” for “INSTALL”.
CICS Objects are defined in groups. The name is arbitrary: I suggest that you use
as group name the name defined in your Jazz Configuration: -
You should put related objects into the same
group. In my tests I’ve put everything
into group “MANAJAZZ” which is defined by its first occurrence: DEF PROGRAM(MENU1) GROUP(MANAJAZZ) first
defines the group, then defines the program into it. Note that as well as naming the group
“MANAJAZZ” we can also use this name for other objects within the group: for example here the library is also called “MANAJAZZ”.
Finally the group is installed: this makes everything defined into it available
to CICS. We can now clear the screen,
enter the transaction code “MNU1” and our program displays its screen:
We can respond to a screen by entering data –
in this case choosing option 1, 2, or 3 – and pressing [Enter], or we can
respond by pressing one of the function keys like PF3, CLEAR, etc. Jazz default logic will handle any of the
function keys. Click here to learn about this
default handling, and how to override it if you need to.
IF we enter an invalid value like 4 or X then there
will be an error message and the program will wait for a correct value.
Since we haven’t yet written any of the
programs, if we enter 1, 2, or 3 our program will attempt to call them and
fail, causing program Menu1 to trap the error and respond with an error
screen.
Just in case you’re interested, here is the COBOL program generated by Jazz for this menu
function, and here is the code to create the 3270 screen.
Fortunately you’ll rarely, if ever, need to
work at this level of detail.
If you’re like me, as soon as you start testing
your program you’ll want to change it. Perhaps it doesn’t run at all and there are
errors to be corrected. Or you see some
minor changes – a spelling mistake in the screen text, for example. With a
batch program you simply re-compile and re-run the program, but with CICS
programs you have to tell the CICS system that there is a new copy of the
program or screen. We do this with the CICS command
CEMT
SET PROGRAM(name) NEWCOPY
where “name” is the name of the program that
you’ve just changed.
The same applies to the MAPSET: if you change
the screen enter (for example)
CEMT
SET PROGRAM(CICS1S) NEWCOPY
Note that the command is “SET PROGRAM”, not
“SET MAPSET”.
Our next program is about as simple as an
enquiry program can be. We want to
display a screen that asks which record we want to see, then responds by
displaying that record. So we could write a program
that asks for an account number: -
But will the user know the account number? Perhaps they only know the customer’s
name. We can hardly send the customer
away to find out their account number before we can tell them whether there’s
any money in their account! We want to
write the program so that we can look up the record by EITHER the account
number or their name. This is easy if
we’ve defined alternate indexes with our file.
To provide lookup by either Account or Name is very easy. We do this by defining an alternate index in the record definition with the DKEY or UKEY property. Here is the definition of CustF: note the definition of Name (highlighted): -
*# Last Updated by JAZZUSR at 29/10/2021
2:04:01 PM
COPY Types;
COPY FR;
DEFINE CustF VSAM DATA(
Account PIC '999999' KEY,
Region DECIMAL(3) EXISTS FR.Region,
#388 E FR.Region and CustF.Region
have different types
District DECIMAL(3) RANGE(1:10),
Name CHAR(30) CAPS DKEY 'jazzuser.vsam.custf1',
SalesThisMonth MONEY(7,2),
SalesYTD MONEY(7,2),
Billingcycle LIKE Types.Month,
DateCommenced DATE)
DSNAME 'JAZZUSER.VSAM.CUSTF';
DKEY means “Duplicate key”, meaning that there might be several records with the same value of Custf.Name. UKEY is less common: it means “Unique Key” and would be used for fields like Social Security Number that are unique, but are not the record’s primary key. There would not be two customers with the same Social Security Number, and an attempt to create a second record with a value already used would raise an error.
With a VSAM record DKEY and UKEY specify an alternate index, so we must use IDCAMS to create the index and path. Jazz can do this for us from the definition above: from the Jazz workbench use menu New/Data/VSAM, and follow the dialog. A job somewhat like this will be submitted: -
//IBMUSERL JOB ,CLASS=A,MSGCLASS=H,NOTIFY=&SYSUID,COND=(8,LT)
//*** THIS JOB IS FOR MANAGEMENT OF VSAM
FILES.
// SET
MEMBER=DTREGN
// SET SOURCE=IBMUSER.MANAJAZZ.SRCLIB
//*
//STEP1
EXEC PGM=IDCAMS
//VSAMOUT DD DSN=IBMUSER.VSAM.CUSTF,DISP=SHR
//SYSPRINT DD SYSOUT=*
//SYSIN
DD *
DELETE IBMUSER.VSAM.CUSTF1
DELETE
IBMUSER.VSAM.CUSTF1.AIX
DEFINE AIX
(NAME(IBMUSER.VSAM.CUSTF1.AIX) -
RELATE(IBMUSER.VSAM.CUSTF) -
TRACK(10 10) VOLUMES(VPWRKA) KEYS(30 10) -
NONUNIQUEKEY UPGRADE REUSE)
DEFINE
PATH (NAME(IBMUSER.VSAM.CUSTF1) -
PATHENTRY(IBMUSER.VSAM.CUSTF1.AIX) UPDATE)
BLDINDEX INDATASET(IBMUSER.VSAM.CUSTF) -
OUTDATASET(IBMUSER.VSAM.CUSTF1.AIX)
/*
Note that with DKEY and UKEY options you may give the path name: here we’ve written DKEY 'ibmuser.vsam.custf1' and in a batch program there’d be a DD statement for the path,
//CUSTF DD DSN=IBMUSER.VSAM.CUSTF1,DISP=SHR.
If we omit this then Jazz will find the file name “custf” at the end of the DSNAME option and append 1, 2, 3, etc to it as it finds each alternate index option in the definition. Making the path name explicit is recommended.
Note also that Name has been given the property CAPS. For key fields this is recommended, otherwise records with Name=”Robert” might be different to records with name “ROBERT”.
One more thing before we go ahead and re-generate program CICS1. The program will now look up CustF by either Account or Name. Here are the first few records of our test database, sorted by Name: -
1Printed at 30 Oct 2021, 11:08:10 RepNbr1 Page 1
0Account *------------Name------------* Region *--------Region Name---------* District SalesThisMonth Billingcycle DateCommenced
0 000001 BANFIELD, Nora Joyce Annie 5 Canada 6 $5,817.53 Sep 28 Feb 18
000002 BARKMAN, Olivia Martha 9 South America 5 $806.60 Feb 28 Feb 18
000003 BARNES, Albert Paul 4 United States of America 2 $391.00 Nov 28 Feb 18
000004 BARNES, Ann 9 South America 4 $8,365.22 Jul 28 Feb 18
000005 BARNES, Arthur Cyril 7 No Record found 6 $7,571.57 Aug 28 Feb 18
000006 BARNES, Caroline 6 France 6 $2,791.39 Nov 28 Feb 18
000007 BARNES, Edward John 6 France 4 $6,122.00 Jul 28 Feb 18
000008 BARNES 7 No Record found 7 $123.48 Jul 28 Feb 18
000009 BARNES, Hannah Francis 9 South America 4 $8,146.51 Oct 28 Feb 18
000010 BARNES, Harold Victor 9 South America 4 $8,274.53 Jun 28 Feb 18
000011 BARNES, Harriet Francis 10 Africa 4 $9,114.45 Nov 28 Feb 18
000012 BARNES, Henry Maurice 4 United States of America 6 $7,071.86 May 28 Feb 18
000013 BARNES, Henry 8 Italy 2 $3,558.19 Jun 28 Feb 18
000014 BARNES, Hilda 7 No Record found 2 $1,796.75 Jun 28 Feb 18
000015 BARNES, Jessie Crawford 6 France 8 $80.00 Oct 28 Feb 18
000016 BARNES, John William 7 No Record found 6 $4,282.59 Jul 28 Feb 18
000017 BARNES, John 6 France 5 $8,288.67 Aug 28 Feb 18
000018 BARNES, Melissa 1 New Zealand 3 $5,071.68 May 28 Feb 18
000019 BARNES, Olive Myrtle 6 France 5 $1,686.59 Feb 28 Feb 18
000020 BARNES, Sam 4 United States of America 2 $9,790.19 May 28 Feb 18
000021 BARNES, Stephen 3 United Kingdom 6 $349.30 May 28 Feb 18
000022 BARNES, Thomas 8 Italy 5 $3,455.45 Mar 28 Feb 18
000023 BARNES, William Robert 2 Australia 5 $2,660.84 Apr 28 Feb 18
000024 BARNES, William 6 France 3 $6,226.49 Oct 28 Feb 18
000025 BARNES, William 9 South America 3 $8,630.92 Nov 28 Feb 18
000026 BENJAMIN, Albert 8 Italy 3 $9,237.37 Jun 28 Feb 18
000027 BENJAMIN, Amelia Beatrice 5 Canada 3 $9,308.07 May 28 Feb 18
We probably don’t want to have to enter “BARNES, Albert Paul” to read the first “BARNES” record, and our Jazz program doesn’t require us to. Instead, when the search field has format CHAR then Jazz assumes that we want to treat our input value as a GENERIC key: we enter “BARNES” and the program returns the record with account = 000003, and name of “BARNES, Albert Paul”. This is the default: we don’t need to do anything special to make this happen, and this default applies to any key with CHAR format including the primary key, not just to keys defined with DKEY or UKEY. However it doesn’t apply to Custf.Account as this has format PIC ‘999999’, not CHAR. Here we must enter a number, but we don’t have to enter leading zeros, these will be filled in automatically when we enter (e.g.) “3”.
If we want something different to GENERIC then we can add FULL or WILDCARD 'character' to the properties of NAME in its data definition,
Name CHAR(30) REQUIRED DKEY 'ibmuser.vsam.custf1'
WILDCARD ',',
or as an option of the KEY value within the GET statement
GET Custf KEY(Custf.name FULL);
FULL means that the full key length will
be used: now we would be looking for a value “Apthorpebbbbbbb” (“b” represents a blank character),
and without entering the exact name value we wouldn’t find any records. WILDCARD functions like GENERIC but requires the user to enter the special character (',' in this example) to denote the end of the search string.
As with Menu1, we start with New/Logic/CICS
Program. In the dialog
1.
Give
the Program Name, and accept the default INSCREEN and COMMAREA names.
2.
Give
a TRANSID value if we want the option of invoking this program directly
3.
Name
Menu1 as the Exit (PF3) action
4.
Set
program type 1 Table Enquiry
5.
Name
the file that it is to look up (Custf): -
Click [Finish] and Jazz will create our program
and screen for us! Here is Jazz program CICS1: -
There are a few features of this program that
need comment.
1. In
ACCEPT we normally separate fields with commas, e.g.
ACCEPT
(CICS2S.Account, Cics2S.name);
But
then the ACCEPT’s
validation logic would have required a value to be given for both fields. Because we’ve used OR then if a value is given for
CICS2S.Account any value given for Cics2S.name will be ignored.
2. Similarly
GET
Custf KEY(Custf.Account OR Custf.Name);
first
checks to see if there’s a value in Custf.Account that is not the default (zero). If
there is then it looks up Custf by Custf.Account. If not then it tests to see if there is a
value for Custf.Name and uses that.
There must be one or other value or else the ACCEPT statement would
have reported an error.
NOTE THE
IMPLICATION: you cannot have a record whose key value (primary KEY, DKEY, or UKEY) is its default value. Thus if you have
defined your record layout as
DEFINE
CustF TYPE(VSAM) DATA(
Account PIC '999999' HEADING 'Account Number'
KEY VALUE 1234,
then there could
not be a record with Account = 1234, and you could use a test
IF
CustF.Account = 1234 THEN;
to distinguish
whether this were a real record or not. Of course the normal default value is zero, meaning that if
you’d omitted the VALUE
property then you would not be able to create or access a record with CustF.Account = 0.
If we click [Screen] we see the screen that
Jazz generated for us. Name has been
moved from the list of general display fields to the search field area: -
Jazz has sent this off to be compiled on the zOS system. Of course we may want to change the default screen, in which case we’ll edit it an re-process it. And of course we may want to change our program logic, but at least what Jazz has generated for us is a start, and it may even be what we want.
So far so good: but what about the fact that
GET
Custf KEY(Custf.Name); might return several records? For example, searching for “Apthorpe” there are 8 possible records. GET can only return one at a time, and will return the first,
but what about the other seven? Again,
Jazz handles this completely automatically.
On recognizing a multi-record situation Jazz adds to our program:
-
1. A definition of
a Temporary Storage file: -
DEFINE
TS1 TYPE(TS) DATA(
Account LIKE CustF.Account);
2. An option TS(1) is added to the GET statement, making it
GET
custf KEY(CustF.Account OR CustF.Name) TS(1);
Jazz generates logic that, when a name value is entered and [Enter] pressed, reads the set of qualifying records (there are 8 for “Apthorpe”) and stores their primary key values in TS1. The first record is returned and (if there are more) PF11 (=Next) is enabled. The user can then move forwards and backwards through the list of eight records with PF11 and PF10. Here we’ve pressed “PF11 twice to be looking at the 3rd record: -
Once again, for your interest here is the COBOL program and the screen layout.
In this topic we’ve introduced the basic
principles of on line programming, showing you how to
write a simple enquiry program. The next two topics build on the knowledge that
you’ve gained here, showing you how to write update programs, and how to write more complex enquiries
and updates in which you bring together families of records such as a customer
record, and a list of that customer’s current orders. If you are interested in writing web service
programs and you’re not intending to write “classical CICS” programs using
3270-type screens you can probably skip these chapters and go straight to the
chapter on Service Oriented
Architecture.
Once again, for your interest here is the COBOL program and the screen layout.
Notice the
way that BillingCycle is displayed: -
In CustF BillingCycle is defined: -
Billingcycle
LIKE types.month,
LIKE types.month means that its definition is the same as types.month, which is defined: -
DEFINE
Types TYPE(SYSTEM) DATA(
Month CODES(January,February,March,April,May,June,July,August,September,October,November,December));
Coded fields are not unique to on-line programming, but they are particularly useful as they provide concise record layouts (in this case, requiring only a TINYINT variable which is a single byte), specify validation rules (must have a value from 1 to 12), specify a display format (one of the values “January” etc), and by defining a distinct data type they reduce our opportunity for programming errors.
When the field is displayed its value is converted to the display value “January” etc. We enter the value as 1 to 12.
As earlier,
before we can test our program we must add it to our
CICS application group with CICS command CEDA.
As well as the program, mapset, and
transaction, this is the first time that we have used the CUSTF file so this
must also be defined. We don’t need to
repeat the LIBRARY definition.
·
DEF
PROGRAM(CICS1) GROUP(MANAJAZZ)
·
DEF
MAPSET(CICS1S) GROUP(MANAJAZZ)
·
DEF
TRANS(TRN1) PROGRAM(CICS1) GROUP(MANAJAZZ)
·
DEF
FILE(CUSTF) GROUP(MANAJAZZ) DSNAME(IBMUSER.VSAM.CUSTF)
These are
added to the previous definitions, so that when we execute
·
INSTALL
GROUP(MANAJAZZ)
the whole group, programs MENU1 and CICS1 and all their associated objects, is installed.
We do this, then we either
Enter transaction MNU1 to display the menu, and select 1, or
Enter transaction TRN1
If we change the program then we need to execute
CEMT SET PROGRAM(CICS1) NEWCOPY
and if we change the screen
CEMT SET PROGRAM(CICS1S) NEWCOPY