Posted: Thu May 08, 2014 7:18 am Post subject: How to execute another REXX program when exiting the current
I have a REXX program that displays DB2 Table information. I execute it by executing an ISPF User Command named TT that executes the REXX program named PGMDISP passing a /T parameter which tells PGMDISP to only execute the DB2 Table Information logic.
I wanted to be able to place my cursor on a table name when editing SQL or JCL and press a PFKey to execute TT against the table name.
I cloned John Bubenheim's ZOOM, which lets you browse a JCL dataset, so that I can extract the table name, and named it DB2ZOOM. When I press the PFKey it executes DB2ZOOM but for some reason doesn't execute TT after it exits DB2ZOOM, but instead just exits.
I have a TESTREXX program where I was able to execute TESTREXX and have it execute TT upon exiting using the PUSH statement in TESTREXX; however when I do the same thing in DB2ZOOM it doesn't work.
Code:
/*% NOCOMMENT rexx */
/*
PROGRAM: DB2ZOOM
AUTHOR: Roy Mathur
PURPOSE: Provide cursor sensitive DB2 Table name recognition
allowing users to execute TT (PGMDISP) against a
table in a file they are viewing or editing; it does
not work in browse.
USAGE: Place cursor under any valid DB2 Table name and start
DB2ZOOM from the command line or a predefined PFKey.
PFKey use is recommended to minimize cursor
repositioning. If the cursor is left on the command
line, the first data line displayed will be searched
for a valid DB2 Table name.
NOTES:
- The slash-asterix-percent NOCOMMENT card causes all
REXX comment lines to be removed before the program
is loaded into VLF storage.
MAINTENANCE:
- 2014-05-06 - roy mathur - Original coding.
===================================================================*/
/*-------------------------------------------------------------------
* - Set error and message controls
* - Establish edit macro environment
* - Set mode
-------------------------------------------------------------------*/
SETUP:
"ISPEXEC CONTROL ERRORS RETURN"
x = Msg("OFF")
"ISREDIT MACRO (ARG)"
/*-------------------------------------------------------------------
* - Find and save current cursor location
* - Set data length and a list of valid Table name characters
* - Determine if cursor is on valid Table name character
-------------------------------------------------------------------*/
CHECK_CURSOR_DATA:
"ISREDIT (LIN,COL) = CURSOR"
olin = lin ; ocol = col
if col = 0 then do
zedsmsg = 'Invalid Cursor Location'
zedlmsg = 'Error 1: The cursor must be on any character of a creator.tablename.'
address ispexec "SETMSG MSG(ISRZ001)"
signal QUIT
end
"ISREDIT (DATA) = LINE .ZCSR"
data = Translate(data)
/*-------------------------------
| identify end of table name
|------------------------------*/
epos = pos(' ',data,col)
if epos = 0 then do
zedsmsg = 'Invalid Cursor Location'
zedlmsg = 'Error 2: Unable to find a blank after the creator.tablename. The cursor must be on any character of a creator.tablename.'
address ispexec "SETMSG MSG(ISRZ001)"
signal QUIT
end
data = substr(data,1,epos - 1)
/*-------------------------------
| identify start of table name
|------------------------------*/
data = reverse(data)
bpos = pos(' ',data)
if bpos = 0 then do
zedsmsg = 'Invalid Cursor Location'
zedlmsg = 'Error 2: Unable to find a blank before the creator.tablename. The cursor must be on any character of a creator.tablename.'
address ispexec "SETMSG MSG(ISRZ001)"
signal QUIT
end
/*-------------------------------
| extract table name
|------------------------------*/
data = substr(data,1,bpos - 1)
data = reverse(data)
data = strip(data)
/*-------------------------------
| identify start of table name
|------------------------------*/
if substr(data,1,1) = "'" then data = substr(data,2)
data = reverse(data)
if substr(data,1,1) = "'" then data = substr(data,2)
data = reverse(data)
/*If Verify(Substr(data,col,1),val,"N") \= 0 Then Do
Say "INVALID CURSOR LOCATION"
Signal QUIT
End
*/
/*-------------------------------
| execute tt
|------------------------------*/
PUSH "%pgmdisp" data "/T" arg
signal QUIT
/*-------------------------------------------------------------------
* - Reset excluded lines
* - Return cursor to original location
* - Exit from ZOOM
-------------------------------------------------------------------*/
QUIT:
Posted: Thu May 08, 2014 7:33 am Post subject: Sometimes works
When I exited SPUFI the TT screen popped up. When I exited, it popped up again and again and again. Apparently all the times I Zoomed were queued up and didn't execute until I exited SPUFI.
How can I get it to execute immediately within SPUFI?
Hi kolusu, I did/do have the same PFKey settings. Yes they do.
I finally got it to work by replacing PUSH with:
"%PGMDISP" data "/T" arg
Now I'm wondering whether I can modify it so that it works when I'm browsing a member instead of editing it. I've been searching, but so far haven't found anything.
Joined: 26 Nov 2002 Posts: 12375 Topics: 75 Location: San Jose
Posted: Thu May 08, 2014 12:01 pm Post subject:
RoyKMathur wrote:
Now I'm wondering whether I can modify it so that it works when I'm browsing a member instead of editing it. I've been searching, but so far haven't found anything.
Edit 1 : Looks like Doug Nadel has taken down his utilities page.
Edit 2: Found it in my archives.
Code:
/* REXX exec to do cursor sensitive data extraction from an ISPF */
/* Screen. */
/* Uses undocumented/Unsupported variables zscreeni & Zscreenc */
/* available in ISPF for OS/390 R2.5 (ISPF4.5). */
/* */
/*------------------------------------------------------------------ */
/* ---> NOTE: ZSCREENI and ZSCREENC may give odd results in some */
/* ---> situations such as command line at the bottom!!!! */
/* ---> If this is a problem, force a call to subroutine */
/* ---> GET_ZSCREEN_VALUES instead of using ISPF's variables. */
/*------------------------------------------------------------------ */
/* */
/* Screen image may translate attr bytes to dsn chars causing */
/* extra characters like '#' to be added to the dsname */
/* */
/* Will not work in popups if invoked with the SUSPEND keyword. */
/* Note that the default command table entry for TSO does have */
/* the SUSPEND keyword. */
/* */
/* Usage: */
/* Name this VCURSOR, set a pfkey to VCURSOR and */
/* create a command table entry: */
/* VCURSOR 0 SELECT CMD(%VCURSOR) */
/* (Or setting pfkey to TSO %VCURSOR will work in most cases) */
/* Then place cursor on dsname and press the pf key. */
/* ZSCREENC may be wrong if initial command doesn't start */
/* with a percent or have MODE(FSCR) on the SELECT statement. */
/* */
/* Author : Doug Nadel April 24, 1999 */
/* Updates: Apr 26, 1999 now views PDS members also. */
/* Aug 18, Allow dsname in parentheses. */
/* Added additional information re MODE(FSCR). */
/* Bypass ZSCREENI and ZSCREENC if needed. */
/* (ISPF version <4.5 but will work in 4.5+) */
/* March 31, 2000 Added basic recognition of GDG names */
/* and view/edit/browse customization */
/* April 3, 2000 Added prompt panel. */
/*------------------------------------------------------------------ */
/* Customization to set service to view edit or browse */
/* or to use prompt panel. */
/*------------------------------------------------------------------ */
service='PROMPT' /* set to VIEW, EDIT, or BROWSE */
/* or PROMPT. */
/*------------------------------------------------------------------ */
Address ispexec
'VGET (ZSCREENI,ZSCREENC,ZENVIR)' /* Extract screen image,
cursor pos and ISPF level */
If substr(zenvir,5,4) <4.5 Then
Call get_zscreen_values
trtable='abcdefghijklmnopqrstuvwxyz' /* Setup valid dsname chars */
trtable=trtable||translate(trtable)||'$#@0123456789.''-{()'
trtable=translate(xrange('00'x,'FF'x),,trtable,' ')
zscreeni=translate(zscreeni,,trtable,' ') /* Remove non-Dsn chars */
If substr(zscreeni,zscreenc+1,1) <> ' ' Then /* Maybe csr on dsn */
Do /* Extract dsn from screen image
and view dataset */
name=word(substr(zscreeni,1+lastpos(' ',zscreeni,zscreenc)),1)
name=translate(strip(substr(name,1,56))) /* Max of 56 char name */
If substr(name,1,1)='(' Then
Parse Var name '('name')'.
Parse Var name dsn '('mem')' /* Is there a member name? */
omem=mem
If mem<>'' Then /* If so, reformat for view
cmd */
Do
gdg=0
name=dsn /* Get dsn */
If substr(name,1,1)='''' Then /* if original name started with
quotes */
name=name'''' /* Fix quotes */
If datatype(mem,'N') = 1 Then /* Gdg? */
Do
Drop otrap.
Call outtrap 'otrap.'
Address tso 'LISTCAT ENT('name')' /* Get real gdg names */
Call outtrap 'OFF'
If otrap.0>(2-2*mem) Then /* If enough lines returned */
Do
a=otrap.0-1+2*mem /* Parse listcat output */
n="'"subword(otrap.a,3,1)"'" /* Get real dsname */
If sysdsn(n)='OK' Then /* Verify that ds exists */
Do /* If real gdg name exists */
name=n /* Use rea name as dsname */
mem='' /* Forget the member name */
omem='' /* Forget the member name */
gdg=1 /* Indicate we forgot member
name */
End
End
End
If gdg=0 Then /* If gdg check failed */
mem='MEMBER('mem')' /* Add member keyword for view*/
End
'CONTROL ERRORS RETURN' /* Return errors to program */
'LMINIT DATAID(VCURSOR) DATASET('name')' /* Alloc w/ Tso naming */
If rc>0 & substr(name,1,1) <> "'" Then /* Alloc w/O tso name */
'LMINIT DATAID(VCURSOR) DATASET('''name''')'
If rc=0 Then
Do
service=translate(service)
If service='PROMPT' Then
Call getservice
If service<>"" Then
service 'DATAID('vcursor')' mem /* View the dataset */
End
Else /* Allocs failed: Set original
message */
'LMINIT DATAID(VCURSOR) DATASET('name')'
If rc>7 Then
'SETMSG MSG(ISRZ002)' /* If error, show messages */
'LMFREE DATAID(&VCURSOR)' /* Free ds if allocated */
End
Else /* Cursor was not on a dsname */
Do /* Give user an error message */
zerrsm = 'Invalid cursor position'
Parse Value '* YES The cursor was not on a data set name.',
With zerrhm zerralrm zerrlm
'SETMSG MSG(ISRZ002)'
End
Exit 0
get_zscreen_values: /* obtain the screen image */
Address ispexec 'VGET (ZSCREENW,ZSCREEND)'
p = ptr(96+ptr(ptr(24+ptr(112+ptr(132+ptr(540))))))
zscreeni=translate(storage(d2x(p),,
zscreenw*zscreend),,xrange('00'x,'3f'x))
zscreenc = c2d(storage(,
d2x(164+ptr(ptr(24+ptr(112+ptr(132+ptr(540)))))),4))
Return
ptr: Return c2d(bitand(storage(d2x(Arg(1)),4),'7FFFFFFF'x))
getservice: Procedure Expose service name omem
'VGET ZSCREEN'
service='EDIT'
dsn=name
Parse Source . . me .
If omem <> "" Then
Do
If substr(dsn,1,1)='''' Then
dsn=substr(dsn,1,length(dsn)-1)'('omem')'''
Else
dsn=dsn'('omem')'
End
Address tso
ddname='$VCSR$'zscreen
'alloc f('ddname') reuse new del dso(po) dir(1) sp(1)' ,
'track recfm(f b) lrecl(80)'
Address ispexec
'LMINIT DATAID(DID) DDNAME('ddname') ENQ(EXCLU)'
'LMOPEN DATAID(&DID) OPTION(OUTPUT)'
Call write ")ATTR"
Call write "+ TYPE(NT)"
Call write "@ TYPE(PT)"
Call write "? TYPE(CH)"
Call write "# TYPE(output) just(asis) caps(off)"
Call write ")BODY WINDOW(60,14)"
Call write " @Cursor Sensitive Action+"
Call write "+%"
Call write "+Dataset:+&DSN"
Call write "+"
Call write "? Select action:"
Call write " _Z% 1. Edit"
Call write " %#VCAXXY +"
Call write " %#VCAXXZ +"
Call write " "
Call write "? Press%END?to cancel this action."
Call write " "
Call write "? To avoid this panel, modify your "me" exec."
Call write ")INIT"
Call write " VGET (VCACTNX) PROFILE"
Call write " .ZVARS = 'VCACTNX'"
Call write " &VCAXXY = ' 2. View'"
Call write " &VCAXXZ = ' 3. Browse'"
Call write ")REINIT"
Call write " REFRESH(*)"
Call write ")PROC"
Call write " IF (.CURSOR = VCAXXY) &VCACTNX = '2' /* allow csr selct*/"
Call write " IF (.CURSOR = VCAXXZ) &VCACTNX = '3'"
Call write " VER (&VCACTNX, NB ,LIST,1,2,3)"
Call write " IF (.MSG NE &Z) &VCACTNX=1"
Call write " VPUT (VCACTNX) PROFILE"
Call write ")END"
'LMMADD DATAID(&DID) MEMBER(FOO)'
'LMFREE DATAID(&DID)'
'LIBDEF ISPPLIB LIBRARY ID('ddname')'
'ADDPOP'
'DISPLAY PANEL(FOO)'
If rc>0 Then service=""
Else If vcactnx=2 Then service='VIEW'
Else If vcactnx=3 Then service='BROWSE'
'REMPOP'
'LIBDEF ISPPLIB'
Address tso
'FREE F('ddname')'
Return
write:
Parse Arg p1
"LMPUT DATAID(&DID) MODE(INVAR) DATALOC(P1) DATALEN(80)"
Return
I think the problem is at a higher level than the REXX Edit macro because when I am browsing a dataset or member and enter VCURSOR I get back a message "Invalid Command" at the top right of the screen (PF1 displays: The command entered is not valid for BROWSE.).
I'm still walking through VCURSOR to see learn from it. Already I found one line of Doug's code that replaces 26 lines of my code...
I haven't been able to find anything that'll let me execute a command from the command line that will capture data where the cursor is positioned. Apparently you MUST be in edit or view mode. Does anyone know whether this is possible?
Joined: 26 Nov 2002 Posts: 12375 Topics: 75 Location: San Jose
Posted: Mon May 12, 2014 2:48 pm Post subject:
RoyKMathur wrote:
I haven't been able to find anything that'll let me execute a command from the command line that will capture data where the cursor is positioned. Apparently you MUST be in edit or view mode. Does anyone know whether this is possible?
RoyKMathur,
If your command needs an edit session, then I guess you are out of luck. Why can't you invoke the command in VIEW mode, so that you are guaranteed that you don't destroy the member in case something goes wrong. _________________ Kolusu
www.linkedin.com/in/kolusu
It's not that I can't enter View or Edit but rather that while browsing a job's output or pds(mem) and having paged down x number of pages and then realize I want to zoom in on a file or table...now I have to enter view/edit and then page back down before I can zoom...I'm LAZY and would rather just zoom while I'm there.
They say "Necessity is the mother of invention", but I think it's "Laziness is the mother of invention".
I mean seriously, ISPF has been around for 4 decades and we still can't extract a word in Browse mode!!! There are still millions of people around the world using ISPF. I bet at one time the TSO/ISPF software development team had a bunch of imaginative innovative ideas but upper management deep-sixed them. Shame.
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum