Improved ISPF productivity
All the following edit macros were developed to make ISPF edit/browse processing more productive.
The first three ,CB,CE and CM, allow for browsing, editting or dataset list utility processing of any
dataset name shown on the current edit screen, by simply entering CB or CE or CM on the
COMMAND ===> line and then locating the cursor anywhere on the dsname, before hitting ENTER.
For example, while editting JCL the contents of a SYSIN member may be browsed or editted without
recourse to the normal process of entering EDIT on the command line and then having to remember
and enter the DSN(member) details on the resultant ISREDM03 (Edit Command - Entry) panel.
CURSOR-BASED BROWSE MACRO - defined in ISPF ISPEXEC library as CB:
/****REXX*************************************************************/
ADDRESS ISREDIT
'MACRO PROCESS'
ADDRESS ISPEXEC 'CONTROL ERRORS RETURN'
'(cl,cc) = CURSOR'
IF cc = 0 THEN EXIT
'(LINE) = LINE' cl
UPPER line
valid = XRANGE('A','Z') XRANGE('0','9') '@#$£(.)'
end = LENGTH(line)
start = end - VERIFY(REVERSE(line) ' ',valid,'N',end-cc+1) + 2
len = VERIFY(line' ',valid,'N',cc) - start
IF len < 1 THEN EXIT
dsn = SUBSTR(line,start,len)
IF VERIFY(dsn,'.','M') = 0 THEN DO
'(dataset) = DATASET'
dsn = dataset'('dsn')'
END
ADDRESS ISPEXEC BROWSE "DATASET('"dsn"')"
IF rc > 0 THEN
DO
retcode = rc
SIGNAL Error_check
END
ELSE EXIT
Error_check:
IF retcode = 12 THEN
DO
ADDRESS ISPEXEC "SETMSG MSG(CMSGS007)"
EXIT
END
ELSE
DO
IF retcode = 14 THEN
DO
ADDRESS ISPEXEC "SETMSG MSG(CMSGS008)"
EXIT
END
ELSE
IF retcode = 16 THEN
DO
ADDRESS ISPEXEC "SETMSG MSG(CMSGS009)"
EXIT
END
ELSE
DO
ADDRESS ISPEXEC "SETMSG MSG(CMSGS000)"
END
END
EXIT
__________________________________________________________________________________
CURSOR-BASED EDIT MACRO - defined in ISPF ISPEXEC library as CE:
/***REXX**************************************************************/
ADDRESS ISREDIT
'MACRO PROCESS'
ADDRESS ISPEXEC 'CONTROL ERRORS RETURN'
'(cl,cc) = CURSOR'
IF cc = 0 THEN EXIT
'(LINE) = LINE' cl
UPPER line
valid = XRANGE('A','Z') XRANGE('0','9') '@#$£(.)'
end = LENGTH(line)
start = end - VERIFY(REVERSE(line) ' ',valid,'N',end-cc+1) + 2
len = VERIFY(line' ',valid,'N',cc) - start
IF len < 1 THEN EXIT
dsn = SUBSTR(line,start,len)
IF VERIFY(dsn,'.','M') = 0 THEN DO
'(dataset) = DATASET'
dsn = dataset'('dsn')'
END
ADDRESS ISPEXEC EDIT "DATASET('"dsn"')"
IF rc > 0 THEN
DO
retcode = rc
SIGNAL Error_check
END
ELSE EXIT
Error_check:
IF retcode = 4 THEN
DO
ADDRESS ISPEXEC "SETMSG MSG(CMSGS004)"
EXIT
END
ELSE
DO
IF retcode = 14 THEN
DO
ADDRESS ISPEXEC "SETMSG MSG(CMSGS005)"
EXIT
END
ELSE
IF retcode = 16 THEN
DO
ADDRESS ISPEXEC "SETMSG MSG(CMSGS006)"
EXIT
END
ELSE
DO
ADDRESS ISPEXEC "SETMSG MSG(CMSGS000)"
END
END
EXIT
__________________________________________________________________________________
CURSOR-BASED DATASET LIST UTILITY MACRO - defined in ISPF ISPEXEC library as CM:
/***REXX**************************************************************/
ADDRESS ISREDIT
'MACRO PROCESS'
ADDRESS ISPEXEC 'CONTROL ERRORS RETURN'
'(cl,cc) = CURSOR'
IF cc = 0 THEN EXIT
'(LINE) = LINE' cl
UPPER line
valid = XRANGE('A','Z') XRANGE('0','9') '@#$£(.)'
end = LENGTH(line)
start = end - VERIFY(REVERSE(line) ' ',valid,'N',end-cc+1) + 2
len = VERIFY(line' ',valid,'N',cc) - start
IF len < 1 THEN EXIT
dsn = SUBSTR(line,start,len)
IF VERIFY(dsn,'.','M') = 0 THEN DO
'(dataset) = DATASET'
dsn = dataset'('dsn')'
END
ADDRESS ISPEXEC "VGET ZDLDSNLV"
Saved_zdldsnlv = ZDLDSNLV
ZDLDSNLV = dsn
ADDRESS ISPEXEC "LMINIT DATAID(dataid) DATASET('"dsn"')"
ADDRESS ISPEXEC "LMOPEN DATAID("dataid") OPTION(INPUT)"
ADDRESS ISPEXEC "LMMLIST DATAID("dataid")"
IF rc > 0 THEN
DO
retcode = rc
ADDRESS ISPEXEC "LMFREE DATAID("dataid")"
SIGNAL Error_check
END
ADDRESS ISPEXEC "VPUT ZDLDSNLV"
ADDRESS ISPEXEC "CONTROL NONDISPL ENTER"
ADDRESS ISPEXEC "SETMSG MSG(CMSGS001)"
ADDRESS ISPEXEC "SELECT PGM(ISRUDL) PARM(ISRUDLP)"
SIGNAL Endit
Error_check:
IF retcode = 4 THEN
DO
ADDRESS ISPEXEC "SETMSG MSG(CMSGS002)"
SIGNAL Endit
END
ELSE
DO
IF retcode = 12 THEN
DO
ADDRESS ISPEXEC "SETMSG MSG(CMSGS003)"
SIGNAL Endit
END
ELSE
IF retcode > 15 THEN
DO
ADDRESS ISPEXEC "SETMSG MSG(CMSGS000)"
EXIT
END
END
Endit:
ZDLDSNLV = Saved_zdldsnlv
ADDRESS ISPEXEC "VPUT ZDLDSNLV"
EXIT
__________________________________________________________________________________
CURSOR-BASED MACROs - messages defined in ISPF ISPMLIB library as CMSGS00:
CMSGS000 '' .ALARM=YES .WINDOW=RESP
'Unspecified error accessing &dsn - may not exist'
CMSGS001 '' .ALARM=YES .WINDOW=RESP
'Enter line command M for member list processing'
CMSGS002 '' .ALARM=YES .WINDOW=RESP
'&dsn contains no members'
CMSGS003 '' .ALARM=YES .WINDOW=RESP
'&dsn not a PDS'
CMSGS004 '' .ALARM=YES .WINDOW=RESP
'&dsn no data changed/saved'
CMSGS005 '' .ALARM=YES .WINDOW=RESP
'&dsn in use'
CMSGS006 '' .ALARM=YES .WINDOW=RESP
'Specified member not found or no members in &dsn'
CMSGS007 '' .ALARM=YES .WINDOW=RESP
'Zero length data set, empty dataset or empty member'
CMSGS008 '' .ALARM=YES .WINDOW=RESP
'Specified member not found'
CMSGS009 '' .ALARM=YES .WINDOW=RESP
'No members in &dsn'
The following macros allow the ISPF user to have access to functions not too dissimilar from the very
useful PC functions of CUT, COPY and PASTE. As the HELP information contained in each macro
shows CUTting will either copy lines selected by CC..CC line commands or cut lines selected by
MM...MM line commands. The resultant block of lines is then PASTEd either B(efore) or A(fter)
the designated line in the target dataset.
CUT lines are held as variables in the users ISPF profile pool. Any consecutive uses of CUT without
an intervening PASTE will result in the loss of the lines copied or moved from the first CUT.
CUT - defined in ISPF ISPEXEC library as CUT:
/**REXX**************************************************************/
ADDRESS ISPEXEC
'ISREDIT MACRO (PARM1) NOPROCESS'
linestocut = 0
IF parm1 = '?' THEN
DO
CALL help
Exit
END
'ISREDIT PROCESS RANGE C M'
SELECT
WHEN rc = 0 THEN
DO
'ISREDIT (CMD) = RANGE_CMD'
'ISREDIT (LINE1) = LINENUM .ZFRANGE'
'ISREDIT (LINE2) = LINENUM .ZLRANGE'
linestocut = line2 - line1 + 1
END
WHEN rc <= 4 THEN
DO
zcmd = ' '
zedsmsg = 'Enter "C"/"M" line cmd'
zedlmsg = 'CUT requires a "C" or "M" line command'
'SETMSG MSG(ISRZ001)'
Exit 12
END
OTHERWISE
Exit 12
END
cutcnt = 0
DO i = line1 to line2
cutcnt = cutcnt + 1
'ISREDIT (CL'cutcnt') = LINE' i
INTERPRET "CL"cutcnt"= STRIP(CL"cutcnt",'T')"
'VPUT (CL'cutcnt') PROFILE'
END
'VPUT (CUTCNT) PROFILE'
IF cmd = 'M' THEN
DO
'ISREDIT DELETE 'line1 line2
zcmd = ' '
zedsmsg = linestocut 'lines cut and deleted'
msg = 'lines were cut and deleted from the current file'
zedlmsg = linestocut msg
'SETMSG MSG(ISRZ000)'
END
ELSE
DO
zcmd = ' '
zedsmsg = linestocut 'lines cut'
zedlmsg = linestocut 'lines were cut from the current file'
'SETMSG MSG(ISRZ000)'
END
Exit
Help:
Say ' '
Say ' ISPF/PDF edit macro to write lines from a file to the users '
Say ' PROFILE pool for later inclusion by the PASTE macro. '
Say ' '
Say ' To run: '
Say ' Enter CUT at the COMMAND ===> prompt and use C or M line '
Say ' commands to select the lines to be cut. '
Say ' '
Say ' If the M line command is used, the selected lines will be '
Say ' deleted from this dataset. '
Say ' '
RETURN
__________________________________________________________________________________
PASTE - defined in ISPF ISPEXEC library as PASTE:
/**REXX**************************************************************/
ADDRESS ISPEXEC
'ISREDIT MACRO (PARM1) NOPROCESS'
linestocut = 0
trunccnt = 0
line1 = 0
lptr = 0
IF parm1 = '?' THEN
DO
CALL help
Exit
END
'CONTROL ERRORS RETURN'
'ISREDIT PROCESS DEST'
SELECT
WHEN rc = 0 THEN
DO
'ISREDIT (lptr) = LINENUM .ZDEST'
END
WHEN rc <= 8 THEN
DO
zedsmsg = 'Enter "A"/"B" line command'
zedlmsg = 'PASTE requires an "A" or "B" line command'
'SETMSG MSG(ISRZ001)'
Exit 12
END
WHEN rc <= 20 THEN
EXIT 12
WHEN rc = 20 THEN
lptr = 0
OTHERWISE
Exit 12
END
'CONTROL ERRORS CANCEL'
'VGET (CUTCNT) PROFILE'
IF rc ª= 0 THEN
DO
zedsmsg = 'Use CUT before PASTE'
zedlmsg = 'No data has been stored via CUT macro'
'SETMSG MSG(ISRZ001)'
Exit 12
END
IF cutcnt = 0 THEN
DO
zedsmsg = 'Use CUT before PASTE'
zedlmsg = 'No data has been stored via CUT macro'
'SETMSG MSG(ISRZ001)'
Exit 12
END
trunccnt = 0
cutcount = cutcnt
DO i = cutcnt to 1 by -1
'VGET (CL'i') PROFILE'
'ISREDIT LINE_AFTER 'lptr' = DATALINE (CL'i')'
IF rc = 4 THEN
DO
trunccnt = trunccnt + 1
END
END
'VGET (ZENVIR) SHARED'
DO i = 1 to cutcnt by 1
'VERASE (CL'i') PROFILE'
END
cutcnt = 0
'VPUT (CUTCNT) PROFILE'
IF trunccnt > 0 THEN
DO
zedsmsg = trunccnt ' lines truncated'
msg = 'Current rec.len. shorter than origin'
zedlmsg = msg '-' trunccnt ' of ' cutcount ' recs truncated'
'SETMSG MSG(ISRZ001)'
END
line1 = lptr + 1
'ISREDIT CURSOR = 'line1 0
Exit
Help:
Say ' '
Say ' ISPF/PDF edit macro to write lines from the user PROFILE pool '
Say ' into the current file. This macro is used in conjunction with '
Say ' the CUT macro. '
Say ' '
Say ' To run: '
Say ' Enter PASTE at the COMMAND ===> prompt and use A or B line '
Say ' commands to select the location at which the lines will be '
Say ' pasted. '
Say ' '
RETURN
All macros have been developed and run under ISPF/PDF 4.2.1 for OS/390 1.3 but should be
downwardly compatible to at least ISFP 3.2.
All macros can of course be assigned to a spare PF key, something which has proved very useful with
CUT and PASTE. (Eg PF16 = ;CUT, PF17 = ;PASTE)
[Back]