Jazz On Line Programming: Introduction

Jazz On Line Programming: Introduction. 1

General On-Line Concepts. 1

Writing On-line Programs. 2

Generating a New CICS Program.. 2

Creating a Screen. 4

Basic Menu Processing. 6

On-line Program Logic. 7

Automatic processing at start 7

Default processing of AID keys. 8

Automatic processing at end. 8

Testing our CICS Program.. 8

Re-Testing our CICS Program.. 13

Writing an On-line Enquiry Program.. 13

Alternate Indexes: DKEY and UKEY. 14

Generic keys and Wildcard characters. 15

Handling Multiple Records. 18

Next: Complex Enquiries and Updating Files. 18

One other thing Displaying and Entering Coded Fields. 19

Testing our 2nd CICS Program.. 19


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

General On-Line Concepts

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:


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

Writing On-line Programs

Well 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. Well 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 its possible to get: the menu doesnt 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 operators choice. At the start we have neither the program, nor the screen: well develop both.

Generating a New CICS Program

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 youre 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: -


a.                   Give the program name. Youd check the Replace checkbox if it already existed and you wanted to replace it. In this case well 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, well choose that.

f.                    Click [Finish]

Thats 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 well be asking the user to enter a number 1, 2, or 3. We add a definition for a suitable field: -


Function PIC '9' RANGE(1:3),


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.

Creating a Screen

Now we return to our program and click [Screen]. We can see that Jazz has generated a screen, but its 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 fields 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 weve 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 weve 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 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, youll 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.

Basic Menu Processing

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.

Here is our complete program: -


Click [Process] and the program is submitted to zOS to be compiled. If we have also processed the screen then were almost ready to test our first CICS program. Before we look at this, we should take a little time out to look at whats going on.

On-line Program Logic

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 dont 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 well see examples where COMMAREA needs to be used explicitly.

Automatic processing at start

We started our program with


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 hasnt 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 clicks the PF3 button. In effect our program starts with





However this is not visible in our Jazz program (wed 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 dont 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 doesnt mean that every field in this record has data, or that the data is valid.

Default processing of AID keys

Another thing that we might need to think about: what if the user doesnt click [Enter]. Normally wed expect them to enter some data into the screen and click [Enter], but they may click 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 theyre clicked. If you dont think about this Jazz will provide defaults: -

PF3 = Return. The initial screen will be redisplayed as if you hadnt clicked 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


MENU1S.ERROR = 'PF4 or 5 clicked';



Write your normal logic here

Automatic processing at end

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 cant 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 clicks Enter but well 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.

Testing a CICS Program with z/OS

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 Ill 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: -

         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.

         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 Ive defined for my application. Initially of course there are only the CICS commands.

         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: -








If the program or layout (mapset) has already been defined to CICS for this group then youll 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 Ive 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. Well see other examples later.


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 clicking [Enter], or we can respond by clicking 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 havent 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 youre interested, here is the COBOL program generated by Jazz for this menu function, and here is the code to create the 3270 screen. Fortunately youll rarely, if ever, need to work at this level of detail.

Re-Testing our CICS Program

If youre like me, as soon as you start testing your program youll want to change it. Perhaps it doesnt 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


where name is the name of the program that youve just changed.


The same applies to the MAPSET: if you change the screen enter (for example)


Note that the command is SET PROGRAM, not SET MAPSET.

Writing an On-line Enquiry Program

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 customers name. We can hardly send the customer away to find out their account number before we can tell them whether theres 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 weve defined alternate indexes with our file.

Alternate Indexes: DKEY and UKEY

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: -


Account PIC '999999' HEADING 'Account Number' KEY,

Subgroup GROUP,

Region DECIMAL(3),

District DECIMAL(3),


Name CHAR(15) REQUIRED DKEY 'ibmuser.vsam.custf1',

SalesThisMonth MONEY(7,2),

SalesYTD MONEY(7,2),

Billingcycle LIKE types.month,

DateCommenced CHAR(10))

