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]