ISPF Programmers Guide
ISPF Programmers Guide
Analog Computing
Bernd Ullman, 2013
ISBN 978-3-486-72897-2, e-ISBN 978-3-486-75518-3
Author
Franz Lanz
Panoramaweg 27
72658 Bempflingen
Germany
ispf@lanz.de
ISBN 978-3-11-040753-2
e-ISBN (PDF) 978-3-11-040761-7
e-ISBN (EPUB) 978-3-11-040765-5
Set-ISBN 978-3-11-040762-4
Library of Congress Cataloging-in-Publication Data
A CIP catalog record for this book has been applied for at the Library of
Congress.
Bibliografische Information der Deutschen Nationalbibliothek
Die Deutsche Nationalbibliothek verzeichnet diese Publikation in der
Deutschen Nationalbibliografie;
detailed bibliographic data are available on the Internet
at http://dnb.dnb.de
© 2015 Walter de Gruyter GmbH, Berlin/Boston
Cover illustration: OlgaYakovenko/iStock/thinkstok
Typesetting: PTP-Berlin Protago-TEX-Production GmbH, Berlin
www.degruyter.com
Preface
Since approximately 1980, I worked many times with the Interactive System
Productivity Facility (ISPF) (a subsystem of z/OS driven by TSO) during my
activities as external advisor, programmer and lecturer in the IBM host. As the
name already says, this subsystem is designed to help the users in the IBM
Mainframe host environment to a higher productivity at their work in IBM
z/OS. I can promise you, ISPF fulfils this task very well.
As soon as I was more familiar with ISPF and so had outgrown to the beginners
stage, the desire emerged in me to automate and accelerate some recurring
operational sequences if possible. I have looked around myself on the book
market which book can support me with the realization of the desire on a high
level. However, I found no book, which would be suitable.
Since I developed at home and abroad a set of procedures and programs during
my lecturer, adviser and programming activities in different enterprises, which
brought me often a substantial accelerations of my work in z/OS, I decided to
publish my experiences in developing ISPF applications as well as the
developed programs in this book. This program collection is SMART ISPF
UTILITIES called. The procedures and programs described in this book can be
from internet downloaded.
This book will support you to reach your full potential in using ISPF as an
application programmer, a system programmer or another z/OS-ISPF user. You
will learn how you use the ISPF programming facilities to develop professional
ISPF application programs. Additionally you can enhance your programming
skills by referencing the programs of SMART ISPF UTILITIES available on
internet, in order to become a skillful ISPF application programmer.
Franz Lanz
Bempflingen, Mars 2015
Contents
Preface
1 Introduction
1.1 Users of this book
1.2 The significance of the REXX programming language in z/OS
1.3 Brochures for programming ISPF applications
1.3.1 The REXX programming literature
1.3.2 ISPF reference books
1.3.3 TSO reference books
1.3.4 The ISPF services
List of programs
List of tables
List of screens
Bibliography
Index
1-Introduction
1.1-USERS OF THIS BOOK
This book has been comprised for ISPF users with programming skills. You will
learn how to insert and use your own functions in the ISPF using the procedure
language REXX together with ISPF programming facilities.
These chapters are only of interest to programmers who want to use REXX
programs under special conditions as there are:
–Calling subroutines written in Assembler language.
–Calling REXX programs by programs that are written in other languages.
–Writing REXX execs to perform MVS operator activities.
The father of the REXX programming language Michael Cowlishaw wrote this
book. It contains descriptions of all elements of the language without describing
implementations in single carrier systems. I use this book often for creating
REXX programs, because it is also helpful to create REXX programs under MS
Windows just because it only contains the description of the REXX language and
nothing else.
1.3.2- ISPF reference books
Of course, for such a big subsystem as the ISPF many reference books are
available. You can find these books free of charge in IBMs internet book
libraries. They are available in two types:
1.As PDF books for downloading to your PC.
2.For direct display with an internet browser.
In the following chapter, I will show you where you can find all information to
develop ISPF applications. Unfortunately, IBM changes methods from time to
time to find a certain type of reference book. You can use the following steps:
1.With the following URL you reach the general z/OS literature frame:
2.http://www-03.ibm.com/systems/z/os/zos/library/bkserv/
3.You can click on the line z/OS V2R1 documentation in PDF format. This
action leads you to z/OS V2R1 Elements and Features selection menu. When
a new release of z/OS appears, the text V2R1 may change.
4.Now press Cntrl+F and enter the search text ISPF. The browser positions the
cursor on z/OS ISPF.
5.Click on this line and see the group of available ISPF publications.
6.Click on the book you want and the book is opened in your PDF reader. You
can now save it on your PC for later use.
Under this link, you will find ONLY ISPF reference books. However, also earlier
releases are listed.
Table 1.1 on page 4 shows the ISPF reference books designed for ISPF
programming purposes and their form numbers for z/OS release V2R1:
Table 1.1: Reference books for the programming of ISPF applications
Hint:
If you are searching for a book using the form number, then you should use only
the basic number without the release appendix. The system then shows all
available titles and you can choose the proper exemplar.
The following listing shows such manuals you should have as an ISPF
programmer:
The REXX programming language has been designed with just one objective. It
has been designed to make programming easier than it was before, in the belief
that the best way to foster high quality programs is to make writing them as
simple and as enjoyable as possible. Each part of the language has been devised
with this in mind; getting the design right for people to use is more important
than providing for easy implementation.
A programming language is a complex structure, typically characterized by its
most visible aspect – its syntax. Of equal importance is its semantics, the meaning
behind the instructions. But perhaps most important of all is the philosophy
behind the language – the guiding principles that governed the decisions made as
the language was designed.
Guideline for the development of REXX
I met Michael Cowlishaw at the 25th anniversary of REXX and he told me that
during the development of REXX in the following sentence hung on the wall his
office:
Example:
TSO EXEC 'dsn(member)’
The EXEC command still knows a number of options that are only interesting
for special cases. See the command description in the manual TSO-E
Reference in chapter EXEC Command.
This is the same execution of the program compdate as shown in Screen 2.1 on
page 10.
For information about ISPF SELECT service, refer to the IBM ISPF Services
Guide. Information on the use of ALTLIB command, see section 7.5 ALTLIB –
Dynamic linking of EXEC libraries on page 126. The ALTLIB command also has
a display option. I once had the above program executed without the ALTLIB
DEACTIVATE command and then ran the command ALTLIB DISPLAY manually.
I received the following display:
Therefore, it is advisable to always start first at these points with actions for
performance improvement. You should not expect too much of compiled REXX
procedures because of the following reasons:
Performance tips:
1. Compiled programs:
The time needed to perform the called ISPF and TSO functions is usually much
higher than the execution time required for the pure REXX code. Thus, it is
usually not advisable to use compiled REXX procedures. I have gained this
knowledge from working in a very large project with hundreds of compiled
REXX programs.
Here you see an example of continuation lines in the definition of text literals.
Keep in mind that the continuation character in the resulting text appears as
blank. Therefore, you should always define continuation lines of literals so that
the resulting text contains a blank at this point anyway.
Example:
When you perform the statement:
Rule:
The resulting data type is only NUM when an admissible number in the sense
of REXX is assigned to it. Permissible blanks in HEX and BIN strings are
removed by the REXX assignment command.
Null strings:
A special type of data is the null string. This type of data is often assigned to
variables if no result of an executed command is present. The null string is
determined as a literal by two consecutive apostrophes. Null strings are of data
type CHAR and have a data length of 0 (zero). Examples of definition and query
of null strings:
2.8 - OPERATORS OF THE REXX LANGUAGE
The operators define the operations which with variables and constants are to
be performed. Types of operators:
–String operators
–Arithmetic operators
–Comparison operators
–Logical operators
Rules:
–If in a statement between the constants and variables there is more than one
blank, the result is at this point only a single blank.
–If you want to prevent the automatic insertion of blanks, elements with the
concatenation operator (||) need to be connected. Blanks that stand on the left
or right of the concatenation operator are ignored in this c5ase.
–If you want to insert multiple blanks, they must be defined as a literal in
quotation marks.
–The concatenation operator is not necessary when individual elements of the
statements can be clearly recognized by the interpreter.
Examples:
This program example shows how texts can be assembled.
Operator Function
+ Addition
- subtraction
* multiplication
/ Division
The + and – signs can be set as a sign in front of variables and constants.
Example:
When executed, the program produces the following list output: 3 1 -3 4 1 30%
2.8.3- Compare operators
Table 2.2: Compare operators
Operator Description
= Simple equal
== Strictly equal
Note:
The result of a comparison is always 0 or 1 and of type NUM.
Therefore, the result of a comparative operation is usable in arithmetic
operations.
What is the difference between the strictly and the normal comparison?
In normal comparison:
–If at least one of the compared values is of type CHAR then both leading and
trailing blanks are removed. Then the shorter value is padded with blanks until
it has the length of the other value. Then the comparison is performed.
–If both comparative values are of type NUM, one value is subtracted from the
other one. The result is then greater than zero, equal to zero or less than zero.
In strictly comparison:
–No padding of CHAR type values take place.
–Values of type NUM are compared character by character from left to right
rather than with a subtraction.
–Values of different lengths are always NOT equal.
Operator Description
Task:
The dataset user001.flight.data(flights) contains the flight log of the performed
flights. I wanted to know how many flights I have on the individual aircraft
types carried out and how many hours with each type. I did not know
beforehand how many aircraft types were used in total. During the program
run, the types must be successively detected and stored
Program 2.2: Program FLIGHTS to explain the using stems and EXECIO
ft_nbr. Due to the pre-definition statement ft_nbr. = 0 is this stem of type NUM. This
allows that 1 can added continuously to count the number of flights. The index
is always the name of an aircraft type.
ft_std. Due to the pre-definition statement ft_std. = 0 is this stem of type NUM. This
allows that the time of a single flight can be added continuously. The index is
always the name of an aircraft type.
This example also shows how stems are used for data set processing!
The EXECIO command reads all the records of the file in the stem save.. You
will now ask: Where is the information about how many records are read?
Rule:
All functions that populate a REXX stem from the outside with a variable
number of records, write the number of records in the index 0 (zero) of the
stem. In the above example, after the EXECIO command has been executed
contains save.0 the number of records read.
Advice:
If you are using texts in indices of stems, of course, you must be sure that you
address these variables properly. As an example, see Program 2.2: Program
FLIGHTS to explain the using stems and EXECIO on page 20.
As for all variables in REXX, also applies for STEMS the rule, that a stem variable
as long their own name in uppercase letters as content has until it gets explicitly
another content. This rule applies only when the stem was by a general null
string assignment not predefined. For clarification, we look at the following
examples:
The gray stem variables were not assigned to a value, so their names appear as
the content. When I initialize hugo. with null string the result looks like this:
See also the Remark in section 2.6 Variables in REXX on page 14.
In REXX a method was developed that is unrivaled and best in my opinion. You
can call this method a window or channel method. In order to understand this
method, we first need to look at a concept that plays a decisive role. These are
the external system environments. The correct name is Host Command
Environment.
subsys SUBSYS is the name of a host command environment. This name has a maximum of 8
characters and must designate a host command environment which is addressable in our
TSO/ISPF environment. SUBSYS can be specified as either a literal as well as just a name.
Example:
The following sample program shows a comprehensive application of the
ADDRESS command.
Program 3.1: Examples of ADDRESS command
The SAY commands in the above program produced the following output:
I hope that this example can answer all questions related to the application of
the ADDRESS command exhaustive. Now the question arises: How the
commands come to the right subsystems. The following chapter explains this.
Example:
The program section shown below indicates the beginning of one of my
programs. The special feature of this is that the program can be online directly
under ISPF or in TSO batch and without ISPF run. Since when running in batch
the STEPLIB DD statement for the load library is contained in the job, the ISPF
command LIBDEF ISPLLIB is not necessary in this case. Therefore, I use a
temporary ADDRESS command to run each LIBDEF ISPLLIB. Note the
continuation comma that is behind each address “ISPEXEC”, characterizing
the next line is still part of the address ISPEXEC and forms a complete REXX
command. I deliberately chose this example to make you familiar with the
intricacies of continuation lines related to ADDRESS.
The commands in lines 9 to 12 only apply when the program runs online
executed in ISPF. Lines 17 through 19 are TSO commands. Because I have not
changed the active host command environment since starting the program, TSO
is still active. Therefore, these external commands are sent to TSO. For
description of the LIBDEF command, see section 7.4 LIBDEF – Dynamic linking
of ISPF libraries on page 123.
Remark:
In many REXX program examples, you can see the following use of the ADDRESS
commands:
The value after address is a fixed value, not a variable. When you assign the
variables TSO or ISPEXEC a value, then has this no effect on the execution of
ADDRESS commands. You can put the name of the environment in quotes.
However, this is not required! If one has an environment using the ADDRESS ()
function stored in a variable, then you have to use the version address
(remaddr) to restore the environment. remaddr is the variable that was
assigned by the function ADDRESS().
Examples:
Note:
This technique works only if the actual host command environment
is TSO. Within all other permanently active host command environments, you
cannot work with this method.
Tip:
I have been accustomed for a long time, in principle; always keep in REXX
programs in which I use the three host command environments TSO, ISPEXEC
and ISREDIT the TSO as an active environment. In addition, use for the two
environments ISPEXEC and IRSEDIT the corresponding prefix. That makes a
little more work on the keyboard, but it makes me free from the obligation of
constantly having to remember the currently active environment. However,
this procedure is a matter of taste. Look for your own style!
Environment Function
TSO the environment in which TSO/E commands and TSO/E REXX commands
execute in the TSO/E address space.
LINKMVS an environment that links to modules on the same task level. This
environment allows you to pass multiple parameters to an invoked module,
and allows the invoked module to update the parameters. The parameters
you pass to the module include a length identifier.
LINKPGM an environment that links to modules on the same task level. This
environment allows you to pass multiple parameters to an invoked module,
and allows the invoked module to update the parameters. The parameters
you pass to the module do not include a length identifier.
CONSOLE the environment in which MVS system and subsystem commands execute.
To use the CONSOLE environment, you must have TSO/E CONSOLE
command authority and an extended MCS console session must be active.
You use the TSO/E CONSOLE command to activate an extended MCS
console session. See z/OS TSO/E System Programming Command
Reference, for more information about using the CONSOLE command.
CPICOMM the environment that allows you to invoke the SAA common programming
interface (CPI) Communications calls.
LU62 the environment that allows you to invoke the APPC/MVS calls that are
based on the SNA LU 6.2 architecture. These calls are referred to as
APPC/MVS calls throughout the book.
APPCMVS the environment that allows you to access MVS/APPC callable services
related to server facilities and for the testing of transaction programs.
Notes:
I will cover only the grey marked environments in this book. There are many
other host command environments available. One example is the environment
to DB2. You find information on this environment at the following
URL: http://mainframe-tips-and-tricks.blogspot.de/2011/12/sample-db2-
rexx-program.html.
SUBR Acquisition of call parameters and disassemble them with different methods. Calling the
subprogram OUT to show the results of decompositions.
19 Take the first parameter in the variable IP1. In this type of taking over, the parameter values
are translated in upper case.
23 This statement divides the text of the first parameter into up to four parts when at least four
terms separated by blank are present in the text. The dot at the end means that all parts of
the text that lie behind the four words are ignored. During the transfer, with “PARSE ARG”
the texts are not set in upper case.
27 Here IP1 is divided so that all the texts that are between commas are written in the
corresponding tags. If no comma is found in IP1, the entire contents of IP1 is contained in
variable A1.
29 Asks whether more than one parameter is passed. If so, then a PARSE ARG executes
processing two parameters.
31 Separation of two parameters into five variables. The comma between the variables x2 and
x3 signals the PARSE command that two parameters are passed.
name Specifies the name of the internal or external program which is called. If the name
is literally specified, then the program is only externally searched.
parameter This information includes the transfer parameters. Commas must separate several
parameters. The parameters must not be in brackets.
Example:
Active:
When the name SUB is in apostrophes, the system searches SUB in external
libraries only.
Rules:
–Internal subroutines must use RETURN to jump back to the command after
the CALL statement. With EXIT, the main program would leave.
–In external REXX subroutines is the command EXIT usable for return.
–If a subroutine is called with CALL and this program returns a value using the
command RETURN(value), this value is stored in the REXX special variable
RESULT. The calling program can use the variable RESULT to take over the
return value.
–When calling external programs no stems are transferrable. To solve this
problem, take advantage of the data stack of the TSO. See section 3.11 QUEUE –
Working with the TSO stack on page 53.
For examples of calling subroutines, See Program 3.2: ARGTEST – Example of
the parameter handling in REXX on page 31.
Functions
Internal and external programs can also be executed using a function call. This
happens because you use instead of the CALL statement the function call as
follows:
Name is the name of an internal or external program. In principle, you can call
any program as a function. Of course, this only makes sense for such a program,
which also returns a value. Note that this also may be a text string. This return
value can contain many different parts because it may be up to 16MB long! For
a technique how to divide the individual values of a return text that you can
easily determine this in the calling program, REXX provides elegant ways.
Example:
Notes:
The command LEAVE is not usable to leave a DO group! Note also that for each
DO, an END must belong. This means: DO and END must always occur in pairs.
This pairing is easy to control with the editors Colored Code facility (HILITE
command!).
3.4.2- The DO loop
The DO loop has a very wide scope for design. I would like to present some basic
examples here:
3.4.2.1- DO FOREVER
Here a never-ending loop is started. This variant is rare. The risk of program
loops is relatively high, because you have to safely exit the loop. You can leave
this DO loop using LEAVE or link them to a WHILE or UNTIL condition to leave
them in this way.
3.4.2.2 DO I = A TO B BY C
Explanation of values:
I is the loop index
A is the start value
B is the end value
C is the incremental step value
All these four values must be of type NUM. The values A, B and C can be the
result of a calculation expression.
Variations:
a) With a loop index without increment and end value
b) With a loop index, negative initial value, increment and end value
Use EXIT to leave a main program. If the EXIT command used is in an internal
subroutine, the main program is exited. If there is an external procedure
called, then only this will exited, but not the calling program.
expression This value is returned to the calling program. If the
calling program is the TSO, then this value must be
an integer number in the range of -2**31 to 2**31-1,
because in this case the value is set in the register 15
and then to the TSO returned. If the REXX program
was called in a TSO batch job, this return code is by
the TSO as a step return code returned to the MVS.
Example:
The following example illustrates this technique: I have written an external
subroutine called TEXIT, which consists only of the EXIT 999 command. In the
following program, this routine is once as a function and once called with CALL:
As you can see when TEXIT is called as a function, the return value is returned
in XXX and when called using CALL the return value is returned in the special
variable RESULT.
Command syntax:
RETURN expression
Example
The following internal procedure returns a 1 if the YEAR variable contains the
number of a leap year. Otherwise, 0 is returned.
Program 3.4: Function LEAPYEAR
In this case, the ISPF step ends in a batch job with the RC = 16. See also section
6.1 Execution of programs in a TSO/ISPF environment on page 105.
The operation and diversity of IF commands can best explained with examples.
So here are some examples of IF queries from some of my programs:
First example
Second example
Third example
In this example, you can see that in an IF command not only a DO group, but
also a DO loop can start.
Command syntax
INTERPRETexpression
expression The content of expression dissolves and the resulting REXX command executes
immediately. The expression is usually composed of literals and variables that
make up the command to execute.
Note:
A beginner in REXX programming may have some difficulties in defining
INTERPRET commands correctly. So I am going to show the operation of the
INTERPRET instruction using a few examples. As usual in this book, I take these
examples from some of my practice programs.
As you can see, original REXX commands as well as ISPF commands are
assembled. Since the latter have to be set in single quotes, the two delimiters (')
and (") are alternately used for literals so that useful statements are developed.
When the INTERPRET command translates and we assume that the ZSCREEN
variable has the value 4, then the following command sequence would run:
SQL_CN.3 contains the text PRI_DATE. Thus, the following statement executes:
I hope I have been successful inspiring you for the INTERPRET instruction! You
can use it when necessary to produce very elegant solutions. In addition, in
some cases it is simply essential! You can find such a solution in the REXX
program SPROFVAR – Load user ISPF variables on page 270.
Before I turn to this issue, I have to tell you how the REXX data and here
especially figures are internally stored. If you have ever programmed in a
programming language other than REXX, you know the effort you have to do
there to define your variables containing figures. Since there is binary data
which may be stored in fields of 16, 32 or 64 bits, there is decimal data with up
to 31 decimal digits. Add the different variants of the floating point data. Let
alone the different variants of the floating-point numbers. Fortunately, you can
forget it all in REXX.
How REXX figures internally stores:
REXX puts all the data in EBCDIC text strings. So also the data that contain
numbers. The numbers before they participate in arithmetic operations are
converted to an appropriate format that the underlying system can handle
and are converted back into text strings after completion of the arithmetic
operation. This happens for each arithmetic operation within a command.
For this very simple rule, of course there must be a defined width for the figures
so that the numerical representation remains manageable.
Example:
If the command X = 2/3 is executed then an infinite fraction occurs.
As in the REXX fractional numbers are not stored in words such as Short
Floating Point or Long Floating Point, where the number automatically by the
word length is limited, but as unpacked figures in EBCDIC format, an infinitely
long number would need to be stored here. This means, it must be set
somewhere how many significant digits are to be stored in such a number. If
the default width of NUMERIC DIGITS 9 were active, the number X would be
stored as EBCDIC characters in: 0.666666667. That is, for the storage of X, 11
bytes are occupied internally. The NUMERIC command is available with three
main functions, of which I will discuss only two.
Note:
As long as the numbers remain in a program below ABS(999999999), you do
not need to change the value of NUMERIC DIGITS. However, as soon as a
number generated during the program runs and goes beyond this number
space, you have the NUMERIC DIGITS to increase accordingly, or you get a
program abort. If you read all of this, one might be tempted, at the beginning of
each REXX program simply to enter the command NUMERIC DIGITS 50. This
would be likely to be on the safe side. However, here we must remember that
then all fractional numbers that have as many places stored after the decimal
point with 50 significant digits, and even worse, of course, also be calculated
using this width.
Example:
The following commands produce this result:
In order to understand this example, you have to realize that REXX normal
comparison operations (not the exact with the double operator symbol)
between two is performed such a way that first the second number is
subtracted from the first and then the result is compared with zero. If we view
the results shown in the above IF statements that are behind the NUMERIC
FUZZ 1, then this is due to the following effect: Because FUZZ is less than
DIGITS, the takes place before subtraction. From 4.9999 the integer is 5.
Tip:
If you ever need to perform extensive calculations with REXX for which
comparisons of fractional numbers happen to fail due to differences in the rear
decimal places that you do not expect, then you remember NUMERIC FUZZ.
The currently active values for NUMERIC can be displayed as follows:
PARSE Reads data from the terminal when programs execute online. In batch
EXTERNAL processing data are from DD SYSTSIN. If no data is available, then a null-string
will be returned.
ARSE NUMERIC Returns the currently active values for the three NUMERIC options DIGITS,
FUZZ and FORM.
PARSE PULL Reads the TSO data stack. If it is empty, this command works like PARSE
EXTERNAL.
PARSE SOURCE Returns information about the source code of the currently running program.
PARSE Returns information about the REXX interpreter, under which the program is
VERSION running.
Rules:
–In all PARSE commands, UPPER can be specified as the second word. Thus, the
results are returned in uppercase. Just like the ARG instruction, too.
–In the data to be fractionized, the blank plays a special role: If no separator or
placement points are given in the variable list, the separation is on the blanks
in the performed text.
–In the variable list, the point (dot) can be as placeholders for variables used.
For safety reasons, I always use the dot as the last variable position. This
collects everything possibly in the text that is still behind the positions I need.
Otherwise, this part would additionally be in the last assigned variable.
–Variables that have no values could be assigned during the fractionizing
contain null strings.
Let us now look at the different variants of the PARSE command in detail:
Example:
Based on the realization that you should have the opportunity in fractionizing
texts, this rule has been created to proceed in several steps in order to
completely fraction- ize differently structured texts. As a consequence, it may
be well useful to always assign the last variable throughout the rest of the text
without any compromises. You can then decompose this last variable in the
next PARSE step.
The numbers in the left column on the list refer to the respective PARSE
command line in the program. In the following text, I will explain the
functioning of each PARSE command of the program in detail
The function DATE provides the expression 28 Mar 2015. Here, since the
individual values are separated by a single space, you can use the blank as a
delimiter. This frac- tionizing would produce the same results if several blanks
were between the values
The command DATE("S") returns a value of the form YYYYMMDD. From this
expression, the values YYYY, MM and DD should separate. The touchdown 5
means that from there the allocation for the MM variable begins and 7 defines
the position where DD begins.
The value to be resolved is the same as in statement 12. The positioning of the
variables are with relative positions. The counting of the relative positions
starts at one. The touchdown +4 means that from there the allocation for the
MM variable begins. Because before no touchdown was defined, the characters
1 to 4 are to the variable YYYY assigned. +2 means that it is incremented to the
previously mentioned setting position, namely +4 to two positions, to
determine the variable dd.
The parsed value is in the form HH:MM:SS. The hours, minutes and seconds
shall be separated. In this example, I will use the specification of an absolute
position for the three values. This results in a kind of SUBSTRING selection.
Here, the start and end are specified for each variable. The definition for the
extraction is as follows: <start> variable name. The second value always
addresses the position behind the extracted value.
The parsed value is in the form HH:MM:SS. I work with absolute start positions
for the individual values. Dummy points (:) eliminate the colons.
The parsed value is in the form HH:MM:SS. Here the colons are as separators
used.
The parsed value is in the form HH:MM:SS. This is where the colons are used as
separators, wherein the separator is in a variable (assignment in line 34).
3.9.3- PARSE VAR
This type of Parse command is most often used. It differs from the PARSE
VALUE type where the parsed text needs to be in a variable. The PARSE VALUE
command from above now can be done like this:
Example of EXPOSE:
As you can see in this example from practice, not only simple variables are
contained in the EXPOSE option but also stems.
Rule:
In external subprograms, the option PROCEDURE is unusable, because the
variables are in the calling program anyway not known. If you copy an external
subprogram in a main program to improve the performance, you must always
make sure that the variables does not overwrite each other. In this case, you
should insert the PROCEDURE option behind the name of the inserted
subroutine.
This command always writes the records to the end of the stack. This means
that the last written record will also read as the last one when the stack is read
completely. This technique is referred to as first in first out (FIFO). If you
create a stack to create a file, then FIFO is always right. Namely, when a data set
is read, it is normally expected that the first read data record is the first in the
data set. A QUEUE command with no expression produces a blank entry in the
stack. This empty entry is required for various commands (e.g. the EXECIO
command) to recognize the end of data in the stack.
This command always writes the records before the first record in stack. This
means that the last written record is read first on reading. This technique is also
referred to as last in, first out (LIFO).
The following commands can read data from the stack:
–PULL
–EXECIO
–SUBMIT
–DSN (for execution of DB2 utility functions)
There are probably many more programs and systems that can be read from
the stack data. However, I have even used these.
Rules:
–The SELECT statement opens a set of condition queries. It must be terminated
with an END.
–The condition queries can consist of any number of WHEN statements that run
from top to bottom in sequence until one of the WHEN conditions is true.
–If the first WHEN condition is detected as true, then the following REXX
command will be executed. The SELECT sequence is at the END left belonging
to the SELECT statement.
–If none of the WHEN conditions are true, then the REXX command in the
OTHERWISE statements is executed.
–The OTHERWISE statement is mandatory. It must be inserted immediately
before the END statement belonging to the SELECT.
–Behind OTHERWISE any number of statements can follow without requiring
them to be included in a DO group.
–The interpreter only notices the absence of the OTHERWISE condition, if for
any current program run none of the WHEN conditions is true. In this case, a
program termination occurs. This means on this way you can install a time
bomb in your program. Therefore, you should never forget the OTHERWISE
statement before the END of a SELECT sequence.
–Once one of the WHEN conditions meets, then the following conditions are
ignored and their program code will no longer go through. If these skipped
commands errors contain such as wrong contents in numerical operations,
these errors are only recognized when these commands are actually be
executed.
–Behind the WHEN keyword all possibilities that the IF statement knows can
be used.
If you want to read something from the terminal, you have two options:
–You can define a small panel for the input of data. I always use this way when
I want to enter the user data on the screen. This offers much better ways of
setting of texts and the plausibility check of the entered values.
–You tell the user using the command SAY what to enter now and then issue the
command PULL.
Tip:
If you believe that you must always use the PULL command, then I urge you to
insert a query previously that determines whether the data stack is actually
empty. If necessary, you can clear the data stack before you use the PULL
command. It could look like this:
When I run this procedure online, I get the following messages on the screen:
I turned off tracing by the direct input of the command TRACE O. Thereafter,
the program runs normally to the end. How you see the VALUE = ... TRACE from
the calculation in the line, the individual calculation steps are listed in detail.
Tip:
I strongly recommend to practice intensively the TRACE command, because it
is a powerful aid in creating REXX applications.
3.17 - SIGNAL – JUMPING WHEN ERRORS
There are three main forms of the SIGNAL command:
SIGNAL label
SIGNAL ON errortype NAME label
SIGNAL VALUE expression
Using the first way you can jump directly to a label in the program. This use of
the SIGNAL instruction corresponds to a GOTO in other programming
languages.
Note:
I cannot remember having ever used the SIGNAL command to jump to another
location in the program, because I develop in REXX just GOTO free program
code.
With the second type, at the beginning of the program traps can be set to cause
the interpreter to jump there in the event of an error. The third type of
command can be specified as an internal branch address of a program in
expression. There is then jumped after EXPRESSION is resolved.
We now turn to the second part, the REXX functions. I will not discuss any
function that is described in the brochure TSO/E REXX reference, but only those
that are in my opinion often needed in practice. How functions are called, I have
explained already in the section 3.3 CALL – Call other programs on page 35.
There we already talked about the topics parameter input and return of the
results.
The REXX functions can be divided into groups by application area. I have made
the following division into groups for the presentation of the REXX functions in
this book.
Table 4.1: REXX function groups
Function:
Returns the currently active host command environment.
Format:
name = address()
Function:
The DATE function is applicable for two purposes:
–Return of the current date in different forms.
–Calculation of date values.
On the following pages, I will explain these two variants in detail.
Format:
today_date = DATE(format)
It returns the current date in the notation defined in the format. The possible
entries for format and the resulting return values are summarized in the
following table. Only the first letter is entered to define the format.
Table 4.2: Parameters of the DATE function
Base Days since January 1, 0001 without the present day. The format wd = date("B") // 7
can be used to determine the current day of the week. 0 is Monday and 6 is Sunday.
Month English name of the month in upper and lower case. For example, January.
Normal Date in the format: DD Mon YYYY. Mon is the short form of month: Jan, Feb, Mar, etc.
This is the default setting, if no parameter is entered.
Format:
result = DATE(format1,input,format2) Rule:
Rule:
The date specified in input is converted to the format specified in format1.
Format2 is mandatory; it defines the format of input. Input can also be a DATE
function.
Function:
The TIME function provides two ways to use it:
–Returns the current time of day.
–Starting and stopping the difference timing measurement.
Format:
Time = TIME (format)
The following table shows which options can be set with format and which
results TIME then provides.
Table 4.3:Options of the TIME function
Civil Time of day in the form HH:MMxx, where xx can be either am or pm. This is for American
time information.
Elapsed Result is the time in the form SSSSSSSSS.UUUUUU, where seconds are before the decimal
point and the decimals of seconds behind. With this form, the stopwatch is started. Each
subsequent call with this form gives the elapsed time back since the first call.
Long Returns the time in the format HH:MM:SS.UUUUUU. The digits after the decimal point are
microseconds.
Normal Returns the time in the form HH:MM:SS. This is the default.
Reset Specifies the time back since the start or the last reset of the timer and resets the stopwatch
to zero.
Format:
Number = QUEUED()
Format:
Number = SOURCELINE()
Example:
With the following DO loop, you can run through all lines of program code:
Format:
user = userid()
Format:
value = VALUE("XYZ"var)
Example:
The edit macro #TSOB from the SMART ISPF utilities submits REXX procedures
currently being edited to run in a batch. In this batch job either a variable
number of STEPLIB DSNs and a variable number of SYSEXEC DSNs can occur.
The SMART ISPF utilities program SPROFVAR stores this information into the
ISPF user profiles. The organization of the variable is as follows:
The profile variables SYSEXEC and STEPLIB each contains the number of
existing DSNs for this type that are to be included in the batch job. The
corresponding DSNs are then in the variables SYSEXECn and STEPLIBn, where
n is from 1 to content of SYSEXEC and STEPLIB respectively.
The following commands define the variables. That is their content in the
profile pool.
Subsequently, the program section from the edit macro #TSOB that reads the
variables from the profile and includes them in the JCL:
The rest of the procedure is suppressed.
Format:
result = ABS(number)
This function returns the unsigned absolute value of a number. The format of
the returned number is obtained from the currently valid NUMERIC options.
Examples:
Example:
end
ind
Example:
In this example, it is shown that with repeated calls always the same random
numbers are received when using the same number for option ind.
Program 4.1: RAMDOM – Generate random numbers
As you can see, in rows 2 and 4 plus 3 and 5 respectively appear the same
numbers, because in the corresponding RANDOM calls a base number was
specified. It is irrelevant what base number you choose.
SIGN returns the sign of the number specified by the following rules:
Format:
result = COMPARE(text1,text2[,filler])
text1,text2 The texts to compare.
filler The shorter of the two texts is expanded with the filler before comparison. The default
character is a blank.
Note:
I have never needed this feature because this function can be carried out with
the normal logical text comparisons operands, too. However, if you want to find
the position from which the inequality begins, COMPARE is very useful.
text This is the text, which shall be examined. When only this parameter is specified, then the
function returns the values NUM or CHAR.
type When type is specified, then the function returns 1 if the text contains only elements of the
entered type property, otherwise 0.
Type Properties
X Text contains only hexadecimal digits (a-z, A-Z, 0-9) and blanks can stand between hex pairs.
Null string is also a hexadecimal character.
Example:
The following program lines come from a program that performs date
conversions of the format YYYY/MM/DD in the format YYYY/DDD (Julian date)
and vice versa. Before in the program any arithmetic operations are be
executed check whether all input values are numeric. See the following
statements:
The PARSE command in line 24 parses the number entered in the variables
YYYY, MM and DD. The IF statement in line 25 checks whether all three values
are numeric. It works like this:
The DATATYPE function returns for all tests in which a correct number is found
1, otherwise 0. If only one of the tests provides 0, then the multiplication of all
three tests is 0. This means that at least one value is not numeric.
Caution trap:
If anyone thinks now "You can do this much better by contracting the two IF
statements in lines 25 and 27 into one IF statement." Then I can only say, "You
have traded with lemons!" Why does this not work properly? This does not lead
until then to an error if the program is actually called with wrong input values.
Because then the following happens: All arithmetic operations of IF statements
are executed to determine the result. This means in our case that the multiply
operation yyyy*mm*dd is executed to complete the IF statement. Therefore, if
one of the values contains a nonnumeric character, the program will cancel.
Therefore, if someone should resist the temptation to contract these two IFs in
one thing, he has built a classic time bomb here. The issue works until an
incorrect value actually appears.
So, remember the following rule:
Rule:
Before you perform any arithmetic operations in a statement, you must
previously perform tests in which no arithmetic operations occur, to ensure
that all involved values are numerical!
By the way, what is the most embarrassing error in the programming?
The most embarrassing programming error:
Suppose you installed an extensive plausibility test in your program and this
breaks in the reasonableness test without reporting the user’s error. Then it is
a bad thing for the user, because he does not know what he did wrong.
The conversion functions are always very useful when values have to be
converted into other forms of representation.
Example:
This small REXX program determines the job name directly from the system
tables of z/OS.
Screen 4.1: Read the job name from CVT
If you have the necessary knowledge of the z/OS operating system, try to
decipher the REXX commands. Find the necessary knowledge about the
conversion instructions in the following subsections. Of course, here all people
who have ever programmed in assembler have an advantage. This applies to all
conversion functions.
4.4.1- C2D – Character to decimal
Function:
This function returns the decimal value of a text. By specifying a length,
negative numbers can be converted.
Format
number = C2D(text,[n])
text This text is as binary text considered whose decimal value returned is.
n If specified, this number indicates how many bytes are converted from text from the right. Is the
first (i.e. the leftmost) bit of that number 1, then the number is output as a negative number in
the two's complement.
Advice:
When using this function, it is important to ensure that NUMERIC DIGITS are
set large enough. Otherwise, the call to C2D ends with an error.
In the following small program, I have compiled several calls to the C2D
function. I think that you can understand the operation of C2D well.
Program 4.2: Program to show C2D functionality
Format:
number = C2X(text)
text This text is an EBCDIC string, which is returned in hexadecimal
representation.
Examples:
n If specified, this number indicates how many bytes are returned after the conversion of
number. If n is greater than the number has digits, then is left-padded with spaces. If in
converting, more characters emerge as defined by n, characters are truncated on the left.
Example:
Format:
hexchar = D2X(number,[n])
number This is a decimal number whose content is returned in hexadecimal notation.
n If specified, this number indicates how many bytes are returned after the conversion of
number. If n is greater than the output length resulting from the conversion, the result is
left-padded with 00 if it is a positive number, it is filled with hex FF, if it is a negative
number. If in converting, more characters emerge as defined by n, left standing characters
are truncated.
Examples:
Due to specifying the length of 20, the shaded places were prefixed on the left
4.4.5- X2B – Hexadecimal to Binary
Function
Convert a hexadecimal number into a binary string in text format.
Format:
bintext = X2B(hexnumber)
hexnumber The hexadecimal string is converted into a binary string. The output is four
times as long as the input.
Examples:
Format:
text = X2C(hexnumber)
hexnumber This hexadecimal number is converted to its decimal
representation.
Examples:
n If entered, this number indicates how many bytes are converted from hexadecimal
value from the right. When the first (i.e. the left- most) bit of number is 1, then the
number is returned as a negative number in the two's complement. If this number is
zero, then the returned value will be a positive number.
Note:
When using this function, it is important to ensure that NUMERIC DIGITS are
set large enough. Otherwise, the call to X2D ends with an error.
Format:
result = CENTER(intext,length,[pad])
intext Input text, extended or shortened as defined by the length parameter.
length Number of characters of the result text. Is length less than the length of intext, then the input
text is equally shortened on both sides.
pad Here, a fill character to specify which of the left and right of intext is added for an
enlargement. Standard for the pad character is a blank.
Format:
text = COPIES(intext,n)
intext Input text that is n times duplicated.
n Number of copies.
Example:
Format:
Text = FORMAT(number,before,after,expp,expt)
expt Limit of digits of number when the output is automatically switched to exponential
representation.
Format:
text = JUSTIFY(intext,length[,pad])
intext Input text that normally consists of words, each separated by one or more blanks.
Example:
Format:
text = LEFT(intext,length[,pad])
intext Input text.
Format:
text = RIGHT(intext,length[,pad])
intext Input text.
Format:
text = DELSTR(intext,start[,number])
intext Input text.
start Starting position of the text to be deleted in intext. When the starting position is greater
than the length of the intext then intext is returned unchanged.
number Number of characters, which are deleted. The text will be deleted up to the end when this
parameter is not specified.
Format:
text = INSERT(intext,text[,start][,length][,pad])
intext Inserted text.
start Start position in text after the insertion is to occur. When the starting position is omitted or
zero, then intext is inserted at the beginning of text.
length Number of characters which are inserted. When this parameter is not specified then the
current length of intext is automatically used.
pad If the entered length is greater than the current length of intext then this character expands
intext on the right as defined in length.
Example
See next function CHANGE.
Function:
Change of texts.
Format:
text = SCHANGE(intext,searchtext[,replacement][,testtext])
intext Text to be changed.
searchtext Search text. Change replaces all texts that are found with searchtext with the
replacement text in a single call.
replacement This text should replace the search text. When the replacement text is omitted or
contains a null string, then searchtext is only removed from intext.
testtext The CHANGE shall only take place if this text is included in the intext. Of course, it
does not make sense when searchtext and testtext are equal. However, the function
still runs properly.
Format:
n = LENGTH(text)
Format:
text = OVERLAY(intext,text[,start][,length][,pad])
intext Text inserted by overlay.
start Start position in text from which the insertion is to occur. When the starting position is
missing, 1 is assumed. When the parameter start is specified, it must contain a positive
integer.
length Number of characters to be overlaid. When this parameter is not specified, the current length
of intext will automatically be used.
pad If length is greater than the current length of intext, then this character will extend intext
before the overlay is performed.
Format:
n = POS(needle,haystack[,start])
needle This text is searched for in the haystack
Format:
text = STRIP(intext[,option][,char])
intext This text will be stripped.
option This option specifies whether only leading, trailing, or characters from both ends should be
removed from text. Both Removes the characters at both ends. This is the default
value. Leading Removes leading characters only. Trailing Removes trailing characters only.
1 Tip:
The STRIP function is often required in order to free DSNs from the
surrounding single quotes ('). Sometimes it happens that a DSN is entered once
with and once without the quotes. It often happens that you have to insert the
DSN in a function that absolutely needs quotation marks. In such cases, I use
the following statement:
length Number of characters, which are extracted. When length is not specified, all characters will
be taken up to the end of text.
pad If length is greater than the available text, then the resulting text is extended with the padding
character. The default pad is the blank.
Format:
text = translate(intext[,replacetab][,searchtab][,pad])
intext This is the text that will be translated. If only intext is specified,then this is translated
to uppercase.
replacetab This text contains characters that are replaced in intext if these characters are found
in the search table.
pad The fill character replaces such positions in intext where characters were found using
the search table, but do not have a corresponding position in the replace table.
Examples:
This command first replaces all apostrophes in orgdsn by blanks and then
removes all surrounding blanks from orgdsn.
argl = translate(arg(1))
With this command, the first argument that was passed by a calling program is
set to uppercase.
This command replaces the characters dot, apostrophe, left and right brackets
by blanks. The resulting string contains all qualifiers of the DSN and an
eventually contained member name as single words. To get the member name,
the following command can be used:
meml = word(dsn1,words(dsn1))
Format:
n = VERIFY(text,checktext[,option][,start])
text This is the text which is to be checked.
Nomatch
When specifying N, the function returns zero when ALL of the characters of text are also included in check
text. Otherwise, the position of the first character that is not contained will be given back.
Match
When specifying M, the position of the first character in the text, which is also included in test text will back
given. If no character from check text is found in text, then zero will be given back.
start Start position in text where the search begins.
4.7 - WORD FUNCTIONS
One of the greatest strengths of REXX are the word functions. This is therefore
so useful because just in the z/OS world very many terms appear in ISPF,
programs, JCL, etc., as by blanks or special characters separated texts. From a
text such as a DSN, you can very quickly use TRANSLATE to remove the special
characters and you have a text that consists only of words.
Definition of a word in REXX sense:
–A word is a coherent text that does not contain blanks.
–Words in a string are separated from each other by one or more blanks.
Format
ywort = WORD(intext,position)
intext String from which the addressed word is extracted by position.
position Position number of word to be returned. If position is greater than the number of words in
intext then a null-string will be returned.
Format:
pos = WORDINDEX(intext,position)
intext String in which the selected word is addressed by position.
position Number of the word within intext, of which the position of the first character is
returned.
Format:
length = WORDLENGTH(intext,position)
intext String in which the by position selected word is addressed.
Format
pos = WORDPOS(word,string[,start])
word Searched word. If the word is not found in the string, zero will be returned
Format:
number = WORDS(intext)
intext String whose number of contained words are to be given back.
Format:
msgstat = MSG("ON"|"OFF")
This call returns the status of MSG, which can be ON or OFF. This function is
very useful when you wonder why TSO messages do not appear.
x = msg("ON") This call switches the display of the TSO messages to ON.
x = msg("OFF") This call switches the display of the TSO messages to OFF.
Example:
Note:
The TSO DELETE command always produces a message. In this case, the active
ISPF panel disappears and the delete message will be displayed. Since this is
very annoying and I do not want to see the message from TSO DELETE, here I
suppress the output of the message by setting x = msg("OFF").
If you need more information about this feature, view the detailed description
of this function in the brochure TSO/E REXX Reference.
Format:
x = outtrap(name.)
This call ensures that from now on all TSO messages are written in the
stem name.
x = outtrap("OFF")
This call finishes writing of TSO messages in the stem name. TSO stores the
number of rows of the stem in name.0.
1 With this statement, the TSO is informed that from now messages are no longer sent to
SYSTSPRT, but instead written into the stem text.
2 TSO executes the SUBMIT command and writes the resulting messages in the stem text.
3 The trapping of the TSO messages will be switched off. The variable text.0 now contains the
number of the TSO message lines in the stem text.
4 The messages from row two will be outputted. Since SUBMIT usually produces only two lines
and the text that interests us is always in the second line, we only print this line. The output
line might be:
JOB LANZT373(JOB06586) SUBMITTED
Remark:
I will not describe the LISTDS function here in detail. The above example may
suffice as information. The description of the TSO function LISTDS is contained
in the brochure TSO-E Command Reference.
Format:
text = SYSDSN(DSN)
The SYSDSN function returns ONE of the following texts, which are self-
explanatory:
Example:
The following program part allocates a data set. If the data set already exists, it
is only allocated. If it does not exist, it will be created.
Example:
Format:
value = STORAGE(address,length,text)
value Result.
address Specifies the memory address from which the data are collected in length. This address
must be specified directly in the form of hexadecimal digits.
length Specifies how many bytes are to be read or written at the starting address.
text If anything is specified here, this text replaces the memory contents beginning with address
in the length of text. Before replacing the contents starting at the addressed memory
location, the previous contents are stored in the variable value.
Note:
The replacement of memory locations should be handled very carefully. You
can shoot down your own address space. However, you do not need to worry,
because with the security rights that you have as a normal user, you cannot
override system areas.
Example 1:
The Common Vector Table (CVT) contains pointers to other tables in the z/OS
system. Therefore, if you want to read data from these tables, such as the job
name, then you first have to read the contents of the CVT . This address is
common in all z/OS systems at the memory location 16. The number 16
expressed as a hexadecimal number is 10. The pointer to the CVT is always four
bytes long.
Example 2
I found another example of the application of the STORAGE function on the
Internet. It gets the name of the program that is currently executing.
Program 4.7: PROGNAME examples for using STORAGE function
Note:
If this program is executed online under ISPF, the displayed name is always
IKJEFT01. This is the TSO processor.
Remarks:
–To run an EXECIO command, a DD name must exist that is named in the
EXECIO command. When running a REXX procedure in a batch job, this can also
be done by a DD statement in the JCL.
–The EXECIO command can read data from the data stack as well as write data
to the data stack.
–The EXECIO command can read the data into a stem as well as write data from
a stem. In this case, the name of the stem must be specified in the parameter
field.
–The file specified with the DD statement can also be a member of a PDS or
PDSE.
–When writing data records that are longer than the LRECL of the file, the
records will be truncated and EXCECIO completes the operation without an
error being ex- plicitly reported. However, in this case, the return code 1 is
returned by the command EXECIO.
–Records can be individually read and written. However, this is rather rare in
practice, as this would slow down the process.
Format:
"EXECIO lines iotyp ddname (parms"
lines Specifies the number of records to be read or written:
parms STEM name. Is the name of a stem from which is written or into which is read.
OPEN The data set shall be opened. OPEN will automatically be performed when records
are read or written. Normally, this option is never used.
FINIS The file will be closed when the I/O operation ends.
Program 5.1: EXECIOT – Example for the TSO function EXECIO
The following table contains descriptions of the statements of this small test
program:
Lines Explanation
07-14 Assigning lines to Stem A. The line A.1 is much longer than the LRECL 80 of the data set.
16 Write stem A. into member EXECIOD and CLOSE the data set.
18 Read all records of the file. A.0 now contains the number of records, namely 8
22 Free the DD name OUT. The data set PROX.BOOK.REXX(EXECIOD) is also freed.
Here you can now see the contents of the member EXECIOD after the above
program is running:
As you can see, the first record was shortened to LRECL=80 when writing the
member EXECIOD.
Rules:
–As discussed above, all strings which are found in REXX programs and are not
recognized by the REXX interpreter, will passed to the currently active host
command environment for execution.
–When a REXX program starts, then the host command environment for TSO is
active. Therefore, an ADDRESS TSO command is not necessary in this case. As
long as you do not switch the host command environment to another
subsystem, can you execute TSO commands simply by writing them in a
program line surrounded by apostrophes.
Remark:
Generally, all commands of the Access Method Services are usable as TSO
commands and thus also with REXX.
Program 6.1: TEST1: Simple program using the TSO environment only
Note:
If this program is running online, then the message is printed using the SETMSG
service of ISPF. When it runs in batch, the message uses the SAY command of
REXX.
I will not demonstrate the online execution of the above program here. This is
so simple that I really do not have to show it.
When running this program, the following list is printed. It can be found in
SDSF.
JCL 6.2: JCL to execute TEST2 in a TSO/ISPF environment
When running this program, the following list is printed. It can be found in
SDSF.
I think you now have the necessary knowledge to understand the following
chapters.
7 Introduction to ISPF programming
In the preceding chapters, I you with the operation of ISPF. Likewise, I
familiarized you with the programming language REXX. Now that you have the
necessary knowledge in REXX programming, I will show you how to create ISPF
applications.
I marked REXX in the above table. In this book, I will only use REXX as
programming language to develop ISPF applications. From the above
mentioned languages, REXX is the easiest to use, the fastest and most elegant
language. REXX requires the least effort to create ISPF applications.
7.27
ISPF is a dialog-oriented online system while CICS and IMS are transaction-
oriented online systems in z/OS MVS. Dialogue oriented means in this context
that an online program remains in memory as long as the user works in
dialogue with it. This has the advantage that you as a programmer of online
applications in ISPF do not have to worry about subsequent transactions,
storage of data between transactions, etc. At delivery, a toolbox with all the
tools needed for programming applications running in ISPF is already included.
These tools are described in the following IBM brochures:
ISPF Dialog Developer's Guide and Reference
and
We will discuss in detail all of these elements during the further course of the
book. For each of the above elements I will give you below a brief introduction
followed by examples for each element.
Data sets
REXX normally processes only sequential data sets. This may also involve
members of a PDS. There are also functions for editing directories of PDS. VSAM
and other types of data sets can be processed with special access programs. For
processing DB2 tables See following URL: http://mainframe-tips-and-
tricks.blogspot.de/2011/12/sample-db2-rexx-rogram.html and http://www-
01.ibm.com/support/knowledgecenter/SSEPEK_11.0.0/com.ibm.db2z11.doc.
apsg/src/tpc/db2z_codesqlstaterexx.dita
Panels
Panels are created using the ISPF editor. They consists of two parts: The first
part defines the representation on the screen. The other part performs a certain
plausibility check and defines for which fields help panels are available.
Messages
ISPF provides a very simple and user-friendly way to define messages and
output them as required. The messages can be outputted from programs and
from panels.
Skeletons
Skeletons define a mask for creating data sets, where the variables which are
defined in the skeletons will be replaced automatically by the contents of the
variables of the same name in the REXX procedure. Skeletons are mostly used
for creating JCL lines. The ISPF editor is used to generate skeletons. When a
REXX program calls a skeleton, then all variables in the skeleton are replaced
by the values that are defined in the REXX program with the same name.
Tables
Tables are by programs created and edited using appropriate ISPF functions.
Tables consists of a special ISPF data type. They can only be stored as members
in special ISPF table datasets of type PDS. Since they are interspersed with ISPF
control data, their content can be viewed with edit and browse.
Variables
Variables play a major role in ISPF. ISPF itself contains a large amount of
variables that can be used in some ISPF elements such as panels, messages and
programs. ISPF differentiates between system variables, normally starting with
Z and user variables that can be anything called. The name must not be longer
than eight characters. A table of system variables is found in Appendix D of the
IBM manual ISPF Dialog Developer's Guide and Reference found.
Conclusion
Now having introduced you to the theoretical programming elements, I want to
look at some examples from my practice. The examples are purposely from
practice, because I do not want to bore you with simple things. I ask for your
understanding that I cannot explain the commands and procedures for each
example in detail as this go too far. All the different elements in the examples
are anyway discussed in more detail later in the book.
7.37
7.3.1 Example for use of ISPF panels
The program SSS belongs to the SMART ISPF utilities. It is called in front of the
name of a data set to perform a SUPER SEARCH in a DSLIST panel. The panel
SSSP1 shown below is used by the REXX procedure SSS to read in the text to be
searched for.
Program 7.1: Panel definition of panel SSSpl
The variables SSP1 to SSp14 that contain the search texts are written into the
ISPF profile and are again read before the panel is recalled. Therefore, I do not
have to reenter the search text on every call to SSS. Reading and writing of the
variables using VGET and VPUT could also be performed in the panel, but I
decided to do this in the SSS procedure. Here is the excerpt from the REXX
procedure SSS which calls the panel SSSP1:
7.3.2 Example for use of skeletons
Skeletons are mostly used to assemble extensive job streams. For such an
application, I have taken the following example.
Function:
In a large job step must be commands inserted which perform BIND PACKAGE
for DB2. Since this job must be created for different LPARs, all values that relate
to the individual LPARs are kept variable.
Here first the skeleton member. The variables in skeletons always begin with
an ampersand (&) character. The association of variables with text or other
variables will done by a period (.). Since points must separate the individual
qualifiers of DSNs, you will have to use two points when creating DSNs by
linking variables in skeletons.
Note:
Some variables containing in the skeleton are set already earlier in the
program. Therefore, they do not appear in this part of the program.
Here is the created step in which the variables with real values have been
replaced:
JCL 7.4: Job step build by skeleton VINTPAC
This is a complex example from practice. Try to understand the process. All
important places are grayed out. We will deal in a later chapter in detail
concerning the use of skeletons.
Example:
As an example, I want to take the table that is used in the program SLE of the
SMART ISPF utilities. It contains the names of the recently edited data sets,
along with other information such as date and time of use. First, here is the
program section of the edit macro #IMACRO2 that is called when an edit
session ends. Here, the Table $SLETAB is opened and the DSN of recently edited
data set is inserted in the table. When a member of a PDS was edited the
member name will be inserted in the DSN. If the table does not exist, it is created
and written after processing into the ISPF library ISPPROF. The following part
of the program SLE shows the insertion of a DSN in the table $SLETAB.
Screentext 7.1: Program part from SLE – Insert a DSN into table $SLETAB
Here is the part in the program SLE which displays the panel SLEP1 containing
the contents of table $SLETAB.
System variables are, as its name implies, created and managed by ISPF. You
can use them in all ISPF functions. In some, you can change the content. See
ZEDLMSG above. Some system variables are assigned to specific ISPF services.
Since I have used in the shown examples so far some variables of both types, I
will refrain from further examples. However, I want to show you how you can
view the currently defined variables and their contents in your ISPF. To do this,
I proceed as follows: I choose the ISPF option 7.3 and get the following panel,
which is showed shortened below:
Screen 7.2: ISPF variables display using ISPF menu 7.3
If permitted by ISPF, you can change the contents of variables, delete them
entirely or create new variables in this panel. I grayed some of the Z-variable.
These contain values that are often needed in daily operations. To get the
contents of ISPF variables, read them using the command:
ZERRALRM Char 3 The value is set to YES if an alarm was specified in the message definition
otherwise, the value NO. Set when ISPF services issue a return code of 8 or
greater.
ZERRHM Char 8 The name of a Help panel, if one was specified in the message definition.
Set when ISPF services issue a return code of 8 or greater.
ZERRLM Char Long-message text in which variables have been resolved. Set when ISPF
512 services issue a return code of 8 or greater.
ZERRMSG Char 8 Message ID. Set when ISPF services issue a return code of 8 or greater.
ZERRSM Char 24 Short-message text in which variables have been resolved. Set when ISPF
services issue a return code of 8 or greater.
ZEDSMSG
ZEDLMSG
S and L stand for SHORT and LONG. This means that you can put a message up
to 24 characters in ZEDSMSG and in ZEDLMSG a long message up
to 512 characters. See Screentext 7.1: Program part from SLE – Insert a DSN
into table $SLETAB on page 115.
The ISPF service SETMSG writes the error message texts contained in ZEDSMSG
and ZEDLMSG on the currently displayed screen. However, the following rules
are to be considered:
– If the variable ZEDSMSG contains a text, then initially only this text is
displayed on the right top corner of the screen and nothing else happens. First,
when the user presses PF1, then the related ZEDLMSG message will also be
displayed on the bottom of the screen.
– If the variable ZEDSMSG contains nothing, only the ZEDLMSG message is
immediately displayed on the bottom of the screen.
Example:
Notes:
The SETMSG service is usable for every display of messages. You can generate
an error message in ZEDLMSG by combining the content of ZERRLM together
with your own texts. You can fill the variables with a text of your choice and
display them. It is not necessary that a program error situation is present.
Program example:
The following program shows two typical applications of the ISPF message
services:
– In the first use of the service are the names of data sets, which have an ENQ
reservation displayed. The function QUERYENQ detects such ENQs. These are
the statements 202 to 212.
– The second application displays an error message when a data set should be
edited for which the editor is unable to edit.
Screentext 7.2: Example of the ISPF messages service
Function:
Allocate additional data sets to the existing ISPF libraries dynamically and
remove such assignments again.
With these options, you can define how the LIBDEF chains shall be arranged.
Advice:
Always use the STACK option. If this option is missing when creating the
LIBDEF and you reset this LIBDEF assignment, then all pre-existing LIBDEFs
also cancels. If you have called a new application from another application
which also has LIBDEFs, their LIBDEFs are also withdrawn. This means that you
can no longer work with the previous application after return.
Program 7.4: LIBDEF example
Use the ISPF command ISPLIBD to display the current LIBDEF assignment. See
the following screen. It shows the currently assigned LIBDEFs within this
logical ISPF screen.
Screen 7.3: ISPLIBD – Display the current active LIBDEF assignment
Advice:
The LIBDEF definitions apply only to the logical ISPF screen in which they are
executed. This is necessary because otherwise you could not even run different
ISPF applications simultaneously on several logical ISPF screens.
Normally, the TSO is set so that when a procedure is called, then the SYSEXEC
library is first searched and afterwards the program is searched in the SYSPROC
library. This is of course only valid if both library types are assigned.
The command TSO ALTLIB DISPLAY displays the current ALTLIB setting:
Example:
Current search order (by DDNAME) is:
System-level EXE CDDNAME=SYSEXEC
System-level CLIST DDNAME=SYSPROC
Example 2:
Disable the CLIST system level.
When I now execute the command TSO ALTLIB DISPLAY, the following display
occurs:
This means that procedures in the SYSPROC allocation will not be found
regardless whether the allocation exists or not.
Example 3:
I have written a small REXX procedure that executes some ALTLIB commands.
Program 7.5: ALTLIB1: Example of the application of the command ALTLIB
When the procedure executes, the following display appears:
While only a TSO ALLOC command must be executed before using the EXECIO
command, a whole series of commands is necessary to use the ISPF services for
data set processing. Moreover, these commands must run in the right sequence.
I would like to provide guidance to use the right services for a particular task in
the table below. In the right column, you will see the commands that are
necessary to perform a complete service process. The one or more nucleus
commands for performing a service project are displayed in gray. I added
options that must be necessarily set for certain tasks. I also added notes behind
individual commands that are important when using this service.
Attention:
Never forget to execute the final commands LMCLOSE and LMFREE so that the
used resources are completely free after the action. If these two commands are
not executed, the resources remain locked for further editing. There is no way
to subsequently execute the two commands when the program has ended. In
this case, the blocking of resources can only be lifted by LOGOFF and LOGON.
LMOPEN
LMCLOSE
LMFREE
Read a member sequential LMINIT
LMOPEN
LMCLOSE LMFREE
LMOPEN
LMCLOSE
LMFREE
LMCLOSE
LMFREE
LMCOPY
LMFREE (Input)
LMFREE (Output)
LMMOVE
LMFREE (Input)
LMFREE (Output)
LMMDEL
LMCLOSE
LMFREE
LMMREN
LMCLOSE
LMFREE
LMMSTATS
LMFREE
LMOPEN
MLCLOSE
LMFREE
LMCLOSE
LMFREE
MEMLIST
LMFREE
LMDDISP
LMDFREE
Notes:
In the following description of the individual services, I will mainly use the
descriptions of the IBM brochure ISPF Services Guide to explain a service.
Since however as the accompanying examples are very brief in all the
brochures of ISPF, I will bring to (almost) every service a sample program that
was tested by me. The resulting printout of the programs will always be shown.
Only for services where the function is very simple (e.g. LMFREE), I will not
spend any time explaining. In the descriptions of the individual parameters, I
will always mark the default values in gray.
Format:
dataid Here a name of maximal 8 characters must be specified. It is not necessary to enclose the
name at this point in apostrophes. This name must be used in all subsequent LM services
concerning this data set. In the following LM service statements must the DATAID entered
in a variable notation as shown below:
DATAID(“dataid”) or DATAID(&dataid)
ddname DD name of the data set addressed with this LMINIT. When a DD name is specified, this
must have been previously allocated to a data set. This DD allocation can be present by a
previously executed TSO ALLOC command in the program, or come by a defined DD
statement from the outside in a BATCH JCL.
SHR Shared access to this data set is allowed. Other users can also access this data set.
EXCLU Exclusive access. No other users can simultaneously access the data set.
SHRW Works like SHR. However, members can be written into the PDS. This option only applies
for access to a PDS.
Rules:
–The ENQ option can be used only if the data set is addressed using the
DATASET option. In addressing via DDNAME, the ENQ option conditions
determines the ALLOC or DD statement.
–If the LMINIT function addresses a set of concatenated data sets, then this is
only possible by using the DDNAME parameter. The concatenation of the
data sets must be previously performed using a TSO ALLOC statement or by a
DD statement in the JCL of a batch job.
LMINIT examples:
Format:
ISPEXEC LMFREE DATAID(data-id)
data-id Here, the same variable must be specified which was used in
the corresponding LMINIT.
Format:
DATAID Here the same variable must be specified which was used in the corresponding
LMINIT.
OPTION This determines whether the data set should be opened for input or for output. INPUT
is the default value.
LRECL If this option is used, then LMOPEN stores the LRECL of the data set in the lrecl-var.
RECFM If this option is used, then LMOPEN stores the RECFM of the data set in the recfm-
var.
ORG If this option is used, then LMOPEN stores the organization form of the data set (PO
or PS) in the org-var.
Example:
Program 8.1:LMOPEN example
The SAY statement prints the following output:
LRECL=000007 96, RECFM=VB , ORG=PS
Format:
ISPEXEC LMCLOSE DATAID(data-id)
DATAID Here the same variable must be specified, which was
used in the LMINIT and LMOPEN. The possible setting
of ENQs performed by LMINIT will be freed.
Format:
MEMBER Enter here the name of the desired member.
LRECL This is the same parameter as used in the LMOPEN function. The difference, however, is
that when searching in a concatenated data set the characteristic values of the PDS will
be transferred in which the member was found.
RECFM Here mutatis mutandis applies the same to say as for LRECL. If YES is specified, then
some variables are set by ISPF containing values of the member statistics of the member
found. Here especially the ZLIB variable is of interest. When the LMOPEN refers to a list
of concatenated data sets, this variable contains the position number of the data set
within the chain of PDS in which the member was found. Since number, name and type
of the returned variables depend on the type of data set, I will refrain from a detailed
description. If you want to pursue the issue further, I recommend the manual ISPF
Services Guide.
Example:
The following program shows how to search members in a concatenated data
set.
Program 8.2: LMMFIND example
I ran the program. The result is shown here:
Format:
DATAID Specifies the data-id that has already been used by LMINIT and LMOPEN service.
STATS The STATS (YES) option specifies that the member statistics will be set or updated after
insertion of the member. The program must at least have set the values ZLCDATE for the
creation date and ZLMDATE for the modification date. For information about other
variables that can also be set, see the description of the service LMMREP in the
brochure ISPF Services Guide.
NOENQ This option causes the ISPF while deposing the execution of the command to set no ENQ
on the relevant PDS.
Advice:
If a particular member is not in the PDS available when running LMMREP, the
LMMREP command ends with a RC = 8, although everything was done correctly.
This must be observed when checking the return codes.
8.1.8 LMMADD – Add a member
Function:
This service works the same as the LMMREP service. The only difference is that
an existing member will not be replaced. This service should always be used if
you never want to overwrite already existing members. If the concerned
member is available in the PDS when running LMMADD, the LMMADD
command ends with a RC = 4 and the member is not written into the PDS.
Format:
MODE Defines whether the data is to be moved, located or stored into an ISPF dialog variable.
DATALOC dataloc-var is the name of a REXX variable in which the read data record is stored when
mode INVAR was specified.
DATALEN datalen-var is the name of a REXX variable in which the length of the read data record
is saved.
MAXLENE max-length is an input variable that contains the maximum length of a record. You can
always specify the number 32760 here.
Example:
Read the member LANZT.LOGON.CLIST(ALIAS). This data set is defined with
RECFM=VB. I have deliberately avoided any error checking during
development of the program to make the example easier to read.
Format:
DATAID Specifies the same data-id that is already used by LMINIT and LMOPEN
service.
DATALOC dataloc-var is the name of a REXX variable which contains the data to be
written.
[NOBSCAN] This option specifies that the trailing blanks will not cut off when writing VB
records.
Example:
Program 8.4: LMPUT – Writing a member with setting the statistic
information
8.1.11 LMCOPY – Copy data
Function:
The LMCOPY service copies PDS members or entire sequential data sets.
Format:
FROMID Specifies the same data-id that is already used by LMINIT and LMOPEN service to
allocate the input data set.
TODATAID Specifies the same data-id that is already used by LMINIT and LMOPEN service to
allocate the output data set.
FROMMEM from-member-name is the name of the source member or a mask through which the
members to be copied are generically selected. If an asterisk (*) is specified, all members
are copied. If the source data set is a PDS, this parameter must be specified. If the source
data set is of type sequential, this parameter must not be specified.
TOMEM to-member-name is the member name of the member in the output data set. If the from-
member-name is specified and the to-member name not, the member is copied using
the from-member-name in the output data set. If the source data set is of type sequential
to-member-name, this must be specified. If the target data set is of type sequential the
to-member-name cannot be specified.
REPLACE Specifies that existing members are replaced. If this parameter is not specified when
copying multiple members, only those members that are not present in the output data
set will be copied. If members are not copied because they are already present, then the
RC=12 is set.
TRUNC Allows clipping of the input data to the LRECL of the output data set.
Format:
The parameters are the same as those described in the previous services. Since
this is a very simple function, I will refrain from giving a detailed example.
Format:
The parameters are the same as those described in the previous services. Since
this is a very simple function, I will refrain from giving a detailed example.
8.1.15 LMMSTATS – Display or change member statistics
Function:
The LMMSTATS service sets or clears the member statistics for a member in a
PDS. Not all statistic values must be set when calling the service. If some values
are not set, LMMSTATS tries to determine the remaining values (such as the
number of records in a member) to set it correctly.
Format:
MEMBER The name of the member, which statistics should be changed. There can be a generic
mask entered to set statistics for multiple members.
VERSION Version number that is to be set. Here a number from 1 to 99 must be specified.
MODLEVEL Modification level that is to be set. Here a number from 1 to 99 must be specified.
CREATED Creation date of the members. A date in the form valid for the respective country must
be entered. This form is provided in REXX by calling the function DATE (“O”).
MODDATE Modification date of the members. The shape is the same as in CREATED.
MODTIME Time of the modification of the member in the form HH:MM:SS. This format is
provided by the function TIME () in REXX.
CURSIZE Number of records in the members. This parameter should never be specified. The
system determines and sets this value.
MODRECS Specifies the number of modified records. This value can only be set by the system.
USER The user ID that is inserted in the member statistics. This information may contain a
maximum of 7 characters. When the ISPF editor edits the member, the editor sets the
user ID automatically when the member is stored.
CREATED4 Creation date of the member in the form with four-digit year. A date in the form valid
for the respective country must be entered. Normally the form YYYY/MM/DD is used
in Europe. The text must be assembled to contain the correct form for the appropriate
country.
Prior to the creation of statistics, the existing values are deleted (lines 09 and
14).
On line 12, the statistics for the member login are created without any
indication of parameters. In this case, the system searches for the values itself.
The date and time values are taken from the date of execution of the command.
The number of records in the data set and the user ID will also be determined
and entered by the system.
The following two displays show the member lists after the execution of the
above program:
Display 1: Normal view
Display 2: The alternative view after shift right using the PF11 key
Tips:
When you use LMMREP or LMMADD to create a new member, then it is easiest
to execute these commands with the STATS option NO, the default value, and
then right after that execute a call to LMMSTATS with no parameters. Make sure
in this case that you run a LMCLOSE before LMMSTATS because LMMSTATS
may only be applied to a DATAID not opened. This procedure has the advantage
that the LMMSTATS command determines the statistics values based on
existing physics and the present time itself.
When you use LMMREP or LMMADD you must, however, determine the values
yourself and set the corresponding variables. When using STATS (YES) in
LMMREP or LMMADD you need to previously fill some values, otherwise
nothing is entered.
Format:
ISPEXEC LMCOMP DATAID(data-id)
Before executing the command LMCOMP, a LMINIT command with the option
ENQ(EXCLU) must be executed.
8.1.17LMMLIST – Display a member list
Function:
If the LMMLIST service is executed with the LIST or the SAVE option, it will
generate a list of the first occurrence of a member in a concatenated data set. If
only one data set is specified in the TSO ALLOC statement that precedes the
LMINIT service, only the member names of this data set will be listed. When
LMMLIST is executed for first time in a program the content of
the MEMBER variable determines the touchdown point for the selection of
members returned. If the MEMBER variable contains a BLANK, then all member
names of the PDS will be returned.
Note:
LMMLIST returns for each call only the next name in ascending alphabetical
sort order in the PDS directory. Therefore, you must call LMMLIST in a loop if
you want to capture multiple members of a PDS. Before LMMLIST is used, the
LMINIT and LMOPEN service have to be run.
Format:
OPTION(LIST) The first call of LMMLIST creates an internal member list. If the member-var is
initialized with blanks, then LMMLIST returns on each call the next member in
the list beginning with the first member in the PDS. In this case, you successively
get all members contained in the PDS.
OPTION(FREE) FREE releases the occupied shared memory. Whenever a loop for the
determination of member names is completed, perform a single call to LMMLIST
with the FREE option to free the occupied memory.
OPTION(SAVE) With the SAVE option, the list of members is outputted to a data set. The GROUP
parameter defines the name of this data set.
MEMBER Before the first call to LMMLIST, initially specify in member-var the starting
position for the search for the members in the member list. The member-var
contains after the call either the name of the directly addressed member or the
name of the member that is found next.
STATS When YES is specified then, LMMLIST stores for each member the member
statistics information in the corresponding variables. A detailed description of the
member statistics variable can be found in section 8.1.15 LMMSTATS – Display
or change member statistics on page 147.
GROUP Here, an up to eight characters long name can be specified from which a DSN of a
data set is formed in which then, when specifying OPTION(SAVE), the member
list is written. When the GROUP parameter is omitted and OPTION(SAVE) is
specified, then the output of the member names list is written in the LIST data set
of ISPF. The DSN will be formed as follows: <prefix>.<group>.members.
PATTERN You can specify a mask here, which determines the actually returned members.
The description of how the mask must be set up, can be taken from ISPF
Services Guide.
Format:
CURSOR CURSOR defines at which position the cursor should be displayed for the panel.
ZLLCMD The cursor is positioned at the beginning of the first line of data.
ZLUDATA The cursor is positioned in the second input field of the first row of data.
TOP This is a very complicated parameter. Here the original text from the manual ISPF
Services Guide:
The name that designates which member is to appear first on the display. If the member
cannot be found and the list is sorted by name, the member immediately preceding the
requested one in the member list is scrolled to the top. If the list is not sorted by name and
the member is not found, the list is scrolled to the top.
I ran the program and entered a few commands. Expenditures incurred there
can be found behind the display of the panel.
I entered line commands in the panel display and then pressed the enter key
and three times. Successively the following lines appeared:
Note:
The column Lib in the panel shows the data sets position in the chain in which
the member is first found. The member may still occur, but often in the
underlying data sets of the chain.
Format:
LEVEL The dsname-level defines a mask for selecting the DSNs. The rules for the design of the
mask are the same as in the ISPF menu 3.4.
VOLUME Here a VOLSER (a disk name) can be specified. If a VOLSER is specified, the data sets
are only searched in the VTOC of this disk.
Format:
LISTID Here the LISTID from an earlier performed LMDINIT must be specified.
VIEW Here you can specify what additional information should appear when displaying the
panel.
CONFIRM YES means: The confirm delete panel appears always before the DELETE of a data set
is performed.
NO means: The confirm delete panel appears only when a data set should be deleted,
which expiration date has still not expired.
PANEL Here you can specify a panel that you want to use instead of the default panel as used in
ISPF menu 3.4.
Due to using the option VIEW(TOTAL) in the LMDDISP call, all data set
attributes are displayed.
Format:
OPTION The description of these options is very complicated and extensive. Please see this in
the brochure ISPF Services Guide. A simple example of using LMDLIST is shown
below.
DATASET Before the first call to LMDLIST you must initialize dataset-var with a DSN mask. At
each return from LMDLIST, this variable contains the name of the next DSN found in
the list.
STATS If you set STATS(YES) then for each returned DSN, the statistic information of the data
set is returned in special variables. Please see the descriptions of the variables in the
brochure ISPF Services Guide. See also section 8.1.15 LMMSTATS – Display or
change member statistics on page 147 and Table 8.3: Variables returned by the
LMDLIST service on page 161.
GROUP If you entered OPTION(SAVE), then you must specify a 8-character value. The data set
list is then written into a data set. Its name is built up as follows:
<prefix>.<group>.DATASET.
Program 8.10: LMDLIST example
Format:
ISPEXEC LMDFREE LISTID(list-id)
Format:
DATAID Specify the DATAID from the associated LMINIT service call.
MEMBER A mask for the selection of member names can be specified here. If there is no mask
specified, all members of the PDS appear in the displayed panel.
CONFIRM If YES is active, the confirm delete panel appears after entering a delete command in
front of a member and before the deletion is performed. Otherwise, the deletion will be
executed immediately.
PANEL You can specify the name of a panel here that you want to use instead of the default panel
for the display of the member list.
FIELD Defines the length of the line command fields. If 1 is specified, only single digit line
commands such as B, E, V, etc. can be entered. See also the command LMMDISP service
on page 153.
LMDLIST ISPF This service is the only data set list service that returns the HSM migration
status.
DSINFO ISPF This service provides a very comprehensive overview of the characteristics of
a data set.
LISTDSI REXX This service almost provides the same information as DSINFO, but some of
the information is to use something better.
Variable Description
ZDLMVOL Specifies whether this data set spans over multiple volumes. (Y or N)
Remark:
The LMDLIST service is the only service that returns the information on the
migration status of a data set. Therefore, I marked the variable ZDLMIGR.
Format:
DATASET DSNAME is the name of the dataset for the information be returned.
VOLUME VOLSER is the volume serial number (disk name) on which the data set is located.
Specify this parameter only when the data set is not cataloged. The following table shows
the variables that this service returns.
Variable Description
Format:
Data set name or DD name. If a DD name is specified, FILE must also be
specified. You must use the DD name notation when the REXX program runs in
a batch job and a DD statement specifies the data set.
location This option is normally not used.
DIRECTORY The option DIRECTORY specifies whether the requested directory information of a
PDS/PDSE is stored in the corresponding variables. When NODIRECTORY or
nothing is specified, then this information will not be returned. DIRECTORY should
only specified if the corresponding information is really needed because
determination of the directory information takes a long time.
RECALL When entering RECALL, then a data set that is HSM migrated is loaded back to the
normal disk environment. NORECALL is the default value.
SMSINFO When you type the SMSINFO option, then the SMS information about this data set
will be determined and set into the appropriate variables. Because this option causes
much more work by the system, you should use this option only when you need the
information. NOSMSINFO is the default value.
SYSUNIT Generic device type on which volume resides, for e example 3390.
PSPhysical sequential
PSUPhysical sequential unmovable
DADirect organization
ISIndexed sequential
OPPartitioned organization
VSVSAM
???Unknown
SYSUSED Allocation used, in space units. For a partitioned data set extended (PDSE),
‘N/A’ will be returned see the description of the variable SYSUSEDPAGES for
used space of a PDSE.
SYSUSEDPAGES The used space of a partitioned data set extended (PDSE) in 4K pages.
BRecords blocked
??????Unknown
SYSTRKSCYL Tracks per cylinder for the unit identified in the SYSUNIT variable
SYSBLKSTRK Blocks (whose size is given in variable SYSBLKSIZE) per track for the unit
identified in the SYSUNIT variable. For a PDSE, the value “N/A” is returned
because a block of size SYSBLKSIZE can ‘span’ a track in a PDSE. The value
contained in SYSUSEDPAGES is a more meaningful measurement of space
usage for a PDSE.
SYSTRKSCYL Tracks per cylinder for the unit identified in the SYSUNIT variable
SYSBLKSTRK Blocks (whose size is given in variable SYSBLKSIZE) per track for the unit
identified in the SYSUNIT variable. For a PDSE, the value “N/A” is returned
because a block of size SYSBLKSIZE can ‘span’ a track in a PDSE. The value
contained in SYSUSEDPAGES is a more meaningful measurement of space
usage for a PDSE.
SYSADIRBLK For a partitioned data set (PDS) the number of directory blocks allocated will be
returned. For a partitioned data set extended (PDSE), “NO_LIM” will be
returned because there is no static allocation for its directory. A value is
returned only if DIRECTORY is specified on the LISTDSI statement.
SYSUDIRBLK For a partitioned data set (PDS) the number of directory blocks used will be
returned. For a partitioned data set extended (PDSE), "N/A" will be returned
because it is not a static value. A value is returned only if DIRECTORY is
specified on the LISTDSI statement.
SYSMEMBERS Number of members – returned only for partitioned data sets when
DIRECTORY is specified
SYSDSSMS Contains information about the type of a data set, provided by DFSMS/MVS. If
the SMS DSNTYPE information could not be retrieved, the SYSDSSMS variable
contains:
If the data set is a PDSE and the SMS DSNTYPE information could be retrieved,
the SYSDSSMS variable contains:
SYSDATACLASS The SMS data class name – returned only if SMSINFO is specified on the
LISTDSI statement and the data set is managed by SMS.
SYSSTORCLASS The SMS storage class name – returned only if SMSINFO is specified on the
LISTDSI statement and the data set is managed by SMS.
SYSMGMTCLASS The SMS management class name – returned only if SMSINFO is specified on
the LISTDSI statement and the data set is managed by SMS.
Code Description
11 Directory info was asked for but user ID has insufficient, access authority for this data set.
17 ABEND occurred.
31 ISITMGD macro returned with bad return code and reason code. Return code and reason code
can be found in message IKJ58431I, which is returned in variable &SYSMSGLVL2.
Tips:
If you want to use the LISTDSI function in one of your programs, then you find
in the program SSC of the SMART ISPF utilities an internal subroutine named
DSLSTRC that contains the appropriate description for each reason code. You
can copy this subroutine to your program.
Format:
ISPEXEC QBASELIB dd-name ID(id-var)
dd-name DD name.
Format:
dd- DD Name of the ISPF library. The value may be ISPPLIB, ISPMLIB, ISPSLIB, ISPTLIB,
name ISPLLIB, ISPILIB, ISPTABL and ISPFILE.
TYPE type-var is a variable where the QLIBDEF service returns the definition type from the
ID original LIBDEF statement. The returned value can be DATASET, EXCLDATA, LIBRARY
or EXCLLIBR.
ID id-var is a variable into which the QLIBDEF service stores the DSNs of active LIBDEF chain.
Example:
First executes the program a LIBDEF command for ISPSLIB (skeletons). Then
the existing LIBDEF chain for ISPSLIB is queried and displayed using QLIBDEF.
Then the function QBASELIB is executed to print the ISPSLIB chain as well.
Program 8.13: QLIBDEF example
The output of the program (side by side):
Format:
TABLE A freely chosen name for the ISPF table into which this service stores its information
about the ENQs found. This table is returned to program in open state and it must not
exist before calling QUERYENQ. The program must delete the table at the end of the
program with TBEND.
QNAME The user must define the type prior to the call of the QUERYENQ in this variable. Query
types can be SYSDSN, SPFEDIT, SPFUSER etc. Normally, an asterisk (*) is assigned. This
means that all query types are queried.
RNAME Before calling QUERYENQ this variable must contain the name of the queried resource.
This can also be a generic mask ending with an asterisk.
REQ The description for this value is very complex. I refrain from taking this opportunity to
give a comprehensive explanation and always recommend to keep the characters %* for
use. Look at the following example.
WAIT If you specify this option, only the currently pending ENQ contentions will be issued. The
information in rname and qname has no significance in this case.
LIMIT LIMIT is the number of rows that the function maximally returns. The default value is
5000. The specification of zero (0) cancels the limit.
SAVE If you specify an up to eight digits long name of a DSN qualifier here, then the
QUERYENQ service writes the results to a data set with the following name:
prefix.userid.listid.ENQLIST.
XSYS Indicates that the XSYS=YES parameter should be used on the GQSCAN macro call. This
option causes that all available LPARs are searched for the resource, which may mean a
lot of effort. If you are interested in this option, please look at the description of the
GQSCAN macro.
RC Description
0 Table returned or data set written, but XSYS parameter was not specified and the system is
running in STAR mode. The data returned may not reflect all ENQs on all systems.
2 Table returned or data set written.
10 No ENQs satisfy the request, but XSYS parameter was not specified and the system is running in
STAR mode. The data returned may not reflect all ENQs on all systems.
12 Table creation error, parameter or other termination error. See messages for more detail. This
includes services not available due to configuration table restrictions.
Note:
Please note that even if a RC>0 appears, quite useful results can be returned.
When requesting the RC, you must always consider possible situations.
Example:
The following program investigates whether a specific data set has any ENQs.
Program 8.14: QUERYENQ example
The program produced the following output:
As you can see, only the gray shaded user is currently using the data set.
Once you have executed this command, from now on the errors occurring
during the execution of ISPF functions (and only these) back to the program
will be reported and the procedure will not be aborted.
If an error occurs, these variables are written in the function pool. They are
usually only present when an error with an RC > 8 occurred during the
execution of an ISPF function. The two shaded characters in variable names are
very important: S Stands for SHORT. That is, in ZERRSM a short error message
with 24 characters will be returned. L stands for LONG. In ZERRLM, extensive
error messages with 512 characters will be returned. These variables can be
queried in a program and used appropriately for own message output.
Tip:
The variables are always returned in the above-mentioned length. Before using
these two variables, you should remove the superfluous BLANKS using the
REXX STRIP function.
If you use this function, you always know in which environment a program runs
and then you can use the correct method for outputting your error messages.
See the following short program:
Program 9.1: TEST2 – Output of messages when a program runs online or in
batch
Format:
SETMSG MSG(msg-id) [COND]
MSG Here the message ID of a programmer-defined message must be specified. There are also pre-
defined message IDs, which can be used for the issuance of own messages. See the next
chapter.
COND This parameter indicates that this message is only issued when an earlier SETMSG message
is not waiting for output.
As you can see, variables can be used in the definitions of the message line.
These are the names that begin with an ampersand (&). These variables are
replaced through their actual content before outputting the message. In REXX
programs, these variables are naturally without specifying & defined.
9.1.5 Naming convention of the ISPF message IDs
When printing a message, the name of the message ID is searched in the
members of the data sets of the ISPMLIB chain. This raises the question: What
is the name of the member in which a message ID is defined?
Rules:
The name of the member is found by cutting the name of the message ID after
the second numeric characters. Examples are shown in the following table:
G015 G01
ISPE241 ISPE24
XYZ123A XYZ12
Thus all message IDs always start with the name of the member in which they
are defined. In addition, the message ID and the associated member name must
contain at least two numeric characters.
Then the member XYZ12 is searched in the allocation chain of the ISPF library
ISPMLIB and the message XYZ123A is displayed.
Long message text As an Expiration Date only PERM, NONE, blank or a date in the form
YYYY/MM/DD can be entered.
Alarm Yes
This message appears when in the panel SSCPP01 in the field Exp.Date a wrong
value is entered. To display the message, the following command is used:
Coding 9.2: Member TT00 – Example for the definition of a message member
I have outputted all the messages once each with the command ISPEXEC
SETMSG MSG (TT00x). See the results below:
ISRZ000
Names of variables: ZEDSMSG and ZEDLMSG.
This Message ID is used when you want to spend only a hint. The issue of the
long message appears in white.
ISRZ001
Names of variables: ZEDSMSG and ZEDLMSG.
ISRZ002
Names of the variables:
Allows you to output the error message data directly, which are returned from
ISPF because the ISPF error messages will be stored exactly in the variables
which are used in this error message definition. The message appears in yellow.
Depending on the content of the variable ZERRALRM, a beep will be outputted.
The name of a HELP panel can be stored in the variable ZERRHM. This HELP
panel is called when the PF1 key is pressed after the message appears.
ISRZ003
Names of the variables:
Here you have the same options as with the ID ISRZ002. Additionally, you can
fill the variables ZERRTP and ZERRWN. I do not want to explain these two
variables, I have nowhere in the literature found a useful note concerning them.
If you are interested, I suggest you perform some tests with these variables. I
have never needed these variables previously.
Examples from practice programs for using the message member ISRZ001:
Example 1: Excerpt from a REXX program.
Lines Explanation
14: This query is determined that the message is only outputted if the REXX program runs in
FOREGROUND online under ISPF.
17+18 If ZERRLM contains an ISPF message, then the ISPF error message will be appended to the
existing message text.
70 Because the ISPF EDIT command stores its messages when an error occurs in the variables
ZERRSM and ZERRLM, then the message ID ISRZ002 can be used here.
78 Here, the variables ZEDSMSG and ZEDLMSG are filled with private texts. Therefore,
ISRZ001 will be used here.
Remark:
The program from which the above excerpt is derived, is an edit macro.
Therefore, the ISPF commands must be called using the form address
"ISPEXEC". You cannot use the shape by prefixing the command with ISPEXEC
here because the ISPF edit processor would not accept this. The shape with
ISPEXEC before an ISPF command only understands the TSO command
processor!
Standard Standard panels in ISPF normally have a width of 80 characters and consist of up to
panels 43 lines on a screen. When they are displayed, the currently displayed panel is
completely replaced.
HELP Help panels will be formed using certain instructions in the panel definition. They
panels can contain any number of rows and they have their own scrolling mechanism.
POPUP The dimensions of the pop-up panels are determined in the panel definition. When
panels you call them, they will be embedded in the currently displayed panel. The rest of the
underlying panel remains visible. POP Up panels can be moved while the display on
the screen using the cursor. HELP panels are very often defined as POP UP panels.
How to specify the attribute characters; see section 10.3.3.1 The Attribute
section starting on page 193.
Data fields
There are two types of data fields:
–Input fields. These are defined for entering data. Input fields can also be used
for output.
–Output Fields. These fields are only defined for output of data. Output fields
cannot be used for input.
How to specify the data fields; see section 10.3.3.2 The )BODY section on page
195.
The attribute character in front of the field defines the type of a data field.
The remaining lines can be designed as desired. ISPF short messages are always
displayed at the end of the first line from right to left in their current length. If
necessary, parts of the title line are truncated on the right. Long messages will,
if this is defined in the ISPF Settings menu, always be displayed at the bottom
of the panel in a frame. The )BODY section defines the panel structure.
Section Description
)ATTR The attr section defines the attribute characters for the fields of the panel.
)MODEL The model section defines a structure for the representation of variables of an ISPF
table.
)INIT The init section will go through before the panel is displayed. Here, initial values
can be set.
)REINIT The reinit section will go through when the panel is repeatedly displayed.
)PROC The proc section will go through when the panel display is exited by a command.
Here, the processing of the input values is performed. Typically, the plausibility
checks of the input values are performed here.
)END The end statement ends the panel definition. All lines behind this statement will be
ignored.
Example:
By defining this ATTR options, the following standard attribute characters are
active in this panel:
The attribute characters can be defined in any number and any character in the
)ATTR section. The following panel definition shows this:
Program 10.1: Panel definition of panel SLEP1
Note:
If the )ATTR statement is needed in a panel, this must always be the first line.
Comment lines can begin first after the )ATTR line.
The table below comes from the brochure ISPF Dialog Developer's Guide and
Reference. It contains all possible definitions for the attribute characters. The
most important type definitions for everyday use are greyed. I will refrain from
giving a complete description of all options. This is explained in the before
mentioned booklet and occupies circa 30 pages. I recommend you read this
when needed. Moreover, the options used in the above type commands are self-
explanatory.
Table 10.2: )ATTR definitions list
All information must be on the )BODY line. The greyed options are frequently
used. I will explain these here.
This statement defines a pop up panel which is 50 columns wide and 20
rows depth. It is important to ensure that the in the )BODY section defined
rows and columns fit the available framework.
With this statement, the expansion characters are determined. With these
characters, you can fill text lines dynamically with padding characters. See the
following example:
Example:
The panel definition of panel SLEP1 contains the following code:
The first and the last line are shown expanded with the expand character –
(hyphen).
Remark:
The expansion characters must be unique (just like the attribute characters)
within the panel definition. Therefore, this character can only be use for the
definition of dynamic expanding.
When assignments are performed, the following functions are often used for
the determination of the result:
If and ELSE:
Because no THEN is available, another rule must exist how commands are
defined when an IF statement as true ends. This rule is very simple:
Rule:
If an IF query is recognized as true, then all the instructions in the following
lines are executed that are indented at least one column to the right.
Again, it is beyond the scope of this book to discuss the above listed statements
and functions in detail. To explain the design of an ISPF screen, I will use the
screen SSCPP01. The SSCPP01 screen is one screen of the SMART ISPF utilities.
The SSC program calls it. The panel has a complex format and is therefore a
good example to explain the functionality of an ISPF screen structure:
Coding 10.3: SSCPP01 – Panel definition example
Explanations for some lines in this panel definition:
Lines Explanation
57+58: If the variable LRC was set greater than zero in the calling procedure SSC, then the
special variable .RESP will be filled with the text END. This means that the PANRC
variable is set to 1 at the end in row 111. When after returning from the panel the variable
PANRC is 1, the procedure SSC will be exited.
59: If the special variable .RESP contains the text ENTER, the statements up to line 108 will
be executed. Otherwise, the program is continued at line 109.
60– When the function code is EX, then only the expiration date of the data set is changed.
68: In these lines, the date variables that the function DSINFO has delivered will be checked
and if necessary updated. Due to the statement go to out: in line 068 the execution of
the panel continues at line 109.
69: The variable NEWDSN will be verified. NB means NEWDSN must not be blank.
DSNAME means that the variable must contain a valid DSN. If one of these conditions
is not met, then the message CR011A is displayed on the screen.
70: The variable FCHARS will be verified. FCHARS represents function characters. NB
means FCHARS must not be blank. LIST means that the variable must contain only one
of the values contained in the LIST option within the comma-separated text string. If
one of these conditions is not met, then the message CR010A will be displayed.
71+72: The variable FCHARS contains always two characters. The first character of FCHARS
is extracted into the variable FCHAR1 using the TRUNC function and the second
character is extracted in the variable FCHAR2 using the .TRAIL function.
73 If the variable FCHAR1 does not contain C, then no copying operation will be
performed. In this case, the statements until the line 108 is reached will be executed.
79–81: Here the functions TRANS and TRUNC are combined. This has the following meaning:
With TRUNC the first character of the variable UNITS will be extracted. Then the word
following the comma is placed in the UNITS variable with TRANS. This means the full
names are set by the TRANS function. The advantage of this method is that you always
have to enter only the first letter of CYLINDERS, TRACKS or BLOCK at the input. When
the content of the variable UNITS does not begin with one of the letters given in the list,
the message CR018A will be displayed and the program will be exited
The Z variables
Example:
The following excerpt from the panel Coding 10.3: SSCPP01 – Panel definition
example on page 198 shows the allocation of the Z variables in the .ZVARS
statement to the panel locations.
As you can see, 10 variable names are defined in the .ZVARS statement and 10
Z fields are defined in the panel. By the way, you can also address such variables
as Z variables which name would not be too long for a direct placement (e.g.
PRIM, SEC, UNITS).
Attention:
When you insert or remove Z variables during the development of a panel, it
is essential to adapt the .ZVARS statement accordingly.
I simulated such a critical copy task. See the display of the POP UP panel:
Tip:
You can use the cursor to move a pop-up panel within the totally available
display to another position. Proceed as follows: Place the cursor to a point of
the frame of the pop up panel and then press ENTER. Then the
text Window move pending appears in the upper right corner of the
screen. If you now move the cursor to any position in the screen and press
ENTER, the entire pop up panel will be moved to the new position. Using
this method, you can make invisible parts of the surrounding panel visible
again.
Remarks:
To define help panels the grayed lines are needed. I always use this template
when I need to create a new help panel. The general help panel is entered in
the )INIT section of the panel definition. Please note that help panels
specified in the )INIT section act as general help panels. They appear when
PF1 is pressed and the cursor stands at any position in the panel and not in
a field for which an own help panel exists.
Example:
The panel SLEP1 is a typical table display panel. The SMART ISPF utility
program SLE uses it:
Program 10.3: Definition of panel SLEP1
Lines Explanation
23 The )MODEL statement defines that the following line 24 structures the display of values
contained in the table $SLETAB.
24 The Z variable is the last one which occurs in the panel definition and therefore is assigned
to the last varaiable in in the .ZVARS definition in line 26. It is the variable function. The
fields of DSN, DATE and TIME are large enough to contain the variable name itself.
27 The general help panel for the panel SLEP1 is defined here.
42–8 Here the help panels for all fields are defined, which have an own help panel.
Command Function
)BLANK )BLANK 5 inserts 5 blank lines into the skeleton, which is being edited.
)CM With )CM, comment lines can be defined in the skeleton. These lines are not
copied to the output component.
)DEFAULT To control the skeleton processing, seven special characters are reserved by
default. These are the characters: ), &, ?, !, <, |, und >. With the )DEFAULT
command these characters can be changed temporarily
)ENDDOT
)IM This statement inserts another skeleton. The variables of the inserted skeleton will
be dissolved and the result is added to the output component.
)SEL With )SEL a condition can be queried. If this condition is satisfactory, all the rows
are
Example:
The following skeleton adds a step into a job which executes instructions for
DB2 BIND PACKAGE commands. The BIND PACKAGE instructions will not be
executed in this job step; they are executed in the called REXX procedure
VINTPAC.
JCL 11.6: Definition of a skeleton
Remarks:
–I have grayed all relevant places for a skeleton definition.
–In line 10 the skeleton $ISPFDD is inserted. This skeleton contains the
necessary DD statements for execution of REXX procedures in an ISPF batch
environment.
–If a skeleton variable should be connected to another skeleton variable, a point
is used as concatenation operator. If the resulting string is a DSN, an
additionally point will be inserted for separating the single DSN qualifiers. DSNs
are built in the lines 14 and 16. Therefore, here two consecutive dots are used
to assemble DSNs.
Here are the statements of the REXX procedure VINTSN that processes this
skeleton:
Coding 11.1: Skeleton processing
In this part of the program, most skeleton variables are filled with values. Some
have already been set earlier in the procedure. When the statement FTINCL
VINTPAC in line 3221 is executed, the following happens:
–The member VINTPAC will be searched in the data set chain associated with
the DD name ISPSLIB and inserted in an internal area.
–Thereafter, the file-tailoring service is called. This processes the skeleton line
by line.
–The contents of the variables from the REXX/ISPF variable pool replaces the
variables.
–Any existing file-tailoring statements are executed. In this skeleton only one
)IM statement is contained. The member $ISPFDD is searched in the ISPSLIB
chain and inserted in the JCL stream. The variables contained in the member
will be replaced by the actual values.
–When the file-tailoring service has conducted all processing, the result is
added to the internal data stream that has been opened with the FTOPEN
statement.
–When all file-tailoring work that is necessary to form a JCL member is finished
in the procedure VINTSN, the created JCL member is saved using the command
FTCLOSE NAME(name) LIBRARY(ddname). If ddname is not
specified ISPFILE is used.
Rule:
When I write a table (whether new or read before), then it will be written via
ISPTABL in the LANZT.ISPF.TLIBTAB.LPRT data set. When I read them
afterwards, it is first found in the same physical data set under the DD name
ISPTLIB and read from there. In order for the ongoing maintenance of a
table will guaranteed.
TBCLOSE Closes a table and saves it in the output data set if it had been read before.
TBSAVE Backs up a table in the member in ISPTABL without the table to close.
TBBOTTOM Sets the CRP (Current Row Pointer) on the last line
of the table.
TBVCLEAR Fills all the variables of the table with zero values.
Again, I will refrain from describing the above commands in detail. Instead, the
following examples will show you how to create a table and how to use it.
SLE Main This program is called as ISPF function. It displays the panel SLEP1
program and performs the work initiated there.
#IMACROA Edit If an edit session is started, this macro checks whether the IMACRO
macro option is already set for the edited data set in the edit profile. If this is
not the case, the option IMACRO is set to #IMACRO1.
#IMACRO1 Edit This macro defines an ALIAS so, that at the end of the edit session
macro #IMACRO2 is called.
#IMACRO2 Edit This macro will be called automatically when an edit session ends. It
macro inserts the DSN of the currently edited data set into the ISPF table
$SLETAB. At the next call of SLE, the name of the recently edited data
set is contained in the table $SLETAB and it will be displayed in the
panel SLEP1.
SLEP1 ISPF This is the main panel for execution of the SLE application. It shows
panel the table $SLETAB and offers the ability to perform some actions with
the shown data sets.
Many help panels are defined to assist the user in the working with the SLE
application. However, these panels are not important for the function of the
application and are therefore not named here.
Here the part of the edit macro #IMACRO2, which shows the updating (or
creation) of the ISPF table $SLETAB:
Program 12.1: Excerpt from edit macro #IMACRO2
Lines Explanations
70–74 When the table $SLETAB exists, it will be updated and written back to ISPTABL.
75–79 When the table $SLETAB does not exist it will be created and written into ISPTABLE as
new member which then contains one row of data.
Here an excerpt of the panel description of panel SLEP1 where the )MODEL
line defines the structure of the displayed rows of the table $SLETAB.
Coding 12.1:Excerpt from panel definition of the panel SLEP1
Lines Explanation
23 Here the model definition segment begins. This line can be followed by up to 8 definitions
of data structures.
24 Here only one line structure is defined. It contains the names and positions where the
contents of the variables of the table $SLETAB are displayed. Because in the previous
panel definitions already four Z-variables are set, the Z-variable in line 24 for the name
FUNCTION is assigned by the .ZVARS definition.
The TBDISPL command to display the panel SLEP1 together with the table
$SLETAB is shown in the following excerpt from program SLE:
Coding 12.2: Excerpt from program SLE showing the TBDISPL command of
panel SLEP1
Here now a display of the panel SLEP1 containing the data of the table
$SLETAB:
Screen 12.1: Display of panel SLEP1 produced by the program SLE
13 Variables – Definition and using
In this chapter, you will learn how to define and use ISPF variables. ISPF
variables are either automatically known in REXX programs or they can be
made known there.
Advice:
If you intend to use a defined variable in REXX source code and in the called
ISPF services, then the variable name must not be longer than eight characters.
The variables of the ISPF services are an important part of ISPF. Dialog
variables are the primary communicator between the individual components
of ISPF. Programs, procedures, panels, tables and skeletons can all share the
variables from the three ISPF variable pools. The three ISPF variable pools are:
–Function pool for implicit variables.
–Shared pool.
–Profile pool.
The variables are combined in groups, which are associated with a particular
service. Many variables are set only by certain ISPF services. Other variables
must be filled with appropriate values before a service that requires these
variables is called. A ISPF application ID is assigned to each pool of variables.
xxxx PROF, where xxxx is the up to four digits long name of the application. The
profile members are created and processed as ISPF tables.
The following figure shows an excerpt from the list of members in the ISPPROF
data set of my TSO user:
Consideration:
ISPF will be started at the end of the LOGON procedure. This can be done with
three different commands:
1ISPSTART PANEL(name) NEWAPPL(applid).
2PDF
3ISPF
If called with PDF or ISPF, then the following command is issued internally:
When these applications are launched, then all members belonging to these
applications profiles must be loaded. This can be checked very easily by looking
up which ENQs exist on the data set containing the profile members. The easiest
way to check this is using the utility DDLIST. Therefore, I called DDLIST and
entered ENQ in the command line. In the appearing panel, I entered as minor
name prefix the DSN of my profile data set LANZT.ISPF.PROFILE.LPRT and
pressed ENTER.
SHARED The variable is searched only in the shared pool. If it is not found there, the command
ends with a RC=8.
PROFILE The variable will be searched only in profile pool. If it is not found there, the command
ends with a RC=8 and a variable of the same name in the shared pool will be deleted.
PROFILE The variable is only written to the profile pool. A variable of the same name in the shared
pool is deleted.
BOTH The variable is deleted from the shared and from the profile pool.
Remark:
All REXX variables whose name is not longer than eight characters are
automatically known in function pool. If you want to write a REXX variable
into the shared or profile pool, you must explicitly use a VPUT command.
Example:
I wrote a small REXX procedure to read and display some ISPF Z-variables:
Step 1:
I enter SSS in front of the PDS where the SMART ISPF utility programs are
located. The following panel will displayed. In the field 1. = I enter the search
text QUERYENQ.
Screen 14.1: Panel SSSP1 for entering search arguments
When enter is pressed, the search will performed and the following edit panel
is displayed:
The program ISRSUPC produces a list with LRECL=133. Therefore, the lines of
this display are cut off on the right side. To see what lines by the macro #SSS
were removed, here is the origin output of the program ISRSUPC:
Screen 14.3: Original output list of program ISRSUPC
Step 2:
As you can see in line 487 of the program SLE, the word Paramter is wrong. I
will now correct this error. First, I remove all unneeded lines and correct the
wrong word to Parameter. Then the following edit panel remains:
I enter #SSSCH in the command line and press enter. The following display
appears:
What shall the macro #SSS do with the list produced by ISRSUPC?
–Remove any blank lines.
–Remove all lines that start with the following texts: ISRSUPC, PROCESS
OPTIONS USED, THE FOLLOWING PROCESS.
–Shift the lines where the name of the text SEARCH DNS: scanned data set
appears together with the DSN as far to the left that the DSN text starts at
column one.
–Remove the lines that begin with LINES-FOUND together with the next line.
–At the beginning of the revised text put a notice that this data set has been
optimized by macro #SSS.
–Inserting a row by pointing out that using the edit macros #SSSCH, the edited
and possibly changed lines can be written back to the members.
This command positions the cursor on line line and column col in the edited
data.
“(line,col) = cursor”.
The variable line contains the cursor position of the current line and the
variable col the column in the line of the data currently being edited.
As you can see in the following table, many edit macro commands offer both
possibilities.
The following table is a condensed summary of the main edit macro commands
as can be used in a REXX procedure. Of course, the IBM brochure Edit and edit
Macros also contains a description of the edit macro commands. However, this
is presented in a very confusing manner. Incidentally, this is one of the reasons
why this book has been written. Therefore, I make an effort to present the
reader a focused summary in the following table.
Table 14.1: Edit macro commands
14.3 OPERANDS AND ABBREVIATIONS USED
IN THE EDIT MACRO COMMANDS
To help you work with the macro commands as listed in the table above, please
find below a brief description of those operands and abbreviations that are not
always self-explanatory by their name:
Table 14.2: Operands and abbreviations of edit macro commands
Operands Meaning
(var) The name of a variable must be specified. This name must be not longer than 8
characters. If the (var) is on an assignment statement on the left side, the editor
stores into the variable a value. If (var) is on the right side in an assignment
statement, the REXX program must have been previously stored a value into the
variable.
[FIRST] A search for the first or last occurrence of the text is performed in the data
[LAST] currently being edited.
[NEXT] Starts at the current cursor location and performs the operation forward [NEXT]
[PREV] or backward [PREV] in the data currently being edited.
[x] [nx] The operation in question is performed only for EXCLUDED lines (x) or the NOT
EXCLUDED lines (nx).
ALL This operation will affect all lines of the data currently being edited.
amt amt defines the relative number of elements in shift or jump operations. (amt =
amount)
col-1 col-2 Two integers, which limits an operation on the designated columns.
col1 col2
label-range Consists of two line labels of the form .LA and .LB. These can either be standard
labels such as .ZF And .ZL or user-defined edit labels. The characters after the
point may be just letters.
linenum-range Two integer variable or constant that designate a start and an end line for an
operation.
lptr col Integers that contain a line number and a column number.
lptr-range Two integers that specify the first and last line for an operation.
14.4.1 Prototyping
Unfortunately, there is no macro recorder for the ISPF editor available. I
recommend the edit commands, before you use them it in a REXX program to
test them by manually entering in the editor. Therefore, you should prototype
commands after you have seen that the result is right, gather in a second data
set using the clipboard, and then you can create the edit macro from this
collection.
Example:
The following sample macro determines some values using macro commands.
I inserted trace ?i at the beginning. Thus, the development of the variable is
displayed and the macro stops after each command. I entered SAY commands
to display contents of variables at the stop points.
I entered the shaded commands by hand each time when the TRACE stops. As
you can see, the echo print of the REXX commands contain the REXX source line
number.
14.4.3 The program ISREMSPY
During run of the macro, you can use the program ISREMSPY to look at the data
currently being edited at this time. This program is a purely formal TSO
program. Therefore, it must be run under ADDRESS TSO. It can only be used
within an edit session or during the execution of edit macros. To demonstrate
the application of this program, I wrote the following small macro.
Program 14.4: Example program for using the macro testing aid ISREMSPY
I called this macro in the edit session of the data set displayed on the following
screen. On the pages thereafter, you will find the generated screens on each call
of ISREMSPY.
Name Content
.ZCSR Contains the line number where the cursor is currently located.
.ZFIRST Contains the line number of the first row of the data currently being edited. You can
abbreviate it with .ZF.
.ZLAST Contains the line number of the last row of the data currently being edited. You can
abbreviate it with .ZL.
Format:
MACRO (parm1,parm2,..)
The variable names in macro parameters must not be longer than eight
characters. parml and parm2 are variables that must be known in the calling
REXX program.
Example:
The edit macro #ALTXT of the SMART ISPF utilities requires two or four
parameters.
Program 14.5: #ALTXT – Use of parameter passing to edit macros
The Help panel of this edit macro:
#TSOB Edit macro to submit a batch job that executes the REXX procedure currently being edited
within a TSO environment.
Advice:
Please look at these edit macros. Everything is included there. You need to
create and SUBMIT batch jobs using edit macros.
When enter is pressed, the search will performed and the following edit panel
is displayed:
Step 2:
As you can see in line 487 of the program SLE, the word Paramter is wrong. I
will now correct this error. First, I remove all unneeded lines and correct the
wrong word to Parameter. Then the following edit panel remains:
I enter #SSSCH in the command line and press enter. The following display
appears:
What shall the macro #SSS do with the list produced by ISRSUPC?
–Remove any blank lines.
–Remove all lines that start with the following texts: ISRSUPC, PROCESS
OPTIONS USED, THE FOLLOWING PROCESS.
–Shift the lines where the name of the text SEARCH DNS: scanned data set
appears together with the DSN as far to the left that the DSN text starts at
column one.
–Remove the lines that begin with LINES-FOUND together with the next line.
–At the beginning of the revised text put a notice that this data set has been
optimized by macro #SSS.
–Inserting a row by pointing out that using the edit macros #SSSCH, the edited
and possibly changed lines can be written back to the members.
This command positions the cursor on line line and column col in the edited
data.
“(line,col) = cursor”.
The variable line contains the cursor position of the current line and the
variable col the column in the line of the data currently being edited.
As you can see in the following table, many edit macro commands offer both
possibilities.
The following table is a condensed summary of the main edit macro commands
as can be used in a REXX procedure. Of course, the IBM brochure Edit and edit
Macros also contains a description of the edit macro commands. However, this
is presented in a very confusing manner. Incidentally, this is one of the reasons
why this book has been written. Therefore, I make an effort to present the
reader a focused summary in the following table.
Table 14.1: Edit macro commands
14.3 OPERANDS AND ABBREVIATIONS USED IN
THE EDIT MACRO COMMANDS
To help you work with the macro commands as listed in the table above, please
find below a brief description of those operands and abbreviations that are not
always self-explanatory by their name:
Table 14.2: Operands and abbreviations of edit macro commands
Operands Meaning
(var) The name of a variable must be specified. This name must be not longer than 8
characters. If the (var) is on an assignment statement on the left side, the editor
stores into the variable a value. If (var) is on the right side in an assignment
statement, the REXX program must have been previously stored a value into the
variable.
[FIRST] A search for the first or last occurrence of the text is performed in the data
[LAST] currently being edited.
[NEXT] Starts at the current cursor location and performs the operation forward [NEXT]
[PREV] or backward [PREV] in the data currently being edited.
[x] [nx] The operation in question is performed only for EXCLUDED lines (x) or the NOT
EXCLUDED lines (nx).
ALL This operation will affect all lines of the data currently being edited.
amt amt defines the relative number of elements in shift or jump operations. (amt =
amount)
col-1 col-2 Two integers, which limits an operation on the designated columns.
col1 col2
label-range Consists of two line labels of the form .LA and .LB. These can either be standard
labels such as .ZF And .ZL or user-defined edit labels. The characters after the
point may be just letters.
linenum-range Two integer variable or constant that designate a start and an end line for an
operation.
lptr col Integers that contain a line number and a column number.
lptr-range Two integers that specify the first and last line for an operation.
14.4.1 Prototyping
Unfortunately, there is no macro recorder for the ISPF editor available. I
recommend the edit commands, before you use them it in a REXX program to
test them by manually entering in the editor. Therefore, you should prototype
commands after you have seen that the result is right, gather in a second data
set using the clipboard, and then you can create the edit macro from this
collection.
Example:
The following sample macro determines some values using macro commands.
I inserted trace ?i at the beginning. Thus, the development of the variable is
displayed and the macro stops after each command. I entered SAY commands
to display contents of variables at the stop points.
I entered the shaded commands by hand each time when the TRACE stops. As
you can see, the echo print of the REXX commands contain the REXX source line
number.
14.4.3 The program ISREMSPY
During run of the macro, you can use the program ISREMSPY to look at the data
currently being edited at this time. This program is a purely formal TSO
program. Therefore, it must be run under ADDRESS TSO. It can only be used
within an edit session or during the execution of edit macros. To demonstrate
the application of this program, I wrote the following small macro.
Program 14.4: Example program for using the macro testing aid ISREMSPY
I called this macro in the edit session of the data set displayed on the following
screen. On the pages thereafter, you will find the generated screens on each call
of ISREMSPY.
Name Content
.ZCSR Contains the line number where the cursor is currently located.
.ZFIRST Contains the line number of the first row of the data currently being edited. You can
abbreviate it with .ZF.
.ZLAST Contains the line number of the last row of the data currently being edited. You can
abbreviate it with .ZL.
Format:
MACRO (parm1,parm2,..)
The variable names in macro parameters must not be longer than eight
characters. parml and parm2 are variables that must be known in the calling
REXX program.
Example:
The edit macro #ALTXT of the SMART ISPF utilities requires two or four
parameters.
Program 14.5: #ALTXT – Use of parameter passing to edit macros
The Help panel of this edit macro:
#TSOB Edit macro to submit a batch job that executes the REXX procedure currently being edited
within a TSO environment.
Advice:
Please look at these edit macros. Everything is included there. You need to
create and SUBMIT batch jobs using edit macros.
Edit macros:
These program names all begin with character # (hash). Using these names
rule, the macros are easily distinguishable from the other programs.
Direct executable:
These program names all begin with character S (stands for smart).
#EDMEM stand Edit a member which name is the first word in a line of a data currently
alone being edited.
#IMACROA assist SLE General ISPF edit macro. Automatically executed by ISPF when an edit
session starts even if no initial macro is set for the data set currently
being edited.
#IMACRO1 assist Initial macro to insert DOC: lines into a data set, which is called for
SDOC editing.
#IMACRO2 assist SLE This macro inserts the DSN of an edited data set into the table
$SLETAB.
#ISPFB stand Edit macro to submit a batch job to execute the REXX procedure
alone currently being edited within an ISPF environment.
#LCH stand Offers the possibility to perform an edit change command with a long
alone parameter list.
#SSSCH assist SSS This macro can be used when a super search list currently being edited
to restore the displayed lines back into the members in which the
searched lines were found.
#SPLJ stand This macro performs SPLIT and JOIN operations within an edit
alone session.
#SU stand Submit a JCL that does not contain a JOB statement.
alone
#TSOB stand Edit macro to submit a batch job that executes the currently edited
alone REXX procedure within a TSO environment.
#VERASE stand Erase an ISPF variable from the profile and the shared pool.
alone
SCURSOR stand Access to a data set by EDIT, VIEW, BROWSE, MEMLIST or DSINFO.
alone The DSN must appear on an ISPF panel.
SDOC stand This program reads all members of a PDS and produces the $DOC
alone member in the same PDS.
SHOSTPAC stand This macro grabs all members of a PDS and saves the result under the
alone name of the data sets LLQ in the same PDS.
SHOSTUNP stand Unpack a packed member coming as an upload from a PC which was
alone originally packed at a z/OS by the REXX program SHOSTPAC.
SJOBSUFF function Provide job suffix character for dynamic job assembly.
SLISTC stand Produce an IDCAMS LISTCAT of a data set and browse the list. Call in
alone front of a DSN in a DSLIST display.
SLISTRAC stand Produce a RACF LISTDSD of a data set and browse the list. Call in
alone front of a DSN in a DSLIST display.
SPROFEDT stand Execute program SPROFVAR to store users ISPF profile environment
alone variables into ISPF profile.
SPROFVAR stand Store the user’s environment variables into ISPF profile.
alone
SSC01 assist SSC Messages for panel SSCPP01 called by function SSC.
Description:
The edited list can come from following sources:
–A list output of the procedure SSS and processed by the #SSS macro.
–A list output produced by ISPF function SRCHFOR in the resulting display list.
–The member $DOC from a PDS.
At call, the cursor must be in a line in which the member name occurs as first
word. No further help available.
Note:
For an optimal use of this macro, its call should be set on a PF key. E.g. PF22.
Function:
When the "Command = = = >" line in the normal edit panel is too short to contain
the whole CHANGE command, you can use this program to solve the problem.
This program opens a panel for input of two lines each with max 70 characters.
The first line is the SEARCH argument for the change and the second line is the
replacement value. Additionally, you can enter parameters for the CHANGE in
a third line. E.g. 1, ALL, WORD...
Functional description:
When this macro is called, further processing of the position of the cursor
depends on the following:
1.If the cursor is within a line and after this position, characters are on the line,
these characters are moved to a new line after the current one. This is the split
function.
2.If after the position of the cursor only blanks are on the line, the line after the
current line moves to the current line after the cursors position. This is the join
function.
Functional description:
Delete all unnecessary lines from a list produced by the Super Search Function
of ISPF. The procedure SSS calls this macro as initial macro. If you have
performed a manual search, you can also use this macro to revise the list output.
There is no other help available.
15.4.11 Edit macro #SSSCH – Mass update of members
This macro offers a very smart functionality:
When you have performed a super search and you make some changes in the
edited list, you can write back the displayed lines completely to its members.
With this possibility, you can perform mass changes on many members in one
step.
Purpose:
This macro can be used, when a super search list is displayed in edit session, to
restore the displayed lines back into the members in which the searched lines
were found. There is no other help available.
Remarks:
You can remove rows and members from the data set currently being edited. If
you delete a member, all lines belonging to this member must also be deleted
bulky. New rows cannot be inserted because the row numbers which are
included in the displayed list, contain the relative position of these lines in the
member. These line numbers will be used when the lines are written back to
the member. The existing lines with the same number will be overwritten. If
you do not want to write back changes in individual lines, you can of course
delete these lines before calling #SSSCH.
Function description:
The program assembles the job statement using user-defined variables from
ISPF profile pool. Use the program SPROFVAR to store these variables into the
ISPF profile pool.
Special function:
EXCLUDED lines of the edited data set are NOT inserted in the submitted job
stream.
Attention:
Due to using the TSO SUBMIT command, all lines of the edited data set are
translated to UPPER CASE during SUBMIT. This is a regular effect of SUBMIT.
Author's remark:
During my years of consultant activity, I always had all my job statements
adapted to varying conditions in the data centers. To have to not always do this,
I developed the REXX program SPROFVAR. There, I have all the values that
apply to a data center inserted as variables and stored them in the ISPF profile.
When I installed the SMART ISPF utilities at a new customer, I adapted and
executed only the member SPROFVAR. In all the jobs I had to run at the
customer's site, I was able to leave the job statement and start jobs with #SU.
Attention:
This macro does not save the source code of the data set currently being edited.
Hence, the UNDO status of the edit session is not changed by this macro.
Remarks:
To avoid the SAVE command, the currently edited REXX procedure is stored to
a work data set. The batch job will use this work data set to execute the REXX
procedure. The description of the 'SUBMIT *' command in the manual TSO/E
Command Reference contains the following note: The SUBMIT command
converts all characters of the job stream to uppercase before the stream is
submitted to the system.
Note:
To avoid setting all JCL lines in uppercase by command SUBMIT * and thus also
the line which contains the parameter text, this procedure writes the job stream
to member JOB into a work data set and submits the job from this member by
using the command: "SUBMIT '"workfile"(JOB)'". In this case, the lines of the
member JOB will not be transferred to uppercase.
Description:
If a DSN of a data set appears on any ISPF screen, you can get access to this data
set by positioning the cursor within the DSN and call SCURSOR. For a
comfortable use of this function, I recommend to program a PF KEY with TSO
%SCURSOR. If you have positioned the cursor at any position within a DSN and
then pushed the PF key a panel appears to offer a range of access possibilities
to the data set. There are some restrictions for displaying GDGs and VSAM data
sets.
Function:
The program scans all members of the PDS for lines with keyword DOC: as the
second word in a line. Only the first 200 lines in each member will be scanned.
When during this scan no DOC: lines are found, then only the member name will
be stored in the output. When the first DOC: line is found and there are more
than five lines following the last found DOC: line without a DOC: the scan of this
member ends.
Remark:
Help screens are available for all greyed fields. Position the cursor in such a field
and press PF1 to display the help. The general help screen appears, when the
cursor is on any other position on the screen and PF1 is pressed.
Tip:
Insert the following command in the ISPF command table to call the last edit
function very fast when you type in SL in the ISPF command line.
_ SLE 2 SELECT CMD(%SLE)
REXX SLE CALL THE LAST EDIT FUNCTION
For installing this logon procedure, see section 15.6.2 Installation on page 286.
Note:
If SLOGDSN contains DSNs of not existing data sets, a warning message is
displayed during SLOGON, but the logon process continues anyway. This
ensures that the logon process is successfully performed and a working user
environment is created. This is a very important advantage of the
procedure SLOGON.
#C This edit macro compiles the REXX program currently being edited and executes
the compiled program immediately after the compile. One parameter can be
added in the #c call statement. This parameter string will be passed to the
compiled program to be used at execution time. To get an online tutorial
description enter: #c ?
#RO Online compile of the REXX program currently being edited. This procedure can
be called as an edit macro or in front of a member name in a DSLIST/M display
panel. Parms: When #RO is used as a macro additional compiler options may be
passed as parameters.
#RC Use this procedure to assemble and submit a batch job to compile a REXX
procedure.
#RCLOAD Assembly and SUBMIT a job to compile a REXX procedure and generate a LOAD
module or a CALL module.
#IE Edit macro to insert in an application program the call lines to the internal
ISPF_ERROR subroutine. The inserted statements calls the ISPF error handling
subroutine ISPF_ERROR in case an error appears. See the next row in this table.
ISPFERR ISPF error handling routine This subroutine is called when a call to an ISPF
service function ends with an error.
#PAN The screen whose program code is currently being edited will be displayed
immediately.
DAYDIFF Calculates the number of days between two DATE values. DATE values are
entered in the form dd.mm.yyyy.
ENDDAY Calculates the target date for a period of days starting at a given date plus or
minus a number of days.
JULDATE This subroutine calculates for a standard date the JULDATE or vise versa.
LEAPYEAR Calculates whether the entered year is a leap year or not. This function returns a
1 if the entered year is a leap year, otherwise it returns 0. Caution: No plausibility
checking of the entered year parameter is performed.
SCHANGE This REXX subroutine performs changes in any strings. See section
4.6.3 SCHANGE – Change of texts on page 86.
SDYNPAN This program converts the source code of an ISPF panel so that the code can be
embedded in a REXX procedure to be dynamically loaded from there into a
temporary ISPPLIB for execution.
Program description:
Edit macro #c:
Edit macro to compile and execute the REXX procedure currently being edited.
After the characters #c you can enter a string, which will be passed as
parameter to the program for execution.
Examples:
Attention:
The entered parameter string MUST NOT contain the ISPF delimiter character.
This character is used for ISPF command stacking and your parameter will
possibly be truncated at the delimiter character position.
The ISPF delimiter character can be found in ISPF menu 0 in the line Command
delimiter.
Processing flow:
The REXX program currently being edited is written to a work data set. This
data set is used for input to the REXXCOMP program. If compilation is
successful, the CEXEC module is written to the online work data set with
DDNAME ##DD. If the ##DD data set is not allocated, it will be allocated. If the
compilation ends with a RC > 0, the compiler listing is immediately browsed.
The compiled program will be executed using the ISPF SELECT CMD service.
Remark:
Because the REXX program currently being edited is not stored to its data set
for the purpose of compilation, the UNDO command can still be used.
The name of the output data set for the CEXEC code is set up as follows: The last
qualifier of the input DSN is substituted by CEXEC
Example:
The name of the output data set for the CEXEC code is set up as follows: The last
qualifier of the input DSN is substituted by CEXEC
Example:
Attention:
There are two things necessary in order to use this macro:
1.The REXX compiler REXXCOMP must be available in your system. You can
check this using the DDLIST utility.
2.The REXXCL jcl procedure must be available in your system. Ask your system
programming department where it is.
Link library:
If STUB: MVS is set, a file in the source code needs to be defined to where the
load module is to be written. This load library is named by a comment line in
the source code which is structured as follows:
/* LNK: DSN of the load library */
Example:
/* LNK: PEVX.LANZ.LOAD*/
After each call to an ISPF service, the following five lines of code are inserted:
The five lines must be manually inserted in the source code of a program as
follows:
1.Enter #IE in the ISPF command line or program a PF key with #IE.
2.Move the cursor to the line containing the call to an ISPF service.
3.Press enter or the appropriate PF key which contains the command #IE. The
above mentioned five lines will be inserted immediately behind the ISPF
command line.
Description of the lines:
Lines 1 and 5 contain comments and are self-explanatory.
Line Explanation
2 The RC returned by the ISPF service is passed as first parameter. Depending on the RC that
was returned by the ISPF service, a call will be executed to the error handling subroutine
ISPF_ERROR.
3 This line is passed as the second parameter to the subroutine ISPF_ERROR. It contains the
original ISPF command line without the variables contained in the command line being
resolved. This text is used by the subroutine ISPF_ERROR to find the original command line
in the source code of the program by using the REXX command SOURCELINE().
4 This line is passed to ISPF_ERROR as third parameter. It contains the original ISPF
command line with the variables contained in the command line being resolved.
Example:
When using this method, errors in executing ISPF services are displayed as
follows:
I replaced in the above example the contents of the variable DATASET by the
text faked DSN to manually enforce the error. The statement where the error
occurs is in line number 284 in the source code of the program.
Example:
The following call to DAYDIFF returns 365:
say daydiff(15.05.2015 15.05.2014)
SHOSTUNP REXX program to unpack REXX programs and ISPF PANELS into their
libraries on z/OS host.
The two files REXX and PANELS contain all procedures and all panels of the
SMART ISPF utilities in packed form. After transferring into the appropriate
libraries on the z/OS/ system, they must be unpacked using the REXX program
SHOSTUNP. This REXX program is the only program that is usable to unpack
the data sets because the packed data sets have a proprietary format.
Note:
The last three lines in the above panel show the commands automatically
executed under TSO while the upload was running.
15.6.2 Installation
For the installation of the SMART ISPF utilities, multiple scenarios concerning
your TSO/ISPF user environment are possible:
1. You still have an own ISPF library environment with an own logon procedure.
This is the ideal case. You can copy the REXX procedures of the SMART ISPF
utilities directly into your SYSEXEC or SYSPROC library and unpack them there.
If you want to use a panel library for the panels, you can copy the panels to the
ISPPLIB chain. Additionally, you can decide whether you want to use the
SLOGON procedure of the SMART ISPF utilities together with the member
SLOGDSN to make your logon process more variable and convenient.
2. You get the TSO READY prompt when you leave ISPF.
In this case, you can call the logon procedure SLOGON at the READY PROMPT
using the command EX 'dsn(SLOGON)'. First, you must only adjust the member
SLOGDSN so that there the correct data set names are included.
3. Your TSO user is completely logged off when you leave ISPF and you have no
chance to start an own logon procedure.
In this case, you can still use the SMART ISPF utilities. However, installation of
the call environment is somewhat more complex. You can use the command
ALTLIB. While there is a restriction that makes the process somewhat
inconvenient: If you have performed an ALTLIB command, the calling
environment thus created is always only available in the logical screen in which
the ALTLIB command was executed. See the description of the ALTLIB
command below.
dsn is the data set where your REXX procedures reside. If you have installed
the REXX procedures of SMART ISPF utilities into this dsn, the utilities are also
executable.
Recommendation:
Program a PF key with this ALTLIB call. When you open a new logical screen in
ISPF, then you can execute the command immediately by pressing the PF key.
Example:
The following screen shows the assignment of keys PF18 and PF19 for
execution of the ALTLIB command.
Screen 15.8: PF key setting to execute ALTLIB
The command ALTLIB DISPLAY shows the current ALTLIB chain. After pressing
PF18 and then PF19, the following display appears:
I used DDLIST to find the DDNAME SYS00278 and found it in the following
screen:
Example:
I pressed PF18 four times and then I pressed PF19. The following chain
appears:
Note:
The command ALTLIB DISPLAY shows in opposition to the command ISPLIBD
only the DD names of the allocated data sets. If you want to see the
corresponding DSNs, you can view them with the utility DDLIST as shown
below.
15.6.4 Make the SMART ISPF utilities ready to run
Before you can use the SMART ISPF utilities, there are still some steps
necessary:
1.If you can fully use an own logon procedure, you must adapt the members
SLOGON and SLOGDSN and perhaps copy the procedure SLOGON into an
appropriate library. See section 15.6.2 Installation on page 286.
2.Edit the member SPROFVAR, perform the necessary changes and execute it
using the edit macro ##. This program is executable without having to load the
ISPF profile variables for the SMART ISPF utilities.
Conclusion:
After having performed all mentioned steps above, the SMART ISPF utilities
should work fine and I wish you much success with it.
List of tables
Table 1.1: Reference books for the programming of ISPF applications
Table 1.2: ISPF service groups
Table 14.4: Edit macros of SMART ISPF utilities to assemble and submit batch jobs
List of screens
Screen 2.1: Example of a command call in a DSLIST display panel
Bibliography
This bibliography contains excerpts from some IBM manuals concerning the
z/OS TSO/ISPF complex:
TSO/E Publications
–z/OS TSO/E Administration, SA22-7780
–z/OS TSO/E CLISTs, SA22-7781
–z/OS TSO/E Command Reference, SA22-7782
–z/OS TSO/E Customization, SA22-7783
–z/OS TSO/E General Information, SA22-7784
–z/OS TSO/E Guide to SRPI, SA22-7785
–z/OS TSO/E Messages, SA22-7786
–z/OS TSO/E Primer, SA22-7787
–z/OS TSO/E Programming Guide, SA22-7788
–z/OS TSO/E Programming Services, SA22-7789
–z/OS TSO/E REXX Reference, SA22-7790
–z/OS TSO/E REXX User’s Guide, SA22-7791
–z/OS TSO/E System Programming Command Reference, SA22-7793
–z/OS TSO/E System Diagnosis: Data Areas, GA22-7792
–z/OS TSO/E User’s Guide, SA22-7794
ISPF Publications
–z/OS ISPF Dialog Developer’s Guide and Reference, SC19-3619-00
–z/OS ISPF Dialog Tag Language Guide and Reference, SC19-3620-00
–z/OS ISPF Edit and Edit Macros, SC19-3621-00
–z/OS ISPF Messages and Codes, SC19-3622-00
–z/OS ISPF Reference Summary, SC19-3624-00
–z/OS ISPF Services Guide, SC19-3626-00
–z/OS ISPF User’s Guide Vol I, SC19-3627-00
–z/OS ISPF User’s Guide Vol II, SC19-3628-00
Bibliography
This bibliography contains excerpts from some IBM manuals concerning the
z/OS TSO/ISPF complex:
TSO/E Publications
–z/OS TSO/E Administration, SA22-7780
–z/OS TSO/E CLISTs, SA22-7781
–z/OS TSO/E Command Reference, SA22-7782
–z/OS TSO/E Customization, SA22-7783
–z/OS TSO/E General Information, SA22-7784
–z/OS TSO/E Guide to SRPI, SA22-7785
–z/OS TSO/E Messages, SA22-7786
–z/OS TSO/E Primer, SA22-7787
–z/OS TSO/E Programming Guide, SA22-7788
–z/OS TSO/E Programming Services, SA22-7789
–z/OS TSO/E REXX Reference, SA22-7790
–z/OS TSO/E REXX User’s Guide, SA22-7791
–z/OS TSO/E System Programming Command Reference, SA22-7793
–z/OS TSO/E System Diagnosis: Data Areas, GA22-7792
–z/OS TSO/E User’s Guide, SA22-7794
ISPF Publications
–z/OS ISPF Dialog Developer’s Guide and Reference, SC19-3619-00
–z/OS ISPF Dialog Tag Language Guide and Reference, SC19-3620-00
–z/OS ISPF Edit and Edit Macros, SC19-3621-00
–z/OS ISPF Messages and Codes, SC19-3622-00
–z/OS ISPF Reference Summary, SC19-3624-00
–z/OS ISPF Services Guide, SC19-3626-00
–z/OS ISPF User’s Guide Vol I, SC19-3627-00
–z/OS ISPF User’s Guide Vol II, SC19-3628-00