DSNAME 'ibmuser.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 records 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 will do this for us from the definition above: from the Jazz workbench click the [JazzGen] button, and choose function Data/VSAM, and follow the dialog. A job somewhat like this will be submitted: -






















Note that with DKEY and UKEY options you may give the path name: here weve written DKEY 'ibmuser.vsam.custf1' and in a batch program thered 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.

Generic keys and Wildcard characters

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: -

Account Number Region District *----Name-----* Billingcycle

000014 6 8 ABRAHAM,Abram March

000015 6 7 AGNUS,Agnes August

000016 6 3 AGNUS,Agnes December

000017 8 2 AKELANE,Robert January

000018 11 2 ALFRED,Albert August

000019 11 10 ALGIRDASOF,Olgi November

000020 2 2 ANDREW,Andrs June

000025 5 10 APTHORPE,Alice December

000023 8 5 APTHORPE,Benjam March

000021 7 8 APTHORPE,John April

000028 3 6 APTHORPE,Joseph *********

000024 10 4 APTHORPE,Robert March

000022 5 7 APTHORPE,Thomas August

000026 2 2 APTHORPE,WILLIA April

000027 11 7 APTHORPE,WILLIA August

000029 7 4 ARNAULT,Arnould June

000030 3 8 ARVO,Arvi June

000034 6 3 ATKINSON,Arnold January

000033 3 1 ATKINSON,Bertra *********

000035 5 1 ATKINSON,Joseph July

000032 6 10 ATKINSON,Kathle January

000031 4 4 ATKINSON,Regina January

000051 7 4 AXCELL,AlfredEd September


We probably dont want to have to enter APTHORPE,Alice to read the first APTHORPE record, and our Jazz program doesnt 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 Apthorpe and the program returns the record with account = 25, and name of APTHORPE,Alice . This is the default: we dont 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 doesnt apply to Custf.Account as this has format PIC 999999, not CHAR.


If we want something different then we can add FULL or WILDCARD character to the properties of NAME in its data definition,

Name CHAR(15) 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 wouldnt 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 before we may as well start by getting Jazz to generate our program for us. We start by clicking [New], then selecting New CICS Program, as we did with Menu1: -


The most important differences from Menu1: weve selected program type 1 Table Enquiry, and given the table name. Ive given a TRANSID value which will allow this program to be initiated directly as well as from Menu1, and Ive set up the exit to go back to Menu1 anticipating that this is the way it will normally be used. Click [Finish] and Jazz will create our program and screen for us!


Here is 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 well 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. Here is the program logic that Jazz generated: -

*# Last Updated by at 17/06/2015 2:15:39 p.m.


COPY Custf;



Account LIKE CustF.Account);

GET Custf KEY(CustF.Account OR CustF.Name) TS(1);

#373 I GET statement returns one record at a time for Name


IF Custf.$Found = 'N' THEN;

CICS1S.error = 'No Record Found';


SEND Inscreen;


There are a few features of this program that need comment.

1. Here, instead of separating the two fields with a comma weve used OR indicating that they are alternatives. If wed written

ACCEPT (CICS2S.Account, Cics2S.name);

then the ACCEPTs validation logic would have required a value to be given for both fields. Because weve used OR then if a value is given for CICS2S.Account any value given for Cics2S.name will be ignored.



GET Custf KEY(Custf.Account OR Custf.Name);

first checks to see if theres 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


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 youd omitted the VALUE property then you would not be able to create or access a record with CustF.Account = 0.

Handling Multiple Records

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: -


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] clicked, 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 weve clicked PF11 twice to be looking at the 3rd record: -


Once again, for your interest here is the COBOL program and the screen layout.


Next: Complex Enquiries and Updating Files

In this topic weve 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 youve 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 customers current orders. If you are interested in writing web service programs and youre 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.

One other thing Displaying and Entering Coded Fields


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: -


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.



Testing our 2nd CICS Program

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 dont need to repeat the LIBRARY definition.







These are added to the previous definitions, so that when we execute


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


and if we change the screen