REXX TrainingSESSION 1 Introduction to REXX REXX basics REXX Instructions REXX Built-in Functions REXX External functions REXX TSO/E External commands SESSION 2 Executing REXX in BATCH mode Introduction to REXX Edit macros Examples on REXX Edit macros File Tailoring ISPF Tables REXX Quiz What is REXX after all ? Restructured EXtended eXecutor language Programming Language Free format language Issues commands to different Host environments Has extensive mathematical capabilities Suitable for beginners as well computer professionals USAGE of REXX Automating repetitive tasks - Increases productivity - Ex : Allocation of datasets for a release - Ex : Deleting 7th char in all records of a file Interacting with TSO/ISPF dialog manager - to create and display custom-made panels - can store and retrieve variables Creating new commands - Like TIME command, DATE can be created For personal programming tasks - to send a mesg to other MVS users everytime you logon Writing a simple REXX exec An exec is nothing but a group of REXX statements in a sequential dataset or a PDS member The first statement of an exec should be µ /* REXX */ ¶,but not in all cases A simple exec (In a PDS member,MYFIRST) /*REXX*/ SAY µThis is first REXX exec¶ EXIT REXX is case insensitive Executing a REXX exec Explicit execution from tso ready prompt READY EXEC µTATA.REXX.EXEC(MYFIRST)¶ EXEC READY Implicit execution requires the PDS library to be concatenated to either SYSEXEC or the SYSPROC system DDNAME¶s. READY ALLOC DD(SYSEXEC) DSN(µTATA.REXX.EXEC¶) SHR REUSE READY %MYFIRST From ISPF,one can execute it by issuing the following command at command prompt TSO MYFIRST Executing a REXX exec A sequential dataset needs no allocation It can only be executed using the explicit method or the long form From READY prompt, READY EXEC µTATA.SEQ.EXEC¶ EXEC READY CTP LOGON ALLOCATION In CTP main panel, Select 0 --> CTP parms REXX - Arithmetic operators + * / % // ** Add Subtract Multiply Divide Divide and return a whole number without a remainder Divide and return the remainder only Raise a number to a whole number power -number Negate the number +number Add the number to 0 REXX - Logical operators & AND (4 > 2) & (a = a) /* true, so result is 1 */ (2 > 4) & (a = a) /* false, so result is 0 */ | Inclusive OR (4 > 2) | (5 = 3) /* at least one is true, so result is 1 * (2 > 4) | (5 = 3) /* neither one is true, so result is 0 */ && Exclusive OR (4 > 2) && (5 = 3) /* only one is true, so result is 1 */ (4 > 2) && (5 = 5) /* both are true, so result is 0 */ Prefix \ \0 \ (4 > 2) Logical NOT /* opposite of 0, so result is 1 */ /* opposite of true, so result is 0 */ REXX - comparison operators == = \ == \= > < >< >= \< <= \> Strictly Equal Equal Not strictly equal Not equal Greater than Less than Greater than or less than (same as not equal) Greater than or equal to Not less than Less than or equal to Not greater than Note: The not character, "¬", is synonymous with the backslash ("\"). REXX Symbols A REXX symbol can consist of A...Z a...z 0...9 @#$¢?!._ uppercase alphabetic lowercase alphabetic numbers special characters Rules for valid REXX symbols are : The first character cannot be 0 through 9 or a period (.) The variable name cannot exceed 250 bytes The variable name should not be RC, SIGL, or RESULT, which are REXX special variables REXX Special Variables RC: RC stands for return code and is set every time a command is issued.When a command ends without error, RC is usually set to 0. When a command ends in error, RC is set to whatever return code is assigned to that error. SIGL: The SIGL special variable is used in connection with a transfer of control within an exec because of a function, or a SIGNAL or CALL instruction. When the language processor transfers control to another routine or another part of the exec, it sets the SIGL special variable to the line number from which the transfer occurred. RESULT : When an exec calls a subroutine ,the calling exec receives the value returned by the subroutine in the REXX special variable RESULT REXX Instructions Cool Man! Life Made Easy« REXX Instructions A line contains usually one instruction Comma(µ,¶) is the continuation character Semi-colon(µ;¶) is the instruction delimiter Example : say µThe quick fox jumps over¶, µthe lazy brown dog¶; say µover¶ Output : The quick fox jumps over the lazy brown dog over Note that the comma operator adds a space REXX Instructions - SAY To write a line of output to the TSO terminal Syntax SAY {expression} Expression can be of any size and REXX will split it up according to line-width of the terminal Expression can contain variables, literals and functions Example /*REXX*/ name=µRoosevelt¶ say µWelcome to TSO µ name exit Output Welcome to TSO Roosevelt REXX instruction - PULL to read the input from the TSO terminal(When REXX data stack is empty) Syntax : PULL var1 var2 var3« Example : /*REXX*/ say µEnter your name :¶ pull name say µGood morning µ name exit The output will be Enter your name : Lincoln Good morning LINCOLN Note that PULL automatically converts input into uppercase REXX Instruction - UPPER to translate the contents of a single or several variables to uppercase Syntax : UPPER var1 var2 var3 « Example : /*REXX*/ name=µKennedy¶ say µName is µ name upper name say µNow name is µ name exit Output Name is Kennedy Now name is KENNEDY REXX Instruction - EXIT Used to unconditionally leave a program Can optionally pass back a string to the caller Syntax : EXIT {expression} Example named PROG2 /*REXX*/ a=10 exit a*10 /* passes back string 100 to the caller */ When prog2 is called in an exec as x=prog2(),then x will have the value 100 REXX Instruction - IF Used to conditionally execute a single REXX stmt or a group of REXX statements Syntax : If expression then stmt; else stmt; If expression is evaluated TRUE(1) then the THEN part is performed and if FALSE(0) then the ELSE part is performed. A group of REXX statements can be grouped together by using DO«END Nested IF¶s are allowed in REXX. REXX Instructions - NOP NOP stands for No-operation Causes REXX to create No-operation condition Only useful as a target of THEN or ELSE clause Syntax : NOP; REXX Instructions - IF Example /*REXX*/ say ¶Enter AM/PM :' pull ampm if ampm = 'AM' then say 'Good morning!!!' else if ampm = 'PM' then say 'Good evening!!!' else NOP; EXIT Output : Enter AM/PM : AM Good morning!!! When the input is blank or other than AM/PM , the instruction that gets executed is NOP Also note that the ELSE clause is not mandatory When the ELSE clause is removed ,the functionality of the program will still be the same REXX Instructions - DO Used to execute a group of REXX statements under the control of an expression Has several formats The repetitive DO construct DO 5 say µhi there!!!¶ END /* DO X=5 is the same */ The rexx statements within DO..END will be executed five times Contd... REXX Instructions - DO Do with loop counter /*REXX*/ Do I = 1 to 7 by 2 say I End I /* optional to specify the variable */ /* 2 is the step value */ The output will be 1 3 5 7 Contd... REXX Instructions - DO Do..While construct /*REXX*/ I=1 Do while I < 3 say I I=I+1 End The output 1 2 Contd... REXX Instructions - DO Do..Until construct /*REXX*/ I=1 Do until I > 3 say I I= I+ 1 End The output will be 1 2 3 Contd... REXX Instructions - DO The Do..Forever special construct /*REXX*/ Do forever say µinfinite loop¶ end The above exec results into an infinite loop Enough care should be taken to check the exit criteria of the loop, before executing the exec The LEAVE instruction can be used to exit from the loop REXX Instructions - LEAVE Causes REXX to stop executing the current DO-END loop and Syntax : LEAVE {name} Example /*REXX*/ Do forever Say µEnter the code :¶ Pull code If code = µBYE¶ then Leave; end Exit The above exec will prompt the user for a code until the user enters the code µBYE¶. The µname¶ will be used to exit from a particular loop in case of several nested do loops control passes to the next statement after the END of the DO-END pair REXX Instructions - ITERATE Used to restart execution in a DO loop Syntax : ITERATE {name} If name is not specified ,ITERATE will step the innermost active loop If name is specified,that particular loop is stepped Example /*REXX*/ Do I = 1 to 3 by 1 If I = 2 then iterate I; say µI = µ I /* name is not required */ end Output I=1 I=3 REXX Instructions - SELECT Causes REXX to execute one of several different instructions Most used when one of the several paths must be followed Example : /*REXX*/ Say µEnter 1 for salad,2 for pizza :¶ pull choice select when choice = 1 then say µHere is the salad¶ when choice = 2 then say µHere is the pizza¶ otherwise say µYou have opted nothing¶ End When the input is anything other than 1 or 2 then the control is transferred to OTHERWISE clause. REXX Instructions - INTERPRET Used to execute instructions that are built dynamically Allows to build the REXX statements in an exec Syntax : INTERPRET expression Example : /*REXX*/ out='say hi there!!!' Interpret out stmts='do 3; say 'loop'; end' Interpret stmts exit Output will be HI THERE!!! LOOP LOOP LOOP REXX Instructions - NUMERIC Sets controlling limits that govern how REXX evaluates and reports the results of arithmetic operations Syntax : NUMERIC DIGITS {expression} This tells REXX how many significant digits to use when calculating and printing results Syntax : NUMERIC FORM { SCIENTIFIC | ENGINEERING } This tells REXX how arithmetic values that must be expressed in exponential notation will be presented NUMERIC FUZZ {expression} This determines how much two numbers can be different from each other and still be considered equal by REXX REXX Instructions - NUMERIC Example /*REXX*/ numeric digits 4 numeric fuzz 1 a=1000 b=1004 if a = b then say equal else say unequal exit Output EQUAL Since the FUZZ value is 1,the rightmost is not considered in the comparison. In the same example ,note that when B takes value 1005 and numeric digit is 5 ,the output is UNEQUAL ,as REXX rounds off the value of B to 101,while eliminating its rightmost digit REXX Instructions - NUMERIC Numeric form scientific causes REXX to always place one non-zero digit to the left of the decimal point Numeric form engineering makes REXX use powers of ten in exponential notation that are always a multiple of three Example /*REXX*/ numeric digits 5 numeric form scientific a=123.45 * 1e11 say a form() numeric form engineering a=123.45 * 1e11 say a form() exit /* 1.2345E+13 SCIENTIFIC */ /* 12.345E+12 ENGINEERING */ REXX Instructionsto-one or more variables PARSE Tells REXX how to assign data PARSE NUMERIC name returns the current settings of numeric options DIGITS,FUZZ and FORM PARSE PULL makes REXX get the string from the REXX data stack.If the stack is empty,REXX will get the string from the terminal PARSE VALUE parses a string under the control of the template PARSE VALUE expression WITH template PARSE VAR indicates that the string to be parsed is not a literal but a variable PARSE VERSION returns REXX interpreter level and the date released REXX Instructions - PARSE Ex. parse value µNapolean the great¶ with w1 w2 w3 w1 = Napolean w2 = the w3 = great parse value µNapolean the great¶ with w1 9 w2 w1 = µNapolean µ w2 = µthe great¶ parse value 'salt+water=brine' with w1 '+' w2 '=' w3 w1 = salt w2 = water w3 = brine parse version vervar say vervar REXX370 3.48 01 May 1992 REXX Instructions - DROP Used to return one or more REXX variables to their initial or uninitialised state Syntax : DROP name1 name2 name3«.; Same variable can be dropped more than once Examples drop a drop z.5 drop d. /* Unassigns the variable a*/ /* Unassigns the stem variable z.5 */ /* Unassigns all the vars starting with d. */ REXX Instructions - ADDRESS To indicate the destination of non-rexx commands Syntax ADDRESS destination The destination could be any one of these TSO - Routes commands to TSO ISPEXEC - Routes commands to ISPF/PDF ISREDIT - Routes commands to the ISPF Edit macro processor Note : Other destinations exist,but beyond the scope of this training Example : Address tso µlista st¶ /* the destination is set */ µlistds(µtcs.rexx.exec¶) members¶ /* to TSO */ Address ispexec /* Dest. Changed and set */ REXX Instructions - Procedure used to protect the variables in existence when the function or subroutine is called When a RETURN instruction is executed by the called function or subroutine ,all variables saved by the PROCEDURE instruction are restored to the state they were in when saved Syntax : PROCEDURE { EXPOSE name1 {name2}«} name1, name2 are not protected from the subroutine.That is they are exposed to the subroutine REXX Instructions - Procedure Example /*REXX */ lines=2 pages=3 call showlyns say 'The line count is' lines ',the page count is' pages /* 'say' above displays 10 for lines and 3 for pages */ exit showlyns: procedure expose lines lines=10;pages=1 /* sets caller's 'lines' variable */ /* but a local 'pages' variable */ return REXX Instructions - ARG To parse out the arguments passed to a program or internal subroutine and store the arguments in variables Ex : /*REXX*/ arg a,b c = a+ b say µThe sum is µ c exit When invoked as TSO SUM 4 5,the output will be The sum is 9 REXX does not prompt for any missing arguments ARG converts the parameters passed to uppercase REXX Instructions - RETURN used to pass control back to the caller of a subroutine or function.An optional value can also be passed Syntax : RETURN {expression } If invoked as a function ,the value in the return instruction is substituted for the function call If invoked as a subroutine , the value in the RETURN instruction is stored in the REXX special variable RESULT If the RETURN instruction doesn¶t have any expression , then a null string is passed to the caller REXX Instructions - CALL used to invoke an internal or external subroutine and builtin-functions The called routine usually uses the ARG function to extract the parameters passed by the call Example arg x call factorial x say x'! =' result exit factorial: procedure arg n if n=0 then return 1 call factorial n-1 return result * n /* parse 'x' */ /* go get factorial of 'x' */ /* write result out */ /* factorial subroutine */ /* parse 'x' */ /* quit when done */ /* call myself with x minus 1 */ /* build up answer in 'result' */ REXX Instructions - SIGNAL It is an equivalent command for the infamous GOTO command in other languages Syntax : SIGNAL label Example /*REXX*/ say µBefore signal¶ signal bye say µAfter signal¶ exit bye: say µIn signal¶ exit /* displayed */ /* never gets executed */ /* displayed */ Note that the say instruction after signal will never get executed REXX Instruction - PUSH used to place a new element on a REXX data stack Syntax : PUSH {expression} Places the element on the top of the REXX data stack The length of an element can be up to 16,777,215 A null string of length zero is stacked if the expression is omitted stacks strings LIFO sequence REXX Instruction - QUEUE used to place a new element on the bottom of a REXX data stack Syntax : QUEUE { expression } stacks strings in FIFO sequence a null length string is stacked if expression is omitted The PULL instruction is used extract an element from the top of the REXX data stack REXX Functions REXX Functions A function is a sequence of instructions that can receive data, process that data, and return a value. In REXX, there are several kinds of functions: Built-in functions -- These functions are built into the language processor. More about built-in functions appears later in this topic. User-written functions -- These functions are written by an individual user or supplied by an installation and can be internal or external.An internal function is part of the current exec that starts at a label. An external function is a selfcontained program or exec outside of the calling exec REXX Functions - ABS Returns the absolute value of a number The absolute value of a number is the value of the number without the sign being considered The number of digits returned is governed by current NUMERIC DIGITS setting Examples: ABS(¶56.7') returns the number 56.7 numeric digits 2 ABS(' -0.125') returns the number 0.13 REXX Functions - ADDRESS returns the current setting of the destination to which the non-REXX commands in an REXX exec is addressed to Note the the default destination is TSO Example /*REXX*/ say address() address ispexec say address() address isredit say address() exit /* returns ISPEXEC */ /* returns ISREDIT */ /* returns TSO */ REXX Functions - CENTER used to center one string within a certain length area and pad on the left and right of the centered string with an optional padding character Syntax : CENTER(string, length{,pad}) The default padding character is spaces Examples : say center(µuswest¶,10,¶*¶) returns **USWEST** REXX Functions - COMPARE used to compare two strings and return a zero if the strings are the same ,or a non-zero number if they are not non-zero number is the position of the first mismatching character found Syntax : COMPARE(string1,string2{,pad}) If the optional padding character is specified,then the shorter string is padded and compared Examples : COMPARE('123','123') COMPARE('FO?? ','FO','?') COMPARE('abc','ak') COMPARE('ZZ ','ZZ','x') COMPARE('MA ','MA') COMPARE('xy ','xy',' ') returns a 0 (exact match) returns a 5 (1st mismatch after padding) returns a 2 (first mismatching char) returns a 3 (1st mismatch found 3 chars in) returns a 0 (exact match with padding) returns a 0 (exact match with padding) REXX Functions - COPIES used to concatenate or append a string to itself a certain number of times Syntax : COPIES(string,n) Examples COPIES('Hello',4) COPIES('Say what?',0) returns 'HelloHelloHelloHello' returns '' (null string) REXX Functions - DATATYPE used to determine the data type of the string passed Syntax : DATATYPE(string{,type}) If type is omitted,NUM is returned if the string is a valid number and CHAR is returned in all other cases If type is specified,either TRUE(1) or FALSE(0) is returned The valid types are as follows A - Alphanumeric N - Numeric W - Whole number L - Lowercase U - Uppercase M - Mixed case Examples DATATYPE(' 44 ') DATATYPE('*1**') DATATYPE('Wally','M') DATATYPE('75.54','W') returns NUM (numeric) returns CHAR (caharcter string) returns a 1 (mixed case) returns a 0 (not a whole number) REXX Functions - DATE returns the current date An optional character can be passed to obtain date in specific formats Syntax : DATE({option}) Some of the chars that can be passed are U returns date in USA format, 'mm/dd/yy¶ J returns a Julian date in the form 'yyddd¶ W returns the day of the week (e.g. 'Tuesday', 'Sunday', etc.) Examples say date() say date('U') say date('J') say date('W') /* returns 17 Dec 1999 */ /* returns 12/17/99 */ /* returns 99351 */ /* returns Friday */ REXX Functions - DELSTR used to delete or remove one string from within another string Syntax : DELSTR(string,n{,length}) 'string' is the string from which a portion is to be deleted starting with character number 'n', where 'n' is a positive integer The length of the portion to be deleted is given by the optional length parameter When µn¶ is greater than the length of the string no action is performed Examples DELSTR('abcde',3,2) deletes 'cd', leaving 'abe' DELSTR('zyxw',3) leaves 'zy', deleting 'xw' DELSTR('12345',6) no change, since 6 is greater than string length REXX Functions - DIGITS returns the current setting of the NUMERIC DIGITS option Takes no parameters Example DIGITS() /* returns a 9 if REXX default hasn't been changed */ REXX Functions - FORM used to extract the current setting of the NUMERIC FORM option returns SCIENTIFIC or ENGINEERING Example say from() numeric form engineering say form() /* returns engineering */ /* returns default scientific */ REXX Functions - FORMAT used to round off and format a number using REXX rules optional values can be passed which decides the number of digits before and after the decimal point Syntax : FORMAT(number{,{before}}{,{after}}) If before and after are not specified ,the number of digits that are needed to present the rounded number are used Examples FORMAT('78',3) FORMAT(' - 8.7',,2) FORMAT('5.46',3,0) returns rounded number ' 78' returns rounded number '-8.70' returns rounded number ' 5' REXX Functions - FUZZ used to extract the current setting of the NUMERIC FUZZ option The value of FUZZ cannot be greater than the DIGITS setting Example /*REXX*/ say fuzz() numeric fuzz 2 say fuzz() /* returns 2 */ /* returns the default zero */ REXX Functions - INDEX used to find the position of one character string within another character string Syntax : INDEX(string,substring{,start}) 'start' is an optional starting character position for the search within µstring¶ Examples INDEX('hello','ll') returns a 3 INDEX('say what','w ') returns a 0 INDEX('zyxwvu','vu',6) returns a 0 INDEX('zyxwvu','vu',2) returns a 5 REXX Functions - LEFT used to extract the leftmost characters of the string Syntax : LENGTH(string,length{,pad}) If string is shorter than length,the string returned is padded with µpad¶ char in the function call if available or with the default pad character blank. Examples : LEFT('Wallawalla',4) returns 'Wall' LEFT('Republicans',20,'-') returns 'Republicans---------' LEFT('Motley Crue ',8) returns 'Motley C' REXX Functions - LENGTH used to return the length of the string passed to the function Syntax : LENGTH(string) Examples : LENGTH('LIFO') returns 4 LENGTH('Rubber baby buggy bumpers') returns 25 LENGTH('') returns 0 (null string) REXX Functions - MAX returns the maximum numeric value from a list of numeric values Syntax : MAX(number{,number}...) The size of the numeric value returned is limited to the current setting of NUMERIC DIGITS. Up to 20 numbers may be specified as arguments to MAX. Calls to MAX can be nested if more are needed Examples : MAX(21,22,81,67) returns 81 MAX(27.32,0.45,102.3) returns 102.3 The MIN function is similar to MAX except that it returns the minimum value REXX Functions - POS returns the position, relative to 1, of one string within another. Syntax : POS(substring,string{,startloc}) A zero is returned if substring is not found within µstring¶ Examples POS('M','ABCDEFGHIJKLMNOPQRSTUVWXYZ') returns 13 POS('Smith','Merrill, Lynch, Pierce, Fenner, and Smith') returns 37 POS('hart','MVS is breaking my heart...',4) returns 0 (not found) REXX Functions - QUEUED returns the no of elements that remain on the REXX data stack No arguments If queued() returns zero,that indicates the REXX data stack is empty and the next PULL instruction will obtain input from the TSO terminal Example /*REXX*/ newstack push a queue b say queued() delstack exit /* returns 2 */ REXX Functions - RANDOM generates a "pseudo-random" number that will lie somewhere between a supplied (or defaulted) upper and lower bound."pseudo-random" means that the number is not truly random, but it behaves as if it was. Syntax : RANDOM({min}{,{max}{,seed}}) Difference between min & max <= 100000 the default value for min is 0 and max is 999 If only one number is supplied,then a number will be generated in the range of zero to that number µseed¶ is an optional whole number and when specified gives repeatable results each time the exec is invoked Examples : RANDOM() returns a random number 'n', in range 0 =< n =< 999 RANDOM(32,35) returns a random number 'n', in range 32 =< n =< 35 RANDOM(,,251) returns a random number 'n', in range 0 =< n =< 999, and returns the same one every time called this way REXX Functions - REVERSE This function reverses the order of all characters in a string Syntax : REVERSE( string) Example say reverse(µTCSUSWEST¶) returns µTSEWSUSCT¶ REXX Functions - SIGN used to determine the sign of a number Syntax : SIGN(number) returns -1 if the number is negative returns 0, if the nuber is zero returns +1,if the number is positive the number is rounded to meet the current setting for NUMERIC DIGITS before the test. Examples : SIGN('-22.811') returns -1 SIGN(0.0) returns 0 REXX Functions - STRIP used to remove the leading and/or trailing characters from a character string Syntax : STRIP(string{,{option}{,char}}) The default char for µchar¶ is blank The µoption¶ can take either L or T or B and the default option is B Examples : STRIP(' February 11, 1989 ') returns 'February 11, 1989' STRIP('7642.7600',T,0) returns '7642.76' STRIP('$$$$52.4',Leading,$) returns '52.4' REXX Function - SUBSTR used to extract a portion of a string Syntax : SUBSTR(string,n{,{length}{,pad}}) µlength¶ is the length of extracted substring if µlength¶ is omitted,the remainder of the string from char number µn¶ is extracted The extract string is padded on the right with µpad¶ char, if there are not enough characters in the extracted substring to reach µlength¶ Examples : SUBSTR('Hi there',4) returns 'there' SUBSTR('MVS',1,5) returns 'MVS ' SUBSTR('December 7, 1941',6,15,'-') + 'ber 7, 1941----' REXX Function - SYMBOL used to determine whether a symbol is valid REXX symbol Syntax : SYMBOL(name) Returns ³BAD´ if the µname¶ is not a valid REXX symbol If µname¶ is name of the variable with a value assigned to it,¶VAR¶ is returned In other cases, µLIT¶ is returned Examples : j='TSO/E Version 2.1' Symbol('J') Drop j Symbol('J') Symbol('.variable') /* assign value to variable J */ /* returns VAR since assigned */ /* returns LIT after Drop */ /* returns BAD since 1st character is a '.' */ REXX Function - TIME returns the current time of day in a variety of different formats and can also be used to perform elapsed time calculations Syntax : TIME({option}) µR¶ - elapsed time clock to be set to zero µE¶ - return elapsed time since previous TIME(µR¶) µH¶ - No. of hours since midnight µL¶ - hh:mm:ss:uuuuuu µS¶ - No. of seconds since midnight Examples : TIME() TIME('L') TIME('M') TIME('H') TIME('R') TIME('E') returns returns returns returns returns returns 09:18:04 11:00:32.672567 840 /* at 2 in the afternoon */ 12 /* at noon */ 0 /* The first call */ 18.278190 /* about 18 seconds later */ REXX Function - TRUNC used to truncate a number to an integer portion and a decimal fraction portion Syntax : TRUNC(number{,n}) 'n' is the number of decimal places to retain to the right of the decimal point.If µn¶ is omitted,no decimal places are returned Examples: TRUNC(4096.6904) /* returns 4096, dropping decimal fraction */ TRUNC(0.3,3) /* returns 0.300 */ REXX Function - USERID returns the current TSO user id Format : USERID() Example say userid() /* returns the current user id */ REXX Function - WORD used to extract a specific word from within a string of words Syntax : WORD(string,n) The words in the string must be separated by blanks µn¶ indicates that the nth word in the string is to be extracted Examples : WORD(¶Arise Awake and Stop not',4) /* returns ¶Stop' */ test = '1 2 3 4 5 6 7 8 9' WORD(test,1) /* returns '1' */ WORD('Carolina moon, what are you doing over Gismo Beach?',10) /* returns null string */ REXX Function - WORDS used to determine the number of words contained within a string of words Syntax : WORDS(string) Examples : WORDS(µArise, Awake and Stop not till the goal is reached¶) /* returns 10 */ WORDS('1234567890abcdefghikjlmnopqrstuvwxyz $@#!') /* returns 2 */ REXX TSO/E External Functions REXX TSO/E external functions In addition to the built-in functions,TSO/E provides external functions that you can use to do some specific tasks. Functions we will be discussing and frequently used are : LISTDSI OUTTRAP SYSDSN SYSVAR LISTDSI - External Function Returns in variables the dataset attributes of a specified dataset The function call is replaced by a function code that indicates whether or not the call was successful.A non-zero code indicates that the call was not successful Example /*REXX*/ X=LISTDSI(³¶TCS.PDS.COBOL¶´) /* x = function code */ IF X=0 THEN DO SAY µSYSDSORG µ SYSDSORG SAY µSYSLRECL µ SYSLRECL END ELSE SAY µCALL UNSUCCESSFUL¶ EXIT LISTDSI - External function The following points are note-worthy Note two sets of quotes in the call to LISTDSI ³ - to indicate the parm is literal to REXX µ - to indicate the dsname is fully qualified The function code should always be checked after the call The output of the above REXX could be SYSDSORG PO SYSLRECL 80 Totally there are - PO- Partitioned Dataset - Record length 33 variables that are set as a result of the call to LISTDSI external function OUTTRAP - External Function Traps TSO/E command output into a stem variable The function call returns the name of the variable specified Trapping is capturing the lines of data which otherwise would have been displayed at the terminal Example /*REXX*/ x=outtrap("a.") /* turns trap on. x=a. */ "listds 'rhkrish.rexx.exec' members" x=outtrap("off") /* turns trap off. x=off */ say 'No of lines trapped ' a.0 EXIT OUTTRAP - External function Contd.. The output of the exec could be this No of lines trapped 57 Note that the no of lines trapped is stored in A.0 All the trapped lines from A.1 to A.n can be used The outtrap function can be used to trap only a certain no of lines. OUTTRAP(³A.´,10) Only 10 lines trapped. SYSDSN - External Function Returns OK if the specified dataset exists; Otherwise returns appropriate error messages Example call available = SYSDSN(³¶tcs.rexx.exec¶´) /* available could be set to "OK" */ The other possible error messages are as follows MEMBER SPECIFIED, BUT DATASET IS NOT PARTITIONED MEMBER NOT FOUND DATASET NOT FOUND ERROR PROCESSING REQUESTED DATASET PROTECTED DATASET VOLUME NOT ON SYSTEM UNAVAILABLE DATASET INVALID DATASET NAME, data-set-name MISSING DATASET NAME SYSVAR - External Function Uses specific argument values to return information about the user ,terminal ,language ,system ,exec and console session Example say sysvar(sysuid) displays the user id. The arguments corresponding to user information are SYSPREF - Prefix as defined in user profile SYSPROC - Logon procedure of current session SYSUID - User id of current session SYSVAR - External Function Terminal information SYSLTERM - No of lines available on screen SYSWTERM - Width of screen Exec information SYSENV - Whether exec is running in fore or background SYSISPF - whether ISPF is active or not System information SYSRACF - Whether RACF is available SYSNODE - Network node name SYSTSOE - Level to TSO/E installed Note : Only some of the variables are covered REXX TSO/E Commands REXX TSO/E Commands Commands provided with the TSO/E implementation of the language. These commands do REXX-related tasks in an exec, such as: - Control I/O processing of information to and from data sets(EXECIO) - Perform data stack services (MAKEBUF, DROPBUF, QBUF, QELEM,NEWSTACK, DELSTACK, QSTACK) - Change characteristics that control the execution of an exec - Check for the existence of a host command environment (SUBCOM). REXX Command - NEWSTACK used to create a new data stack in the REXX environment When this command is executed, the current data stack is saved and a new stack is created and made the current stack When the stack is empty,the subsequent pull instruction obtains input from the TSO terminal When the stack has data elements,the pull instruction gets the input from the top of the stack Example "NEWSTACK" Push tcs Push uswest pull data say µfrom the stack µ data pull data say µfrom the stack µ data pull data "DELSTACK" /* creates new stack */ /* puts µtcs¶ in top of stack */ /* puts µuswest¶ over µtcs¶ */ /* pulls data from the top of stack */ /* displays µuswest¶ */ /* pulls data from top of stack */ /* displays µtcs¶ */ /* obtains input from tso terminal */ /* delete stack */ REXX Command - DELSTACK used to delete the data stack that was created last in the REXX environment When this command is executed the most recently created stack is deleted and all elements on it are purged If there is any previous data stack,that is made available Example : ³NEWSTACK´ push a queue b ³NEWSTACK´ push c say queued() ³DELSTACK´ say queued() ³DELSTACK´ /* new stack is created */ /* µa¶ is stored on top */ /* µb¶ is stored at the bottom */ /* new stack is created */ /* µc¶ is stored on top */ /* displays 1 */ /* deletes the current stack */ /* displays 2 */ /* deletes the stack */ REXX Command - MAKEBUF used to add a buffer to the data stack in REXX environment returns the relative number of the buffer on the stack in the special variable RC It¶s a temporary extension to the data stack and used when need arises to pass some of the elements to a subroutine Example : ³NEWSTACK´ Push elem1 "MAKEBUF" saverc = RC Push elem1 Push saverc Call subrtn1 "DROPBUF" /* creates new stack */ /* add an element */ /* add a buffer to stack */ /* save number of buffer */ /* add contents of variable elem1 to data stack */ /* pass buffer number too */ /* call subroutine to handle elements */ /* delete buffer,but not stack before makebuf */ REXX Command - DROPBUF used to delete data stack buffer from the data stack in the REXX environment Syntax : DROPBUF {n} 'n' is optional and is the number of the data stack buffer that you wish to remove. That data stack buffer and all those higher on the stack are removed from the stack when DROPBUF is executed If n is omitted ,the recently created buffer is dropped Example : ³DROPBUF ´ /* deletes the recently created buffer */ ³DROPBUF 0´ /* deletes buffer and all elements of stack */ REXX Command - QBUF used to determine the number of data stack buffers that have been explicitly created by the MAKEBUF REXX command number of buffers will be returned through special variable RC If no buffers have been created via makebuf , a 0(zero) is returned is RC Example : "MAKEBUF" "MAKEBUF" "DROPBUF" "MAKEBUF" "QBUF" /* creates buffer 1 */ /* creates buffer 2 */ /* deletes buffer 2 */ /* creates buffer 2 again */ /* returns a 2 */ REXX Command - QELEM The QELEM REXX command is used to determine the number of data stack elements that are contained in the buffer that was most recently created by the MAKEBUF REXX command If no buffers have been created via makebuf , a 0 is returned in RC Example : "MAKEBUF" /* creates a buffer */ Push µTCS¶ Push µTATA¶ Push µCONSULTANCY¶ Push µSERVICES¶ "QELEM" /* returns a 4 in RC */ "DROPBUF" /* deletes buffer and elements in it */ "QELEM" /* returns a 0 in RC */ REXX Command - QSTACK used to determine the total number of data stacks currently is existence The no of data stacks includes the original REXX data stack, as well as those created via the NEWSTACK command If no additional stacks have been created via NEWSTACK , a 1 is returned is RC Example "QSTACK" "NEWSTACK" "NEWSTACK" "QSTACK" /* returns a 1 in RC */ /* creates a new data stack*/ /* creates another new data stack*/ /* returns a 3 in RC */ REXX Command - EXECIO used to perform read and write operations against a sequential dataset or a pds member The data is either read from the data set and placed on the data stack or into a list of variables, or written from the data stack or a list of variables into the data set Syntax for read operations : EXECIO {lines ¦ *} DISKR ddname {linenum} { ( {{FINIS}} ¦ { STEM var {FINIS} } {)} } Syntax for write operations : EXECIO {lines ¦ *} DISKW ddname { ( {STEM var} {FINIS} {)} } REXX Command - EXECIO Example /* read all lines in data set and display them */ Address TSO /* pass unknowns to TSO */ Parse Arg dsn /* get data set name */ "ALLOC DD(TEMP) DA("dsn") SHR" /* allocate file */ end_of_data = 0 /* negate end of file */ Do While end_of_data = 0 'EXECIO 1 DISKR TEMP ( FINIS' /* read a record onto stack */ If RC = 2 then end_of_data = 1 Else Nop /* set end-of-file? */ Pull line /* get line off stack */ Say line /* display line */ End Note : This example uses the original REXX data stack. REXX Command - EXECIO /* Example 2 - copy a file into another */ Address TSO "ALLOC F(IN) DA('SYS1.PROCBLIB(ASMHCL)') SHR" "ALLOC F(OUT) DA(µTATA001.DELETE.ME¶) SHR" 'EXECIO * DISKR IN (STEM DATA. FINIS' /* copy file into stem*/ Queue /* add null line to stack */ 'EXECIO * DISKW OUT (STEM DATA. FINIS' /* copy using stem*/ "FREE F(IN,OUT)" SAY µNo of lines in input : µ data.0 EXIT Note : This example uses stem variable data to read the contents of input file.The Number of lines read will be stored in data.0. Executing REXX in Batch Executing REXX in batch Need arises when the REXX exec takes longer time to complete the execution.So time-consuming and low priority execs can be run in background Main advantage - Batch mode does not interfere with persons use of the terminal Only those execs which do not require any sort of terminal interaction can be run in batch mode. A JCL as shown in the next slide can be used to invoke a REXX exec. Executing REXX in Batch - JCL //TSOBATCH EXEC PGM=IKJEFT01,DYNAMBR=30,REGION=4096K //SYSEXEC DD DSN=TCS.REXX.EXEC,DISP=SHR //SYSTSPRT DD SYSOUT=A //SYSTSIN % SETUP /* // DD * The following points are to be noted : IKJEFT01 - TSO command processor program SYSEXEC - System DD card to which REXX libraries are concatenated SYSTSPRT - Destination of the REXX output,as well the TSO command processor Contd.«. Executing REXX in Batch - JCL Contd.«. SYSTSIN - Instream card wherein TSO commands or invocation of REXX execs can be issued The dataset TCS.REXX.EXEC is a PDS and has a member of the name SETUP. The Instream data can be used to invoke an REXX exec either implicitly or explicitly as indicated below %SETUP >>>> Implicit EXEC µTCS.REXX.EXEC(SETUP)¶ EXEC >>>> Explicit Any parameters to the exec can be passed as below %SETUP µparm1¶ µparm2¶ REXX Exec - Example After the execution of the exec,If there are any elements in the REXX data stack,those elements will be treated as TSO commands and will get executed Example - To purge a user Id /*REXX*/ arg uname queue ³c u =³uname queue ³end´ ³OPER´ exit Invoke the above exec as ===> TSO CUSER TATA001 A similar exec can be written to display all the users REXX EDIT MACRO Edit Macros - Introduction Primary commands that users write.An example is the oftused CUT R or the PASTE K command Using Edit macros save time and keystrokes - Deleting all the lines with first character as µ*¶ Edit macro is a series of edit commands placed in a dataset or a member of partitioned dataset - To find lines with char µa¶ in Col. 31 and char µb¶ in Col. 35 Used to perform often-repeated tasks - Block commenting lines in a COBOL program To run an Edit macro,Type its name and any operands on the command line and press enter Edit Macros - Basics Assignment statement Consists of two parts ,values and key-phrases,which are separated by an equal sign Value segment is the data in the macro and key-phrase segment represents the data in the editor Can be used to pass data from the edit macro to the editor or to transfer data from the editor to the edit macro Data is always transferred from the right hand side of the equal sign in an assignment statement to the left hand side Example : ³ISREDIT (data) = LINE .ZCSR´ The data in the current line is stored in the variable data.so the value segment is data,key-phrase segment is LINE and hence the transfer of data is from the editor to the edit macro. EDIT Macros - Parameters Parameters can be passed to the EDIT macro using the statement µISREDIT MACRO(parm)¶ Suppose the macro name copymem and If it is invoked as Command ====> COPYMEM MYFIRST then MYFIRST is assigned to the variable µparm¶. More than one variable can be passed If there are more variable names than parameters, the unused variables are set to nulls. The macro statement should be the first executable statement in a macro EDIT Macros - Labels A Label is an alphabetic string character used to name lines A label must begin with a period (.) and be followed by no more than 8 alphabetic characters, the first of which cannot be Z. No special characters or numeric characters are allowed. The editor-assigned labels are: .ZCSR The data line on which the cursor is currently positioned .ZFIRST The first data line Can be abbreviated .ZF .ZLAST The last data line. Can be abbreviated .ZL .ZFRANGE The first line in a range specified by you. .ZLRANGE The last line in a range specified by you. EDIT Macro - Assignment stmts. MEMBER Retrieves the name of the library member being edited If a sequential dataset is being edited ,the variable is set to blanks µISREDIT (memname) = MEMBER¶ DATASET Used to get the current dataset name µISREDIT (dsnname) = DATASET¶ LOCATE Used to position the cursor in a particular line using label or the line number µISREDIT LOCATE .ZCSR¶ EDIT MACRO - Ex : Showonly /*REXX*/ "ISREDIT MACRO (STRING)" "ISREDIT X ALL" "ISREDIT F ALL " STRING EXIT /* STRING IS THE PARAMETER */ /* EXCLUDE ALL LINES */ /* FIND ONLY PARM PASSED */ This macro is very simple one and uses EXCLUDE and FIND macro commands It displays only the lines with the string passed to the macro EDIT Macro - Assignment stmts. CURSOR used to position the cursor in a particular row and column µISREDIT (row,col) = CURSOR¶ µISREDIT CURSOR = (row,col)¶ LABEL sets or retrieves the values for the label on the specified line and places the values in variables µISREDIT (var1) = LABEL .ZCSR¶ µISREDIT LABEL .ZCSR = (.here)¶ LINENUM retrieves the current relative line number of a specified label µISREDIT (lnum) = LINENUM .ZL¶ EDIT Macro - Assignment stmts. LINE Sets or retrieves the data from the data line specified by the line pointer µISREDIT (lndata) = LINE .ZCSR¶ µISREDIT LINE .ZCSR = (datavar)¶ LINE_AFTER Adds a line after a specified line in the current dataset ISREDIT LINE_AFTER lptr = <DATALINE> data <INFOLINE> <MSGLINE > <NOTELINE> µISREDIT LINE_AFTER .ZCSR = DATALINE (datavar)¶ LINE_BEFORE Similar to the LINE_AFTER stmt except that it adds a line before the specified the line EDIT Macro - Assignment stmts. RANGE_CMD Identifies the name of a line command entered from the keyboard µISREDIT (varname) = RANGE_CMD¶ NUMBER Sets number mode, which controls the numbering of lines in the current data. µISREDIT NUMBER ON STD COBOL¶ µISREDIT NUMBER ON STD DISPLAY¶ EDIT Macro - Ex : VSAVE /*REXX*/ /* This macro is used to save a member of a PDS when in view mode */ 'isredit macro' /* No arguments */ address isredit /* Changing the host environment */ "(mem) = MEMBER" /* storing member name in mem */ "(dsn) = DATASET" /* storing dsname is dsn */ If mem = '' then do /* if mem is spaces,its PS */ say 'designed for PDS member' exit /* exit from program */ end "isredit save" /* trying to save the source */ if rc = 0 then do /* Not in view mode */ say 'Not in view mode.use SAVE' exit /* Exit from the program */ end Contd. EDIT Macro - Ex : VSAVE "isredit repl .zf .zl " mem /* Issuing replace command */ if rc = 0 then /* check for success */ say 'member saved.Exit from view mode' else say 'member not saved.Return code ' RC exit The macro can be used to save a member of a PDS,when it is opened in view mode. It checks whether the dataset being edited is a PDS It also checks whether the EDIT is in VIEW mode by trying to save the dataset After these checks,the REPL command is issued. Note : CREATE command can be used to create a new member with the same data EDIT Macro Command PROCESS allows the macro to control when line commands or data changes typed at the keyboard are processed ISREDIT PROCESS <DEST> <RANGE cmd1 <cmd2>> µDEST¶ specifies that the macro can capture an A or B line command .The .ZDEST label is set to the line preceding the insertion point.If A or B is not not entered ZDEST is set to last line RANGE specified the line commands µcmd1¶ and µcmd2¶ which the user can enter The .ZFRANGE label is set to the first line identified by the line command that you have entered, and .ZLRANGE is set to the last line. EDIT Macro - Ex : COMMENT /*REXX*/ /*used to comment eztrieve source code in edit/view mode */ address isredit /* Changes environment */ 'MACRO NOPROCESS' /* all line cmds -process later */ 'PROCESS RANGE N' /* process line cmd N now */ if rc ¬= 0 then do /* error if no ln cmd N entered */ say 'enter the n line command' exit end '(lcmd) = RANGE_CMD' /* stores the lncmd entered */ '(first) = LINENUM .zfrange' /* stores the first range of N */ '(last) = LINENUM .zlrange' /* stores the last range of N */ if first ¬= last then do /* adds note to mark begin& end */ temp = '*** comment changes ends ***' 'LINE_AFTER 'last' = NOTELINE (temp)' temp = '*** comment changes begins ***' 'LINE_BEFORE 'first' = NOTELINE (temp)' end EDIT Macro - Ex : COMMENT Do I = first to last 'SHIFT ) ' I 'LINE ¶I' = LINE + *' End Exit /* first range to last range */ /* shifts chrs to right 2 cols */ /* overlays first char with '*' */ the line command µN¶ must be entered prior to invoking the macro Line command - N , NN-NN , Nn Note the use of NOTELINE SHIFT command shifts chars to right To remove the comments,use the built-in µ((µ left shift line command EDIT Macros - Ex : CPBK /*REXX*/ /* used to zoom a copybook in a cobol program */ /* TEST COPY USWNOTE1. */ ADDRESS ISREDIT 'MACRO' '(lnum) = LINENUM' .ZCSR '(lndata) = LINE' lnum lndata = strip(lndata) dspos = pos('COPY',lndata) if dspos = 0 then SIGNAL error_msg lastpos = pos('.',substr(lndata,dspos+5)) member = substr(lndata,dspos+5,lastpos-1) member = strip(member) dsname = 'app1.common.prod.copylib('||member||')' address ispexec "browse dataset('"dsname"')" ; exit EDIT Macros - Ex : CPBK error_msg: say 'Place the cursor over the COPY verb' exit used to browse a copybook mentioned in a COPY verb of a COBOL program Note the use of SIGNAL instruction The macro command can be typed at the command prompt and cursor can be moved to the COPY verb This macro can also be assigned to a function key using KEYS command and may be invoked by pressing the particular key when the cursor is over the COPY verb FILE TAILORING FT - Skeletons Skeletons are members of a PDS that have variables and fixed text.They may be part of a JCL.(Ex JOB stmt) The skeleton files can contain variable-length records, with a maximum record length of 255. Skeletons can be included in a dataset to build a complete JCL during the run time Skeleton libraries are to be allocated to the application library ddname ISPSLIB The allocation should be done before invoking ISPF Allocation can be done temporarily using ISPF service LIBDEF LIBDEF ISPSLIB DATASET ID(µTATA.PDS.SKELS¶) File Tailoring - FTOPEN Allows skeleton files to be accessed from the skeleton library specified by ddname ISPSLIB Output from the file tailoring process will be placed in a temporary file.The name of the temporary file will be stored in the profile variable ZTEMPF If the output is to be saved in a PS or PDS , the particular library has to allocated to the ddname ISPFILE Call invocation format ISPEXEC FTOPEN [TEMP] TEMP specifies whether the output is to be placed in temporary file or not If TEMP is not specified,then the ddname ISPFILE should have been allocated prior to the invocation of FTOPEN File Tailoring - FTINCL Specifies the skeleton that is to be used to produce the file tailoring output Command invocation format ISPEXEC FTINCL skel-name [NOFT] NOFT specifies that no file tailoring is to be performed on the skeleton.So the entire skeleton will be copied to the output file exactly as is with no variable substitution or interpretation of control records NOFT can be used when there are no variables in the skeleton to be included File Tailoring - FTCLOSE used to terminate the file tailoring process and to indicate the final disposition of file tailoring output Command invocation format ISPEXEC FTCLOSE [NAME(member-name)] [LIBRARY(library)] [NOREPL] NOREPL specifies that FTCLOSE is not to overlay an existing member in the output library NAME specifies the name of the member in the output library that is to contain the file tailoring output LIBRARY specifies the name of a DD statement or lib-type on the LIBDEF service request that defines the output library in which the member-name exists. If specified, a generic (non-ISPF) DD name must be used. If this parameter is omitted, the default is ISPFILE. File Tailoring - Example Assume skeleton library as TATA.UTIL.SKELS Skeleton member JOBSTMT //&JOBNAME JOB (BILL01E0),¶TATA',NOTIFY=&&SYSUID, // MSGCLASS=T,MSGLEVEL=(1,1) Skeleton member SYNCSORT //STEP01 EXEC PGM=SYNCSORT,REGION=400K //SORTIN DD DISP=SHR,DSN=&OLDSRC //SORTOUT DD DISP=SHR,DSN=&NEWSRC //SYSPRINT DD SYSOUT=* //SYSIN DD * SORT FIELDS=(1,10,CH,A) /* These are the two skeletons we will be using in the REXX exec to build the sort jcl File Tailoring - Example /*REXX*/ "ispexec libdef ispslib dataset id(¶tata.util.skels')" say 'enter the jobname :' pull jobname say 'enter old source dsn :' pull oldsrc say 'enter new source dsn :' pull newsrc "ispexec ftopen temp" "ispexec ftincl jobstmt " "ispexec ftincl syncsort " "ispexec ftclose " "ispexec vget (ztempf)" "ispexec edit dataset('"ztempf"')" exit File Tailoring - Example If you respond to the prompts for jobname,old dsname and new dsname with jobsort,tata.old.file and tata.new.file respectively,the tailored output will look like //JOBSORT JOB (BILL01E0),¶TATA',NOTIFY=&SYSUID, // MSGCLASS=T,MSGLEVEL=(1,1) //STEP01 EXEC PGM=SYNCSORT,REGION=400K //SORTIN DD DISP=SHR,DSN=TATA.OLD.FILE //SORTOUT DD DISP=SHR,DSN=TATA.NEW.FILE //SYSPRINT DD SYSOUT=* //SYSIN DD * SORT FIELDS=(1,10,CH,A) /* Note that all three variables have been substituted with appropriate values Note the single ampersand in the NOTIFY parameter ISPF Panels A Simple panel definition )ATTR DEFAULT(%+_) % TYPE(TEXT) INTENS(HIGH) + TYPE(TEXT) INTENS(LOW) _ TYPE(INPUT) INTENS(HIGH) CAPS(ON) JUST(LEFT) )BODY + A Sample panel - REXX Training + ------------------------------------+ + %Enter your name please ==>_urname + + + %Name cannot exceed more than 15 chars + + + +Press ENTER to continue,PF3 to exit + + + + )INIT )PROC VER (&URNAME,NB,ALPHAB) )END REXX Exec - Panel Ex. /*REXX*/ "ispexec libdef ispplib dataset id('rhkrish.test.panels')" "ispexec display panel(expan)" if RC ¬= 0 then do say 'command cancelled' exit end else say 'Your name is ' urname exit A simple REXX Exec that displays a panel that prompts for the user name After the panel is submitted, the name entered is displayed After the panel is displayed and inputs are entered,if enter is pressed RC is zero and if PF3 pressed, RC will be 8 REXX - Panel Ex. Output A Sample panel - REXX Training ------------------------------------Enter your name please ==> abcdefghijklmno Name cannot exceed more than 15 chars Press ENTER to continue,PF3 to exit Advanced panels Point and Shoot Fields Action Bar Choice ISPF TABLES ISPF Tables ISPF tables are analogous to arrays A table can exist with or without a key An ISPF table is stored in a PDS dataset Application library - ISPTLIB The table output library must be allocated to a ddname of ISPTABL There are over 20 ISPF services that are relevant to tables ISPF Tables - TBCREATE creates a new table in virtual storage and opens it for processing allows specification of the variable names that correspond to columns in the table one or more variables can be defined as keys to a table Command invocation format ISPEXEC TBCREATE table-name [KEYS(key-name-list)] [NAMES(name-list)] [WRITE|NOWRITE] table-name can be 1 to 8 alphanumeric characters in length and must begin with an alphabet name-list are the list of variables that forms the columns of the table ISPF Tables - TBCREATE WRITE is the default option and indicates that the table is permanent and is to be saved either by TBSAVE or TBCLOSE NOWRITE specifies that the table is for temporary use only and it is to be deleted by either TBEND or TBCLOSE Example ³TBCREATE FSTATUS KEYS(FCODE) NAMES(MESSAGE) WRITE ³ ³TBCREATE TELBOOK KEYS(TELNO) NAMES(ADR1 ADR2)´ ³TBCREATE ADDRESS NAMES(NAME ADDR1 ADDR2 PIN) ³ ISPF Tables - TBOPEN reads a permanent table from the table input file into virtual storage, and opens it for processing Command invocation format ISPEXEC TBOPEN table-name [WRITE|NOWRITE] Example ³ISPEXEC TBOPEN FSTATUS WRITE´ and ³ISPEXEC TBOPEN FSTATUS ´ are the same as WRITE is the default option ISPF Tables - TBADD Adds a new row of variables to the table For tables without keys,the row is added after the current row For tables with keys ,the table is searched to ensure that the new row has a unique key Command invocation format ISPEXEC TBADD table-name [SAVE(name-list)] [ORDER] ORDER ensures no duplicate key condition Example ³ISPEXEC TBADD TELBOOK ORDER´ ISPF Tables - TBSCAN Searches a table for a row with values that match an argument list Command invocation format ³ISPEXEC TBSCAN table-name [ARGLIST(name-list)]´ Example ³ISPEXEC TBSCAN FSTATUS ARGLIST(FCODE)´ Searches the table FSTATUS using the argument FCODE and fetches the error message associated with it.If the row exists in the table, the error message will be stored in the variable MESSAGE as in the TBCREATE service ISPF Tables - TBSKIP Moves the current row pointer of a table forward by +1 All variables in the row,including keys and extension variables ,If any ,are stored into the corresponding variables as defined in the TBCREATE statement Command invocation format ³ISPEXEC TBSKIP table-name´ TBSKIP has many other parameters which are beyond the scope of this training ISPF Tables - TBSAVE writes the specified table from virtual storage to the table output library The table output library must be allocated to the ddname ISPTABL The table must be open in WRITE mode TBSAVE does not delete the virtual storage of the table Command invocation format ISPEXEC TBSAVE table-name NAME(alt-name) µalt-name¶ - the table will stored in the output library with the alternate name ISPF Tables - TBEND deletes the virtual storage copy of the specified table,making it unavailable for further processing The permanent copy is not changed Command invocation format ³ISPEXEC TBEND table-name´ ISPF Tables - TBCLOSE Terminates processing of a specified table and deletes the virtual storage copy If the table was opened in write mode ,TBCLOSE copies the table from virtual storage to the table output library If the table was opened in NOWRITE mode ,TBCLOSE simply deletes the virtual storage copy Command invocation format ISPEXEC TBCLOSE table-name Example ³ISPEXEC TBCLOSE FSTATUS´ ISPF Tables - Example - 1 Creating and storing data in a table /*REXX*/ address ispexec "libdef isptabl dataset id('rhkrish.test.tables')" "tbcreate rexxerr keys(ecode) names(etext) write" do i = 1 to 49 ecode=i etext= errortext(i) "tbadd rexxerr order" end "tbclose rexxerr" exit ISPF Tables - Example - 2 Searching the table for a particular value /*REXX*/ address ispexec "libdef isptabl dataset id('rhkrish.test.tables')" "tbopen rexxerr nowrite" say 'enter the error code (1-49) :' pull ecode "tbscan rexxerr arglist(ecode)" if rc = 0 then say 'The error mesg is ' etext else say 'row does not exist' "tbclose rexxerr" say 'Error mesg using function-' errortext(ecode) exit ISPF Tables - Example 3 Displaying all the rows of a table /*REXX*/ address ispexec "libdef isptabl dataset id('rhkrish.test.tables')" "tbopen rexxerr nowrite" "tbskip rexxerr" if RC ¬= 0 then do say 'tbskip error RC - ' RC exit end say "ECODE ETEXT" do while RC = 0 say ecode etext "tbskip rexxerr" end "tbclose rexxerr" exit List of References REXX in the TSO Environment - Gabriel F.Gargiulo Book manager in MVS Shelf Name Description TSO_V2R5 ISPF_V42 TSO/E V2R5 Bookshelf ISPF 4.2 for MVS Library Book Name Book Title IKJ2C307 ISPEEM01 ISPSRV01 TSO/E V2R5 REXX/MVS User's Guide Edit and Edit Macros Services Guide