ISPF Tips for Cobol Programmers

by Bill Price


This document outlines some features of ISPF which can greatly enhance programmer productivity. These features are basic to the product but, generally speaking, are little known and rarely put into use by most ISPF users.

It is assumed that the reader already has a basic understanding of ISPF.

Please bear in mind that some of the tools presented in this document work best when used in conjunction with other tools, (e.g., using PFKeys to locate labels).


Setting and Using PFKeys

In addition to the basic PFKey functions in ISPF which are set up by default (PF1 through PF12), the user may set up customized PFKeys.

The older mainframe keyboards were constructed with PFKeys 1 through 24. On PC keyboards PFKeys 13 through 24 are available by pressing PFKeys 1 through 12 while simultaneously holding down the Shift key.

The user may customize PFKey settings from the “Keylist Utility” panel. This panel is invoked by entering “KEYS” on the primary command line and pressing enter. Use PF7 and PF8 to page forward and backward. Overtype the default values for PF13 through PF24 with any ISPF command desired. Commands may be stacked using the semicolon. Note that line commands must be preceded by a colon.

With the newer versions of ISPF, the “KEYS” command will pull up a different Keylist Panel depending on which ISPF panel one is working. This allows the user to have a separate set of customized PFKey settings for each of the working environments within ISPF.

From the primary option menu and from SDSF a default Keylist panel will be invoked. In this panel the user may toggle between page 1 and page 2 by pressing enter. In other panels paging is available via PF7 and PF8.

From “view” (option 1) and “edit” (option 2) the ISRSPECH panel will be invoked.

From “browse” (option 1) the ISRSPBCH panel will be invoked.

(Please note that “view”, available in the newer versions of ISPF, brings up the member in browse mode but unprotects the text and the line command area. “View” mode should be used when one has no intention of updating the member but has the need to enter line commands, such as setting labels. Setting labels is not allowed in browse mode since the line command area is protected.)

From option 3 the ISRSABH panel will be invoked.


Suggested PFKey Settings

The following PFKey settings, especially those for edit and view, are highly recommended and are used in the examples throughout this document. For explanations of commands, see later sections.

For ISRSPECH (used for edit and view):

Leave PF1-PF11 at their default values. Set PF12 to “retrieve”.

(PF4 can optionally be set to “return”, a function that is useful for quickly returning to the ISPF primary option menu, from where appropriate PFKey settings can quickly take us to SDSF).

 Key      Definition                             Format   Label
  
 F1 . . . HELP                                    SHORT   Help 
 F2 . . . SPLIT                                   LONG    Split 
 F3 . . . EXIT                                    SHORT   Exit 
 F4 . . . return                                  LONG    return 
 F5 . . . RFIND                                   SHORT   Rfind 
 F6 . . . RCHANGE                                 SHORT   Rchange 
 F7 . . . UP                                      LONG    Up 
 F8 . . . DOWN                                    LONG    Down 
 F9 . . . SWAP                                    LONG    Swap 
 F10 . .  LEFT                                    LONG    Left 
 F11 . .  RIGHT                                   LONG    Right 
 F12 . .  retrieve                                SHORT   Cancel 

Explanation:

PF12 retrieves the most recent command entered on the command line. By successively entering PF12 one can retrieve all subsequent commands. (Note: by entering “RETP” on the command line, one can see a list of the most recent commands entered and select one directly).

Set PF13-PF24 as follows:

 Key      Definition                                Format   Label
  
 F13  . . f procedure 8 first;cursor                 SHORT   Help    
F14 . . l .c LONG Split
F15 . . l .d SHORT End
F16 . . l .e SHORT Return
F17 . . f first SHORT Rfind
F18 . . f first 8 SHORT Rchange
F19 . . :ts LONG Up
F20 . . x all;f 8 p'^' all;x 7 '*' all;f proce 8 LONG Down
F21 . . ex all;f all LONG Swap
F22 . . l .a;up 5 SHORT Left
F23 . . l .b;up 5 SHORT Right
F24 . . cursor;reset SHORT Cretriev

Explanation:

PF13 finds the first occurrence of “PROCEDURE” and then positions the cursor at the command line. This PFKey is used for positioning at the PROCEDURE DIVISION.

PF14 locates label C. (See section on “Setting Labels”).

PF15 locates label D. (See section on “Setting Labels”).

PF16 locates label E. (See section on “Setting Labels”).

PF17 finds the first occurrence of a string value entered on the command line.

PF18 finds the first occurrence in column 8 of a string value entered on the command line. This is useful for locating a Cobol paragraph name.

PF19 splits the line at the cursor position.

PF20 excludes all lines in the program, except for 01 levels in the working storage and paragraph names in the procedure division. This PFKey is useful for quick viewing of all paragraph names in a program. It is most useful when used in conjunction with locating labels. See Example 2 in the Review and Examples section.

PF21 excludes all lines in the program except for those containing the string entered on the command line. This is an extremely useful function.

PF22 locates label A and then scrolls up 5 lines. (See section on “Setting Labels”).

PF23 locates label B and then scrolls up 5 lines. (See section on “Setting Labels”).

PF24 resets the display and then positions the cursor on the command line.



For SDSF:

(Note: This example assumes that your TSOID is CS0355. Modify as needed.)

 PF13  . . o;pre cs0355*                                                        
PF14 . . h;pre cs0355*
PF15 . . i;pre cs0355*
PF16 . . log
PF17 . . IFIND
PF18 . . da otsu;pre cs*
PF19 . . da ojob;pre cs0355*
PF20 . . DOWN
PF21 . . SWAP
PF22 . . LEFT
PF23 . . RIGHT
PF24 . . RETRIEVE

Explanation:

PF13 displays the output queue and narrows the search down to the TSOID specified.

PF14 displays the held output queue and narrows the search down to the TSOID specified.

PF15 displays the input queue and narrows the search down to the TSOID specified.

PF16 displays the system log.

PF18 displays all TSO users currently logged on whose TSOID’s begin with CS.

PF19 displays all active jobs and narrows the search down to the TSOID specified.


For Primary Option Menu:

(Note: this example assumes that the primary command for going to SDSF is 8. Change for whatever value is used for your shop.)

 PF13  . . ;=8;pre cs0355*;o       
PF14 . . ;=8;pre cs0355*;h
PF15 . . ;=8;i
PF16 . . ;=8;log
PF17 . . RFIND
PF18 . . ;=8;da otsu;pre cs*
PF19 . . ;=8;da ojob;pre cs0355*
PF20 . . DOWN
PF21 . . SWAP
PF22 . . LEFT
PF23 . . RIGHT
PF24 . . RETRIEVE

Explanation:

PF13 goes to SDSF, displays the output queue and narrows the search down to the TSOID specified.

PF14 goes to SDSF, displays the held output queue and narrows the search down to the TSOID specified.

PF15 goes to SDSF, displays the input queue and narrows the search down to the TSOID specified.

PF16 goes to SDSF and displays the system log.

PF18 goes to SDSF and displays all TSO users currently logged on whose TSOID’s begin with CS.

PF19 goes to SDSF, displays all active jobs and narrows the search down to the TSOID specified.


Setting Labels

While in edit or view mode, one can place “bookmarks” within the member by setting ISPF labels.

The purpose of setting labels is to allow the user to return to a specific point within an edited (or viewed) member.

Labels are set in the line command area of the screen by entering a period immediately followed by one or more alphabetic characters.

Example:

Before setting label:

000255            MOVE COMPANYB02             TO TZS008-COMPANY. 
000256 MOVE PRODUCTB02 TO TZS008-PRODUCT.
000257 MOVE POLICYB02 TO TZS008-POLICY.
000258 MOVE ITEMNOB02 TO TZS008-ITEMNO.
000259 MOVE RISKSEQB02 TO TZS008-RISKSEQ.

After setting label:

000255            MOVE COMPANYB02             TO TZS008-COMPANY. 
.A MOVE PRODUCTB02 TO TZS008-PRODUCT.
000257 MOVE POLICYB02 TO TZS008-POLICY.
000258 MOVE ITEMNOB02 TO TZS008-ITEMNO.
000259 MOVE RISKSEQB02 TO TZS008-RISKSEQ.

To locate a labeled line, use the “L” (locate) command. In the above example, the line labeled “.A” may be located from any position within the program (above or below) by entering “L .A” on the command line. “L”, unlike “F”, does not perform a unidirectional search from the current edit location, i.e., it will always immediately take you to the labeled line, regardless of your current edit location. The editor can position you much more quickly and efficiently with the “L” command than with the “F” command, since it already knows where the labeled line is. The editor equates the label to a line number.

Labels are removed by simply spacing them out or by overtyping, or by typing in the same label at another location, or by typing the primary command “RES LAB” which removes all labels everywhere, or by simply terminating the edit session.

Do not hesitate to use labels liberally in your edit session. Entering labels in your edited member is perfectly harmless. They in no way affect or modify the member itself, and only remain in effect during the current edit session. They are not saved when the member is saved.

Please note: Working with labels is extremely effective and easy when used in conjunction with PFKeys. Use PFKeys for locating specific labels! Setting labels and locating them via PFKeys allows you to flip between different locations within your program with lightning speed. This is one of the most convenient and powerful features of ISPF, but, sadly to say, very very few ISPF users take advantage of this powerful tool.


Excluding Lines of Text

To view two locations within an edited member at the same time, exclude the intervening lines by using the “XX” block command. Individual lines may be excluded by the line command “X”.

When a line is excluded, it is simply excluded from the display. It is not in any way modified or deleted. If you save a member while lines are excluded and then bring it up in edit again, you will notice that the excluded lines reappear; i.e., exclusion remains in effect only for the current edit session.

To remove all exclusions during an edit session, enter the primary command “RESET” (which for convenience should be set up as a PFKey), and all the excluded lines will reappear.

If you want to restore a subset of excluded lines to the display while leaving other exclusions intact, enter the line command “Fn” where “n” is the number of lines beginning from the top of the exclusion which you wish to display. Enter “Ln” where “n” is the number of lines beginning from the bottom of the exclusion that you wish to display. Use this command with caution, since typing “Rn” instead of “Fn” will repeat the excluded lines “n” number of times!

You can also selectively exclude lines by entering the primary command “EX” (or “X”) with an argument:

Examples:

EX 'ABC' ALL

The above primary command will exclude all lines in the member which contain the string ‘ABC’.

Excluding lines can also be used for selectively mass-deleting lines from a member.

Examples:

DEL EX ALL

The above primary command will physically delete all of the excluded lines from a member, leaving all displayed lines intact.

DEL NX ALL

The above primary command will physically delete all of the displayed lines from a member, leaving all excluded lines intact.

EX ALL;F ALL

To view “at a glance” all lines in a member which contain a certain string, enter “EX ALL” on the primary command line (which excludes all lines in the member), followed by ‘F ALL xxx’ where ‘xxx’ is the string. Only those lines containing the specified string will be displayed.

These two commands (EX ALL;F ALL) may be stacked and set up as a PFKey. The result is an extremely powerful tool for instantly displaying all lines in a member which contain a desired string.

To reset the display after using EX ALL:F ALL, simply enter “RESET”.

Example:

While writing a program, I need to know if I have defined all of my switches in Working Storage. I enter “SW” on the primary command line, press PF21 (which I have set up as EX ALL;F ALL), and I can see every occurrence of the string “SW” in the program. If any are missing from Working Storage, I add them. If I need to continue to “hold” two positions in the program, one in W/S and one in the Procedure Division, I can enter labels .A and .B on the lines desired. I then press PF24 (which I have defined as “RESET”), which restores all excluded lines, and by hitting PF22 (L .A) and PF23 (L .B) I can flip between the two positions in the program as long as needed.

Please note that setting up a PFKey ‘EX ALL;F ALL’ and using it in conjunction with a PFKey for ‘RESET’ is one of the most convenient and powerful tools available in ISPF. Unfortunately, it is virtually ignored by 99 percent of all ISPF users.


Using FIND/CHANGE Commands

Familiarize yourself with the following features of the ‘F’ and ‘C’ commands. Note that the arguments are not positional and may be specified in any order desired, (e.g., “F FIRST xxx” may also be entered as “F xxx FIRST”).

F FIRST xxx

Finds first occurrence of string xxx

F LAST xxx

Finds last occurrence of string xxx

F PREV xxx

Finds the previous occurrence of string xxx

F xxx A. B.

Finds first occurrence of string xxx within the lines labeled .A and .B

F xxx 10 15

Finds the first occurrence of string xxx between columns 10 and 15.

F xxx .A .B 10 15

Finds the first occurrence of string xxx within the rectangular area defined by lines labeled .A and .B and columns 10 and 15.

F X'123C'

Finds hexadecimal value ‘123C’

C P'^' ' ' 10 12 ALL

Changes all non-space characters to spaces in columns 10 through 12.

C P'=' ' ' 1 6 ALL

Changes everything found in columns 1 through 6 into spaces

C P'<' P'>' ALL

Changes all lower-case characters into upper case

(Note: converting from upper case to lower case and vice versa can also be performed by entering the line command ‘LC’ or ‘UC’, or as block commands ‘LCC’ and ‘UCC’).

F P'#' 20 25 FIRST

Finds the first numeric character in columns 20 through 25.

Find and Change commands can be used together with the following Picture arguments:

  P'=' -------> ANY CHARACTER
  P'@' -------> ALPHABETIC CHARACTERS
  P'#' -------> NUMERIC CHARACTERS
  P'$' -------> SPECIAL CHARACTERS
  P'^' -------> NON-BLANK CHARACTERS
  P'.' -------> INVALID CHARACTERS
  P'-' -------> NON-NUMERIC CHARACTERS
  P'<' -------> LOWER-CASE CHARACTERS
  P'>' -------> UPPER-CASE CHARACTERS


Using the ‘FIND FIRST 8’ PFKey

The easiest and most efficient way of positioning yourself at the beginning of a paragraph or section name in a Cobol program is to use the ‘FIND FIRST 8’ PFKey, which in this document is defined as PF18.

Example:

In order to find paragraph TEB-OPEN-CUR02, enter ‘TEB’ on the command line and press PF18. The editor will position you at the beginning of the paragraph. The advantage of using this command is that it immediately brings you to the desired paragraph, regardless of your current position within the program. (Here it is of course assumed that there is no other paragraph in the program that begins with the string "TEB". It is a good programming practice to define unique prefixes for each paragraph.)


RETRIEVE (PF12)

Earlier versions of ISPF by default defined PF12 as ‘RETRIEVE’. If your default ISPF setting for PF12 is not RETRIEVE, you should restore it.

The RETRIEVE command brings back the most recent command entered on the command line.

All commands entered on the command line are saved by ISPF into a stack area. Continually pressing PF12 (RETRIEVE) will retrieve these commands in a circle, beginning from the most recent and ending with the oldest, and then wrapping around again.

The most recently entered commands can also be viewed and retrieved by entering the primary command ‘RETP’. This brings up an ISPF pop-up window from which the user may retrieve a command by line number.

The RETRIEVE command’s primary usefulness is eliminating the need for repetitive typing of long commands, such as finding datanames. Another use is for “remembering” information that was entered previously, such as a customer number or any other data that was entered via a find command.


COLS

The line command ‘COL’ (or ‘COLS’) inserts a column heading line in your edit display at that line location. The column line may be removed by a ‘D’ line command, or by entering the primary command RESET (which we are defining in this document as PF24).

The column line is especially useful when editing a dataset and finding where the fields begin and end within a record. It is also useful for locating certain column positions when writing programs, especially when one is adhering to coding standards that involve column positions.

In edit and view mode, the COLS command is a line command. In browse mode, the COLS command is entered in the primary command area.


BNDS

The line command ‘BNDS’ allows you to set the bounds in your edited member for the FIND, CHANGE, or ‘shift’ commands.

Enter ‘BNDS’ in the line command area and press enter. Then overtype the ‘<’ and ‘>’ where you want the new left and right bounds to be, or, if you already know the column numbers, simply enter ‘BNDS xxx yyy’ where xxx and yyy are the left and right bounds. Subsequent find, change, or shift commands will then only take effect within the bounds that you have set.

Warning: You must restore the bounds when you are done; otherwise these new bound settings remain in effect indefinitely for the entire PDS, even if you log off and log back on again! To make sure that the bounds are reset to the defaults, just enter ‘BNDS’ (with no arguments) in the primary command area. If you fail to do this, your "FIND" and "CHANGE" commands will only work within the column boundaries that were set with the last BNDS command.


Shift Command

Single lines or an entire block of data within an edited member may be shifted right or left by means of the shift command.

The shift command is executed by entering right or left parentheses in the line command area.

To shift a line five columns to the right, enter )5 in the line command area and press enter.

To shift a line three columns to the left, enter (3 in the line command area and press enter.

To shift a block of data nn columns to the right, enter ))nn on the first line of the block, and )) on the last line of the block, and press enter.

To shift a block of data nn columns to the left, enter ((nn on the first line of the block, and (( on the last line of the block, and press enter.

Examples:

Before shifting a block of three lines four columns to the right:

  000159            MOVE TZL000-COMPANY-LNK     TO COMPANYW03.
  ))4 60            MOVE TZL000-PRODUCT-LNK     TO PRODUCTW03.
  000161            MOVE TZL000-POLICY-LNK      TO POLICYW03.
  ))0162            MOVE TZL000-EFFECTDTE-LNK   TO EFFECTDTEW03.
  000163 
  000164            PERFORM TEB-OPEN-CUR01.

After pressing enter:

  000159            MOVE TZL000-COMPANY-LNK     TO COMPANYW03.
  000160                MOVE TZL000-PRODUCT-LNK     TO PRODUCTW03. 
  000161                MOVE TZL000-POLICY-LNK      TO POLICYW03. 
  000162                MOVE TZL000-EFFECTDTE-LNK   TO EFFECTDTEW03.
  000163
  000164            PERFORM TEB-OPEN-CUR01.

Note that with the block command, the number may be entered on the last )) instead of the first:

  000159            MOVE TZL000-COMPANY-LNK     TO COMPANYW03.
  ))  60            MOVE TZL000-PRODUCT-LNK     TO PRODUCTW03.
  000161            MOVE TZL000-POLICY-LNK      TO POLICYW03.
  ))4162            MOVE TZL000-EFFECTDTE-LNK   TO EFFECTDTEW03.
  000163 
  000164            PERFORM TEB-OPEN-CUR01.

The shift command is often used in conjunction with setting bounds.

Example:

I am editing Working Storage and want to shift picture clauses over to line up with column 40, but without disturbing the rest of the line. In the following example, the picture clauses begin in column 36:

  000062        01 EDIT-FIELDS-W82. 
  000063           03 EDIT-2-W82            PIC 9(02)    VALUE ZERO.
  000064           03 EDIT-3-W82            PIC 9(03)    VALUE ZERO.
  000065           03 EDIT-4-W82            PIC 9(03)    VALUE ZERO.

I first enter COLS in the line command area to display a column heading:

  cols62        01 EDIT-FIELDS-W82.  
  000063           03 EDIT-2-W82            PIC 9(02)    VALUE ZERO.
  000064           03 EDIT-3-W82            PIC 9(03)    VALUE ZERO.
  000065           03 EDIT-4-W82            PIC 9(03)    VALUE ZERO.

and then press enter:

  =COLS> ----+----1----+----2----+----3----+----4----+----5----+----6----
  000062        01 EDIT-FIELDS-W82.
  000063           03 EDIT-2-W82            PIC 9(02)    VALUE ZERO.
  000064           03 EDIT-3-W82            PIC 9(03)    VALUE ZERO.
  000065           03 EDIT-4-W82            PIC 9(03)    VALUE ZERO.

I notice that the PIC clause begins in column 36. Therefore I set the bounds to columns 36 through 80 by entering BNDS 36 80 on the command line and pressing enter.

Then I enter the block shift command to shift the lines four columns to the right:

  =COLS> ----+----1----+----2----+----3----+----4----+----5----+----6----
  000062        01 EDIT-FIELDS-W82.
  ))4 63           03 EDIT-2-W82            PIC 9(02)    VALUE ZERO.
  000064           03 EDIT-3-W82            PIC 9(03)    VALUE ZERO.
  ))0065           03 EDIT-4-W82            PIC 9(03)    VALUE ZERO.

After pressing enter the picture clauses are shifted four columns to the right, while the rest of the data on the lines remains intact:

  =COLS> ----+----1----+----2----+----3----+----4----+----5----+----6----
  000062        01 EDIT-FIELDS-W82.
  000063           03 EDIT-2-W82                PIC 9(02)    VALUE ZERO.
  000064           03 EDIT-3-W82                PIC 9(03)    VALUE ZERO.
  000065           03 EDIT-4-W82                PIC 9(03)    VALUE ZERO.

I then press PF24 (‘RESET’) to erase the COLS line, and enter BNDS (with no arguments) on the command line to restore the bounds to the default.


Copy with Overlay

Normally one uses the ‘C’ copy line command in conjunction with ‘B’ for copy before and ‘A’ for copy after. There are certain cases, however, where it is desirable to copy with overlay, using the ‘O’ line command. One can overlay onto a single line with the ‘O’ command, or onto a block of lines with the ‘OO’ block command.

The overlay command takes the copied line and overlays only those columns that contain spaces.

Example:

Suppose that I am setting up some JCL and want to concatenate some datasets. I go to 3.4 and copy the datasets with the mouse, and then drop them into some blank lines in the JCL as follows:

  000008 //I1        DD DSN=HUNTN.A1.C1.PPB210.DATASTRM.G1279V00,DISP=SHR 
  000009 //          DD DSN=HUNTN.A1.C1.PPB210.DATASTRM.G1280V00,DISP=SHR
  ''''''                    HUNTN.A1.C1.PPB210.DATASTRM.G1281V00 
  ''''''                    HUNTN.A1.C1.PPB210.DATASTRM.G1282V00
  ''''''                    HUNTN.A1.C1.PPB210.DATASTRM.G1283V00 
  ''''''                    HUNTN.A1.C1.PPB210.DATASTRM.G1284V00 
  ''''''                    HUNTN.A1.C1.PPB210.DATASTRM.G1285V00 

After pressing enter I have the datasets I want, but I still need to enter the // and the ,DISP=SHR on each line. Rather than typing it all in manually, I copy the data in with overlay as follows:

Copy the line with the desired data (‘C’) and overlay onto the lines that need the data (‘OO’):

  000008 //I1        DD DSN=HUNTN.A1.C1.PPB210.DATASTRM.G1279V00,DISP=SHR
  c00009 //          DD DSN=HUNTN.A1.C1.PPB210.DATASTRM.G1280V00,DISP=SHR
  oo0010                    HUNTN.A1.C1.PPB210.DATASTRM.G1281V00
  000011                    HUNTN.A1.C1.PPB210.DATASTRM.G1282V00
  000012                    HUNTN.A1.C1.PPB210.DATASTRM.G1283V00
  000013                    HUNTN.A1.C1.PPB210.DATASTRM.G1284V00
  oo0014                    HUNTN.A1.C1.PPB210.DATASTRM.G1285V00 

After pressing enter we have the desired result:

  000008 //I1        DD DSN=HUNTN.A1.C1.PPB210.DATASTRM.G1279V00,DISP=SHR
  000009 //          DD DSN=HUNTN.A1.C1.PPB210.DATASTRM.G1280V00,DISP=SHR
  000010 //          DD DSN=HUNTN.A1.C1.PPB210.DATASTRM.G1281V00,DISP=SHR
  000011 //          DD DSN=HUNTN.A1.C1.PPB210.DATASTRM.G1282V00,DISP=SHR
  000012 //          DD DSN=HUNTN.A1.C1.PPB210.DATASTRM.G1283V00,DISP=SHR
  000013 //          DD DSN=HUNTN.A1.C1.PPB210.DATASTRM.G1284V00,DISP=SHR
  000014 //          DD DSN=HUNTN.A1.C1.PPB210.DATASTRM.G1285V00,DISP=SHR

Note that the overlay occurs only within the current bounds settings. It is therefore possible to overlay only a specific subset of contiguous columns by first adjusting the bounds with the BNDS command.


Sort

The primary command SORT allows you to sort lines within your edited member according to the parameters that you specify.

Obviously, this has little or no use for editing Cobol programs. However, it can be very useful for manipulating data files.

The SORT command can be used together with labels, bounds, and specified columns. One can also specify multiple sort columns, ascending or descending.

Some examples:

SORT
Sorts all lines in ascending sequence.

SORT 3 10
Sort in ascending sequence on columns 3 through 10.

SORT .A .B
Sort all lines between and including the lines labeled .A and .B.

SORT 3 10 A 20 25 D
Sort on columns 3 through 10 in ascending sequence, and then on columns 20 through 25 in descending sequence.

SORT 30 35 D .A .B
Sort on columns 30 through 35 in descending sequence, but only from the line labeled .A through the line labeled .B. All other lines are left unsorted.

Or, first set bounds from columns 30 through 35 and then enter:
SORT D .A .B
This will sort in the same manner as the previous example.


Text Split, Text Flow, Text Entry

These commands have limited use for programming, but are very useful when entering text.

Text Split and Text Flow allow you to make an insertion in the middle of a body of text without having to restructure the entire body of text.

Consider the following text:

  000950 MANY KEY VALUES IN HUON ARE "ENCODED", MEANING THAT THEY ARE FLIPPED 
  000951 AROUND BY AN ALGORITHM BEFORE THEY ARE STORED IN THE DATABASE SUCH THAT
  000952 CONSECUTIVE KEY VALUES ARE NOT CONTIGUOUS. "ENCODED" VALUES CAN EASILY
  000953 BE "DECODED" BY READING THE VALUE BACKWARDS, STARTING FROM THE 
  000954 SECOND-TO-LAST DIGIT, AND THEN APPENDING THE LAST DIGIT. (A WORD OF 
  000955 CAUTION DOING THIS: THERE MAY BE EMBEDDED ZEROES THAT ARE SUPPRESSED AT
  000956 THE BEGINNING OF AN EDITED FIELD IN AN ENCODED NUMBER; THEREFORE YOU 
  000957 NEED TO KNOW HOW MANY DIGITS THERE ARE IN THE NUMBER). 

Suppose, for instance, that on line 951 we decide to insert the word “Huon” before the word “database.” Since there is no room for an extra word on line 951, we may need to retype the entire text just to make the extra word fit.

ISPF Text Split and Text Flow take care of this problem very neatly.

To insert the word, enter the line command TS and position your cursor at the point of insertion:

  000950 MANY KEY VALUES IN HUON ARE "ENCODED", MEANING THAT THEY ARE FLIPPED 
  ts0951 AROUND BY AN ALGORITHM BEFORE THEY ARE STORED IN THE DATABASE SUCH THAT
  000952 CONSECUTIVE KEY VALUES ARE NOT CONTIGUOUS. "ENCODED" VALUES CAN EASILY
  000953 BE "DECODED" BY READING THE VALUE BACKWARDS, STARTING FROM THE 
  000954 SECOND-TO-LAST DIGIT, AND THEN APPENDING THE LAST DIGIT. (A WORD OF 
  000955 CAUTION DOING THIS: THERE MAY BE EMBEDDED ZEROES THAT ARE SUPPRESSED AT
  000956 THE BEGINNING OF AN EDITED FIELD IN AN ENCODED NUMBER; THEREFORE YOU 
  000957 NEED TO KNOW HOW MANY DIGITS THERE ARE IN THE NUMBER). 

Press enter:

  000950 MANY KEY VALUES IN HUON ARE "ENCODED", MEANING THAT THEY ARE FLIPPED    
000951 AROUND BY AN ALGORITHM BEFORE THEY ARE STORED IN THE
......
000952 DATABASE SUCH THAT
000953 CONSECUTIVE KEY VALUES ARE NOT CONTIGUOUS. "ENCODED" VALUES CAN EASILY
000954 BE "DECODED" BY READING THE VALUE BACKWARDS, STARTING FROM THE
000955 SECOND-TO-LAST DIGIT, AND THEN APPENDING THE LAST DIGIT. (A WORD OF
000956 CAUTION DOING THIS: THERE MAY BE EMBEDDED ZEROES THAT ARE SUPPRESSED AT
000957 THE BEGINNING OF AN EDITED FIELD IN AN ENCODED NUMBER; THEREFORE YOU
000958 NEED TO KNOW HOW MANY DIGITS THERE ARE IN THE NUMBER).

The editor splits the line at the cursor position, inserts a new line, and places the rest of the text below. The cursor remains at the position following the word “the” on line 951.

Now type the word “Huon” and press enter:

  000950 MANY KEY VALUES IN HUON ARE "ENCODED", MEANING THAT THEY ARE FLIPPED    
000951 AROUND BY AN ALGORITHM BEFORE THEY ARE STORED IN THE HUON
000952 DATABASE SUCH THAT
000953 CONSECUTIVE KEY VALUES ARE NOT CONTIGUOUS. "ENCODED" VALUES CAN EASILY
000954 BE "DECODED" BY READING THE VALUE BACKWARDS, STARTING FROM THE
000955 SECOND-TO-LAST DIGIT, AND THEN APPENDING THE LAST DIGIT. (A WORD OF
000956 CAUTION DOING THIS: THERE MAY BE EMBEDDED ZEROES THAT ARE SUPPRESSED AT
000957 THE BEGINNING OF AN EDITED FIELD IN AN ENCODED NUMBER; THEREFORE YOU
000958 NEED TO KNOW HOW MANY DIGITS THERE ARE IN THE NUMBER).

The desired word has been inserted, but following text is unevenly spaced.

Now use the Text Flow function to restructure the following text. Enter the line command TF on line 951:

  000950 MANY KEY VALUES IN HUON ARE "ENCODED", MEANING THAT THEY ARE FLIPPED    
tf0951 AROUND BY AN ALGORITHM BEFORE THEY ARE STORED IN THE HUON
000952 DATABASE SUCH THAT
000953 CONSECUTIVE KEY VALUES ARE NOT CONTIGUOUS. "ENCODED" VALUES CAN EASILY
000954 BE "DECODED" BY READING THE VALUE BACKWARDS, STARTING FROM THE
000955 SECOND-TO-LAST DIGIT, AND THEN APPENDING THE LAST DIGIT. (A WORD OF
000956 CAUTION DOING THIS: THERE MAY BE EMBEDDED ZEROES THAT ARE SUPPRESSED AT
000957 THE BEGINNING OF AN EDITED FIELD IN AN ENCODED NUMBER; THEREFORE YOU
000958 NEED TO KNOW HOW MANY DIGITS THERE ARE IN THE NUMBER).

Press enter:

  000950 MANY KEY VALUES IN HUON ARE "ENCODED", MEANING THAT THEY ARE FLIPPED   
000951 AROUND BY AN ALGORITHM BEFORE THEY ARE STORED IN THE HUON DATABASE SUCH
000952 THAT CONSECUTIVE KEY VALUES ARE NOT CONTIGUOUS. "ENCODED" VALUES CAN
000953 EASILY BE "DECODED" BY READING THE VALUE BACKWARDS, STARTING FROM THE
000954 SECOND-TO-LAST DIGIT, AND THEN APPENDING THE LAST DIGIT. (A WORD OF
000955 CAUTION DOING THIS: THERE MAY BE EMBEDDED ZEROES THAT ARE SUPPRESSED AT
000956 THE BEGINNING OF AN EDITED FIELD IN AN ENCODED NUMBER; THEREFORE YOU
000957 NEED TO KNOW HOW MANY DIGITS THERE ARE IN THE NUMBER).

The spacing in the text has been restructured.

Please note that TS and TF only work within the current bounds settings.

Using TS and TF with PFKeys

When Text Split and Text Flow are set up as PFKeys, the effect is quite dramatic. With PFKey commands, you do not need to move the cursor over to the line command area and type in the TS and TF commands. Instead, just “point and click” by positioning the cursor at the desired insertion point, pressing the “TS” PFKey, typing your new text, and then pressing the “TF” PFKey. Your new word is inserted and the following text restructured, without having to reposition your cursor and without having to type in line commands.

Note: line commands are distinguished from primary commands on the Keylist panels by preceding them with a colon.

Text Entry

The Text Entry line command allows you to type in a continual stream of text, much like a word processor. You don’t have to worry about adding new lines or tabbing down to a new line when you run out of room. As soon as you press enter, the text you have entered is formatted into a paragraph within the columns set by the BNDS command. If no columns were set by the BNDS command, the text is formatted into a paragraph extending from column 1 through 80.

To use Text Flow:

First enter a BNDS command, e.g., BNDS 1 72

Next, select the line where you want text entry to begin by typing in the line command TE. Press enter.

Begin typing text. Pay no attention to where words begin or end, i.e., you may split the same word between two lines while typing.

When finished, press enter. The ISPF editor will reformat what you have typed into a paragraph within columns 1 through 72, beginning from the line where the TE was entered.


Miscellaneous Items

If you have been using ISPF for a while, you are probably already aware of the following:

Always use split screens.

This allows you to have two or more concurrent ISPF screens.

Create split screens by pressing PF2. This creates a second screen beginning at the current cursor position. To create “full” screens, position your cursor at the very top or very bottom of the display and press PF2.

Another way of creating a new screen is entering the primary command START. (Note that there is a bug in the current version of ISPF which allows the START command to remain on the command line of the “starting” screen. When toggling back to this “starting” screen, ISPF does not recognize the residue command and flashes an error message.)

Toggle between split screens using PF9 (‘SWAP’).

Always use jump commands when going from one panel to another.

Jump commands are primary commands which are preceded by an equal sign. This allows you to move directly from one panel to another without having to return to the primary option menu. For example, from SDSF I can go directly to 3.4 by entering ‘=3.4”.

Always stack commands wherever possible.

Stacking commands saves you keystrokes and allows you to enter a series of commands without having to press “enter” after each command.

Commands are stacked by separating them with a semicolon (;).

Using stack commands is most useful when the system is running slowly. With one “enter” one can send a series of commands to the CPU without having to wait for the screen to come back.


Review and Examples

Once you have learned the tools described in this document, you can use them individually or in combination to solve a variety of common editing problems.

The following examples describe various kinds of edit situations along with suggested methods of solving them in the most efficient manner.

Example 1

I am working on a large Cobol program and need to use a certain dataname that I had used in another paragraph. I don’t remember the dataname or the paragraph, but I do remember that it was built by moving DATANAME2 to it. However, I don’t want to do a ‘FIND’ on DATANAME2, because it occurs hundreds of times in the program. How do I find the dataname I am looking for?

Best solution:

First I put a “bookmark” at my current location by labeling the line .A. This allows me to return back to this spot with PF22 after I have found what I am looking for.

Next I position the cursor at the command line and type DATANAME2 and press PF21 (‘EX ALL;F ALL’). All lines of text are excluded except for those containing DATANAME2.

Next I page through the program until I find the line where my desired data name is built. With all extraneous lines excluded from the program, the paging should go very quickly. When I find the desired dataname I can copy it with the cursor, or I can label this line .B.

Next I press PF24 (‘CURSOR;RESET’) to restore the display, followed by PF22 (‘L .A;UP 5’) to return to my starting location.

If I have copied the desired dataname with the cursor, I can paste it onto the line that I am working on. Or, if I set label .B, I can flip back to the line with the desired dataname by pressing PF23 (‘L .B;UP 5’).


Example 2

I am researching a large, tedious Cobol program and have come upon a line of code that interests me. I need to know the name of the paragraph in which this line of code resides. Unfortunately, the paragraph is very long and I don’t want to waste time paging backwards to find the beginning of the paragraph.

How do I find the paragraph name?

Best solution:

First I put label .A on the current line.

.A                IF BSM-SUB-W81 > ZERO 
004139                MOVE HID-INSURED1-FORMATTED-NAME
004140                                        TO HID-BILL-INS-NAME1-FORMATTED
004141                MOVE HID-INSURED2-FORMATTED-NAME
004142                                        TO HID-BILL-INS-NAME2-FORMATTED
004143                MOVE HID-INSURED-ADDR1  TO HID-BILL-INS-ADDR1-FORMATTED
004144                MOVE HID-INSURED-ADDR2  TO HID-BILL-INS-ADDR2-FORMATTED
004145                MOVE HID-INSURED-CITY   TO HID-BILL-INS-CITY
004146                MOVE HID-INSURED-STATE  TO HID-BILL-INS-STATE
004147                MOVE HID-INSURED-ZIP    TO HID-BILL-INSURED-ZIP
004148                MOVE SPACES             TO HID-BILL-INS-ZIP-PLUS4
004149                PERFORM WEA-SCANLINE
004150                MOVE SCANLINE-WORK-W810 TO HID-BILL-SCAN-LINE
004151            END-IF.

Next I press PF20 (‘EX ALL;F P'^' 8 ALL;EX '*' ALL 7’), which excludes all lines except for paragraph names in the procedure division (and 01 levels in working storage).

- - -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  2 Line(s) not Displayed 
002945 PROCEDURE DIVISION.
- - - - - - - - - - - - - - - - - - - 2 Line(s) not Displayed
002948 A-MAINLINE SECTION.
- - - - - - - - - - - - - - - - - - - 2 Line(s) not Displayed
002951 A000-START.
- - - - - - - - - - - - - - - - - - - 44 Line(s) not Displayed
002996 A-PROCESS SECTION.
- - - - - - - - - - - - - - - - - - - 1 Line(s) not Displayed
002998 A000-START.
- - - - - - - - - - - - - - - - - - - 64 Line(s) not Displayed
003063 A000-EXIT.
- - - - - - - - - - - - - - - - - - - 2 Line(s) not Displayed
003066 B-PROCESS SECTION.
- - - - - - - - - - - - - - - - - - - 1 Line(s) not Displayed
003068 B000-START.
- - - - - - - - - - - - - - - - - - - 80 Line(s) not Displayed
003149 B000-EXIT.
- - - - - - - - - - - - - - - - - - - 2 Line(s) not Displayed
003152 B010-RENWL SECTION.

Next I press PF22 (‘L .A;UP 5’). This locates the line that I have labeled .A, and then scrolls up five lines.

- - -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  2 Line(s) not Displayed 
003821 DZ-COMMON-BREAK SECTION.
- - - - - - - - - - - - - - - - - - - 1 Line(s) not Displayed
003823 DZ000-START.
- - - - - - - - - - - - - - - - - - 314 Line(s) not Displayed
.A IF BSM-SUB-W81 > ZERO
- - - - - - - - - - - - - - - - - - 120 Line(s) not Displayed
004259 DZ000-EXIT.
- - - - - - - - - - - - - - - - - - - 3 Line(s) not Displayed
004263 E300-DUMMY-AMEND SECTION.
- - - - - - - - - - - - - - - - - - - 2 Line(s) not Displayed
004266 E300A-START.
- - - - - - - - - - - - - - - - - - - 44 Line(s) not Displayed
004311 E300A-EXIT.
- - - - - - - - - - - - - - - - - - - 3 Line(s) not Displayed
004315 G100-PROCESS-DEC-END SECTION.
- - - - - - - - - - - - - - - - - - - 1 Line(s) not Displayed
004317 G100A-START.
- - - - - - - - - - - - - - - - - - - 43 Line(s) not Displayed
004361 G100A-EXIT.

The line that I have labeled .A now stands out prominently, sandwiched between two paragraph names. The paragraph name on top is of course the paragraph name that I am looking for. (In the specific example above, the name we are looking for is the section name, which often requires us to look back one or more lines.)

After noting the paragraph name I press PF24 (‘CURSOR;RESET’) which restores the display, followed by PF22 (‘L .A;UP 5’) which positions me back to where I had started.

004133       *
004134 *---------------------------------------------------------------
004135 *MOVE THE INSURE NAME ADDRESS TO THE BILLING AREA FOR RENEWAL
004136 *RBILL.
004137 *---------------------------------------------------------------
.A IF BSM-SUB-W81 > ZERO
004139 MOVE HID-INSURED1-FORMATTED-NAME
004140 TO HID-BILL-INS-NAME1-FORMATTED
004141 MOVE HID-INSURED2-FORMATTED-NAME
004142 TO HID-BILL-INS-NAME2-FORMATTED
004143 MOVE HID-INSURED-ADDR1 TO HID-BILL-INS-ADDR1-FORMATTED
004144 MOVE HID-INSURED-ADDR2 TO HID-BILL-INS-ADDR2-FORMATTED
004145 MOVE HID-INSURED-CITY TO HID-BILL-INS-CITY
004146 MOVE HID-INSURED-STATE TO HID-BILL-INS-STATE
004147 MOVE HID-INSURED-ZIP TO HID-BILL-INSURED-ZIP
004148 MOVE SPACES TO HID-BILL-INS-ZIP-PLUS4
004149 PERFORM WEA-SCANLINE
004150 MOVE SCANLINE-WORK-W810 TO HID-BILL-SCAN-LINE
004151 END-IF.

I have found the paragraph name and come back again, simply by entering a label and then pressing three PFKeys in succession! This method is fast, efficient, and reliable; no paging, no searching, no waiting.

 

Example 3

I want to blank out everything found in columns 73 through 80.

Best solution:

Enter the following command and press enter:

C P'^' ' ' 73 80 ALL

 

Example 4

I am working on a member in ISPF which has mixed upper and lower case characters. I want to convert all lower case characters to upper case.

Solution:

Enter the following command and press enter:

C P'<' P'>' ALL

Or

Enter UCC in the line command area of the top line, max to the bottom of the member, and enter UCC in the line command area of the last line. Press enter.

 

Example 5

I am editing a data file which has been corrupted by records which have a value of ‘1’ in column 49. I need to delete all records from the file that have this value ‘1’ in column 49. However, there are thousands of records in the file, and it will take too long to find and delete them all individually.

Best solution:

Type the following command and press enter:

X 49 '1' ALL;DEL X ALL

The above stacked command does the following:

1. excludes all lines which contain the value ‘1’ in column 49
2. deletes all lines which are excluded

 

Example 6

I have run a Spufi and created an output dataset with record length 80. I would like to convert this spufi output dataset into a generic file which I can download into Excel or Access. In order to do this, I need to strip out all lines that contain headings, titles, and other extraneous information. I could do it manually, line by line, but the output dataset is quite large.

The top of the dataset looks like this:

000001 ---------+---------+---------+---------+---------+---------+----
000002 SELECT * FROM HUND2.DOCEXT                                              
000003 WITH UR;
000004 ---------+---------+---------+---------+---------+---------+----
000005 COMPANY DOCUMENT EXTLEVEL RECTYPE ACTIVTO ACTIVFROM
000006 ---------+---------+---------+---------+---------+---------+----
000007 1 AMEND2005 TZS043 99999999 19900101
000008 1 AMEND2010 POL TZS042 99999999 19900101
000009 1 AMEND2020 POL TZS001 99999999 19900101
000010 1 AMEND2030 POL TZS003 99999999 19900101
000011 1 AMEND2040 POL TZS018 99999999 19900101
000012 1 AMEND2050 POL TZS040 99999999 19900101
000013 1 AMEND2055 TZS043 99999999 19900101

and the bottom looks like this:

000314       1  TRNPL5010  POL       TZS001       99999999     19900101 
000315 1 TRNPL5020 POL TZS003 99999999 19900101
000316 1 TRNPL5030 POL TZS005 99999999 19900101
000317 1 TRNPL5040 TZS004 99999999 19900101
000318 1 TRNPL5055 POL TZS008 99999999 19900101
000319 1 TRNPL5060 POL TZS041 99999999 19900101
000320 1 TRNPL5070 POL TZS018 99999999 19900101
000321 1 TRNPL5080 POL TZS043 99999999 19900101
000322 DSNE610I NUMBER OF ROWS DISPLAYED IS 305
000323 DSNE616I STATEMENT EXECUTION WAS SUCCESSFUL, SQLCODE IS 100
000324 ---------+---------+---------+---------+---------+---------+----
000325 ---------+---------+---------+---------+---------+---------+----
000326 DSNE617I COMMIT PERFORMED, SQLCODE IS 0
000327 DSNE616I STATEMENT EXECUTION WAS SUCCESSFUL, SQLCODE IS 0
000328 ---------+---------+---------+---------+---------+---------+----
000329 DSNE601I SQL STATEMENTS ASSUMED TO BE BETWEEN COLUMNS 1 AND 72
000330 DSNE620I NUMBER OF SQL STATEMENTS PROCESSED IS 1
000331 DSNE621I NUMBER OF INPUT RECORDS READ IS 2
000332 DSNE622I NUMBER OF OUTPUT RECORDS WRITTEN IS 332

How do I eliminate the unwanted lines?

Solution:

First of all, by looking at the output I can see that I am not interested in any line that contains a non-space value in column 3. (Column 3 is chosen here at random; I could just as well have chosen column 1).

Therefore, I enter the following command:

X 3 P'^' ALL

This excludes all non-space lines in column 3. The first page of my display now looks like this:

- - -  -  -  -  -  -  -  -  - -  -  -  -  -  6 Line(s) not Displayed
000007 1 AMEND2005 TZS043 99999999 19900101
000008 1 AMEND2010 POL TZS042 99999999 19900101
000009 1 AMEND2020 POL TZS001 99999999 19900101
000010 1 AMEND2030 POL TZS003 99999999 19900101
000011 1 AMEND2040 POL TZS018 99999999 19900101
000012 1 AMEND2050 POL TZS040 99999999 19900101
000013 1 AMEND2055 TZS043 99999999 19900101
000014 1 AMEND2060 TZS006 99999999 19900101
000015 1 AMEND2070 POL TZS005 99999999 19900101
000016 1 AMEND2080 POL TZS012 99999999 19900101
000017 1 AMEND2090 TZS004 99999999 19900101
000018 1 AMEND2100 POL TZS007 99999999 19900101

By spot checking the result, I am reasonably certain that most (if not all) of the unwanted lines have been excluded.

Next I delete all excluded lines by the following command:

DEL X ALL

Examining the first few pages of the result, along with the bottom of the file, I am now certain that all of the unwanted lines have been stripped out. I am now finished.

000001       1  AMEND2005            TZS043       99999999     19900101  
000002 1 AMEND2010 POL TZS042 99999999 19900101
000003 1 AMEND2020 POL TZS001 99999999 19900101
000004 1 AMEND2030 POL TZS003 99999999 19900101
000005 1 AMEND2040 POL TZS018 99999999 19900101
000006 1 AMEND2050 POL TZS040 99999999 19900101
000007 1 AMEND2055 TZS043 99999999 19900101
000008 1 AMEND2060 TZS006 99999999 19900101
000009 1 AMEND2070 POL TZS005 99999999 19900101
000010 1 AMEND2080 POL TZS012 99999999 19900101

But wait – now I have decided that I want to modify the resulting file such that all the data is left-justified with only one intervening space between data columns. How do I do that?

Solution:

My first problem is to verify that the first data column is only one digit in length. This would appear to be the case, but I want to make sure. Therefore, I first identify the column number where the data appears, by entering the COLS command as follows:

cols01       1  AMEND2005            TZS043       99999999     19900101  
000002 1 AMEND2010 POL TZS042 99999999 19900101
000003 1 AMEND2020 POL TZS001 99999999 19900101
000004 1 AMEND2030 POL TZS003 99999999 19900101
000005 1 AMEND2040 POL TZS018 99999999 19900101
000006 1 AMEND2050 POL TZS040 99999999 19900101
000007 1 AMEND2055 TZS043 99999999 19900101
000008 1 AMEND2060 TZS006 99999999 19900101
000009 1 AMEND2070 POL TZS005 99999999 19900101
000010 1 AMEND2080 POL TZS012 99999999 19900101

Press enter:

=COLS> ----+----1----+----2----+----3----+----4----+----5----+----6----
000001 1 AMEND2005 TZS043 99999999 19900101
000002 1 AMEND2010 POL TZS042 99999999 19900101
000003 1 AMEND2020 POL TZS001 99999999 19900101
000004 1 AMEND2030 POL TZS003 99999999 19900101
000005 1 AMEND2040 POL TZS018 99999999 19900101
000006 1 AMEND2050 POL TZS040 99999999 19900101
000007 1 AMEND2055 TZS043 99999999 19900101
000008 1 AMEND2060 TZS006 99999999 19900101
000009 1 AMEND2070 POL TZS005 99999999 19900101
000010 1 AMEND2080 POL TZS012 99999999 19900101

The ‘1’ is in column 7. So I now determine whether there is any data in columns 1 through 6 by entering the following command:

F 1 6 P'^' ALL 

The result is as expected: there is no non-space data found in columns 1 through 6.

Now I shift all columns over 6 to the left with the block-shift line commands, the first entered on the top line, and the last entered on the last line:

=COLS> ----+----1----+----2----+----3----+----4----+----5----+----6----
((6 01 1 AMEND2005 TZS043 99999999 19900101
000002 1 AMEND2010 POL TZS042 99999999 19900101
000003 1 AMEND2020 POL TZS001 99999999 19900101
000004 1 AMEND2030 POL TZS003 99999999 19900101
000005 1 AMEND2040 POL TZS018 99999999 19900101
000006 1 AMEND2050 POL TZS040 99999999 19900101
000007 1 AMEND2055 TZS043 99999999 19900101
000008 1 AMEND2060 TZS006 99999999 19900101
000009 1 AMEND2070 POL TZS005 99999999 19900101
000010 1 AMEND2080 POL TZS012 99999999 19900101
.
.
.
000299 1 TRNPL5020 POL TZS003 99999999 19900101
000300 1 TRNPL5030 POL TZS005 99999999 19900101
000301 1 TRNPL5040 TZS004 99999999 19900101
000302 1 TRNPL5055 POL TZS008 99999999 19900101
000303 1 TRNPL5060 POL TZS041 99999999 19900101
000304 1 TRNPL5070 POL TZS018 99999999 19900101
(( 305 1 TRNPL5080 POL TZS043 99999999 19900101
****** **************************** Bottom of Data ********************

Press enter. The result is as follows:

=COLS> ----+----1----+----2----+----3----+----4----+----5----+---
000001 1 AMEND2005 TZS043 99999999 19900101
000002 1 AMEND2010 POL TZS042 99999999 19900101
000003 1 AMEND2020 POL TZS001 99999999 19900101
000004 1 AMEND2030 POL TZS003 99999999 19900101
000005 1 AMEND2040 POL TZS018 99999999 19900101
000006 1 AMEND2050 POL TZS040 99999999 19900101
000007 1 AMEND2055 TZS043 99999999 19900101
000008 1 AMEND2060 TZS006 99999999 19900101
000009 1 AMEND2070 POL TZS005 99999999 19900101
000010 1 AMEND2080 POL TZS012 99999999 19900101

By examining the other data columns according to the method described above, I determine that the data can be shifted over as meets the eye on the first page. (Or, if I know the data beforehand and know the column lengths of the table I am working with, I don’t need to bother checking length of possible data values).

I can now shift over each column successively according to the following method:

The second data column should start in column 3. Therefore I need to shift it over to the left one column, without disturbing the data in column 1. This can be accomplished by first setting the bounds from column 3 to 80:

BNDS 3 80

and then entering the block-shift command to shift over one column to the left:

=COLS> ----+----1----+----2----+----3----+----4----+----5----+---
((1 01 1 AMEND2005 TZS043 99999999 19900101
000002 1 AMEND2010 POL TZS042 99999999 19900101
000003 1 AMEND2020 POL TZS001 99999999 19900101
000004 1 AMEND2030 POL TZS003 99999999 19900101
000005 1 AMEND2040 POL TZS018 99999999 19900101
000006 1 AMEND2050 POL TZS040 99999999 19900101
000007 1 AMEND2055 TZS043 99999999 19900101
000008 1 AMEND2060 TZS006 99999999 19900101
000009 1 AMEND2070 POL TZS005 99999999 19900101
000010 1 AMEND2080 POL TZS012 99999999 19900101
.
.
.
000299 1 TRNPL5020 POL TZS003 99999999 19900101
000300 1 TRNPL5030 POL TZS005 99999999 19900101
000301 1 TRNPL5040 TZS004 99999999 19900101
000302 1 TRNPL5055 POL TZS008 99999999 19900101
000303 1 TRNPL5060 POL TZS041 99999999 19900101
000304 1 TRNPL5070 POL TZS018 99999999 19900101
(( 305 1 TRNPL5080 POL TZS043 99999999 19900101
****** **************************** Bottom of Data ***************

The result is as follows:

=COLS> ----+----1----+----2----+----3----+----4----+----5----+---
000001 1 AMEND2005 TZS043 99999999 19900101
000002 1 AMEND2010 POL TZS042 99999999 19900101
000003 1 AMEND2020 POL TZS001 99999999 19900101
000004 1 AMEND2030 POL TZS003 99999999 19900101
000005 1 AMEND2040 POL TZS018 99999999 19900101
000006 1 AMEND2050 POL TZS040 99999999 19900101
000007 1 AMEND2055 TZS043 99999999 19900101
000008 1 AMEND2060 TZS006 99999999 19900101
000009 1 AMEND2070 POL TZS005 99999999 19900101
000010 1 AMEND2080 POL TZS012 99999999 19900101

Now for the remaining data columns I use the same method, each time resetting the bounds to begin at the left margin where I want the new data column to be moved, and setting the right bounds at column 80.

Eventually I have my desired result:

Short cut:

If I am absolutely certain that the data columns always contain non-space data of uniform length, then I do not need to calculate the distance the data column needs to shift over to the left. Instead, I can use the following block-shift command which works a bit differently:

<<80
  .
.
.
<<

Using << instead of (( shifts data over the specified number of columns, but stops shifting as soon as it reaches one column before a non-space character, or reaches one column before the left bounds. Therefore, first set the left bounds to begin at the column of spaces that will intervene between the data column you want to shift and the last data column that has shifted. Then enter <<80 on the top line command area, and << in the bottom line command area. Press enter. By specifying the argument 80, the data (within the current bounds) is shifted 80 columns to the left until it “hits” something, in this case, one space before the neighboring data column. Since the shifting stops one column before a non-space “obstacle”, we have our desired result and no other adjustments are necessary.

 

Example 7

I would like to know whether John Doe is in the office working on his terminal. John Doe’s TSO userid is CS0999. Rather than getting up and walking over to his desk on the other side of the room, I go to the ISPF primary option menu and press PF18. This displays all active TSO sessions which begin with CS0.

SDSF DA SYSB  SYSB     PAG    0 SIO  1738 CPU 100/ 93  LINE 1-18 (79)          
COMMAND INPUT ===> SCROLL ===> CSR
PREFIX=CS* DEST=(ALL) OWNER=* SORT=JOBNAME/A
NP JOBNAME StepName ProcStep JobID Owner C Pos DP PGN Real Paging S
CS0003 ATSO TERM0155 TSU01536 CS0003 LO FF 2 439 0.00 0.
CS0009 ATSO TERM0155 TSU01221 CS0009 IN 7E 2 1067 0.00 0.
CS0010 ATSO TERM0155 TSU01419 CS0010 LO FF 2 1910 0.00 0.
CS0014 ATSO TERM0155 TSU01562 CS0014 LO FF 2 695 0.00 0.
CS0021 ATSO TERM0155 TSU00982 CS0021 LO FF 2 1398 0.00 0.
CS0025 ATSOAI TERM0155 TSU01039 CS0025 LO FF 2 742 0.00 0.
CS0026 ATSO TERM0155 TSU01250 CS0026 LO FF 2 600 0.00 0.
CS0033 ATSO TERM0155 TSU01209 CS0033 LO FF 2 1051 0.00 0.
CS0037 ATSO TERM0155 TSU01099 CS0037 LO FF 2 731 0.00 0.
CS0052 ATSO TERM0155 TSU01449 CS0052 LO FF 2 884 0.00 0.
CS0057 ATSO TERM0155 TSU01557 CS0057 LO FF 2 365 0.00 0.
CS0064 ATSOALOC TERM0155 TSU01224 CS0064 LO FF 2 871 0.00 0.
CS0066 ATSOALOC TERM0155 TSU01173 CS0066 LO FF 2 630 0.00 0.

By paging down I can see whether CS0999 is logged on or not. If CS0999 is currently executing a unit of work on TSO, the line will be highlighted.

If the line is not highlighted and does not seem to be clocking when I refresh the display, then it is possible that John Doe is at his desk doing something else, or has walked away from his desk. If I want to see his most recent activity, or when he logged onto the system, I can go to the SYSLOG by pressing PF16:

SDSF SYSLOG  3532.104 SYSB SYSB 05/09/2002 5W    77,621     COL
COMMAND INPUT ===> S
14:03:01.61 JOB01689 00000090 CS0404V -------- COMPLST (SERCO
14:03:02.18 INSTREAM 00000290 LOGON
14:03:02.69 TSU01705 00000090 $HASP100 CS0112 ON TSOINRDR
14:03:02.73 TSU01708 00000090 $HASP100 CS0436 ON TSOINRDR
14:03:03.04 TSU01705 00000091 $HASP373 CS0112 STARTED
14:03:03.07 TSU01705 00000091 IEF125I CS0112 - LOGGED ON - TIME
14:03:03.12 TSU01708 00000091 $HASP373 CS0436 STARTED
14:03:03.14 TSU01708 00000091 IEF125I CS0436 - LOGGED ON - TIME
14:03:04.02 STC07752 00000290 SEND 'CMN9800I - HUNA002048 compo
14:03:03.',USER=(CS0021),LOGON
14:03:04.29 JOB01687 00000090 CS0021AE -------- FAILURE (CMNBA
14:03:04.45 JOB01689 00000090 IEF404I CS0404V - ENDED - TIME=14
14:03:04.47 JOB01689 00000090 $HASP395 CS0404V ENDED
14:03:05.43 00000091 $HASP309 INIT B INACTIVE *****
14:03:05.45 INTERNAL 00000290 SE '14.03.05 JOB01689 $HASP165 CS
USER=(CS0404)
14:03:06.03 JOB01704 00000090 CS0159Z -------- WRITE (CMNWR
14:03:06.84 JOB01697 00000090 CS0193G STGFORM COPY (VLMMA
14:03:07.04 JOB01697 00000090 CS0193G STGFORM SETB (TSGPA

From here I can enter the command ‘F CS0999 PREV’ to find the most recent activity logged on the system under TSOID CS0999. If I do not find CS0999 on the first try, I press PF5 until I find him or until I reach the top of the log:

SDSF SYSLOG  3532.110 SYSB SYSB 05/17/2002 6W    73,256 CHARS 'CS0999' FOUND 
COMMAND INPUT ===> SCROLL ===> CSR
13:11:39.87 TSU09436 00000091 IEF125I CS0999 - LOGGED ON - TIME=13.11.39
13:11:39.93 TSU09437 00000091 $HASP373 CS0356 STARTED
13:11:39.97 TSU09437 00000091 IEF125I CS0356 - LOGGED ON - TIME=13.11.39
13:11:41.94 STC03632 00000091 VPS351N P0310131 RELEASE REQUEST ACKNOWLEDGED
13:11:43.31 JOB09432 00000090 CS0190Z -------- COBOLLDB (IGYCRCTL) 0000
13:11:43.49 STC03632 00000091 VPS225I P0310131 NOW RELEASED
13:11:44.51 STC03631 00000090 TSS7100E 010 J=VTP A=DC0085 T=TNA12118 F=VTP -
13:11:44.51 STC03631 00000091 KLVNA104 CURRENT PASSWORD EXPIRED:
TERM(TNA12118) APPL(VTP01)
13:11:47.93 JOB09433 00000091 $HASP250 E625242P PURGED -- (JOB KEY WAS
13:11:53.05 STC03632 00000091 VPS351N Y114B1F8 RELEASE REQUEST ACKNOWLEDGED
13:11:53.69 STC03632 00000091 VPS225I Y114B1F8 NOW RELEASED
13:11:55.84 STC03631 00000091 KLVOP314 COMMAND ISSUED
13:11:59.41 INSTREAM 00000290 LOGON
13:12:00.31 TSU09439 00000090 $HASP100 DC0085 ON TSOINRDR
13:12:00.50 INSTREAM 00000290 LOGON
13:12:00.71 TSU09439 00000091 $HASP373 DC0085 STARTED
13:12:00.74 TSU09439 00000091 IEF125I DC0085 - LOGGED ON - TIME=13.12.00
13:12:00.96 TSU09441 00000090 $HASP100 CS0217 ON TSOINRDR
13:12:01.13 SYSB$001 00000290 D R,L

On this display I see that CS0999 logged on at 13:11.

 

Example 8

(Note: This example assumes that the primary command for going to SDSF is 8. Modify as needed for your shop.)

I have submitted a job from ISPF edit and now wish to switch over to SDSF to watch the job run.

I of course can enter the jump command:

=8.da ojob

or

=8.da ojob;pre CS0355*

but this involves a lot of keystrokes.

Instead, using the PFKey settings as recommended earlier in this document, I can press PF4 (which returns me to the primary option menu) and then PF19 (which takes me to SDSF and displays all active jobs with my TSOID prefix). This involves only two keystrokes.

 

Example 9

I am working on a program which moves various error codes to a field called ERR-CODE-W83. I need to have a list of all the error codes used in this program. Since the error codes are numeric, I would also like to know what codes, if any, are being skipped, and what the next available code is.

Solution:

The final result will be a member containing only a list of sorted error codes. Since I will be deleting lines from the program, the first step should be to copy the program into a temporary work member. This is not absolutely necessary, as long as I remember to cancel out when I am finished.

The first step in obtaining the sorted list of error codes is to do an “ex all find all” on the data name ERR-CODE-W83. Enter ERR-CODE-W83 on the primary command line and press PF21. The result is a member that looks something like this:

- - -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -   658 Line(s) not Displayed
000659 15 ERR-CODE-W83 PIC 9(03).
- - - - - - - - - - - - - - - - - - 1283 Line(s) not Displayed
001943 MOVE 140 TO ERR-CODE-W83 (ERR-SUB-W83)
- - - - - - - - - - - - - - - - - - - 29 Line(s) not Displayed
001973 MOVE 141 TO ERR-CODE-W83 (ERR-SUB-W83)
- - - - - - - - - - - - - - - - - - - 8 Line(s) not Displayed
001982 MOVE 142 TO ERR-CODE-W83 (ERR-SUB-W83)
- - - - - - - - - - - - - - - - - - - 37 Line(s) not Displayed
002020 MOVE 144 TO ERR-CODE-W83 (ERR-SUB-W83)
- - - - - - - - - - - - - - - - - - - 95 Line(s) not Displayed
002116 MOVE 144 TO ERR-CODE-W83 (ERR-SUB-W83)
- - - - - - - - - - - - - - - - - - - 55 Line(s) not Displayed
002172 MOVE 221 TO ERR-CODE-W83 (ERR-SUB-W83)
- - - - - - - - - - - - - - - - - - - 40 Line(s) not Displayed
002213 MOVE 145 TO ERR-CODE-W83 (ERR-SUB-W83)
- - - - - - - - - - - - - - - - - - 120 Line(s) not Displayed
002334 MOVE 146 TO ERR-CODE-W83 (ERR-SUB-W83)

I am now interested only in lines which say “MOVE xxx”. All other lines can be deleted. The safest way to do this is to page through the whole member and delete unwanted lines manually. I could, of course, enter the command “DEL X ALL”, but in so doing I risk accidentally deleting a “MOVE” in those few cases where the “MOVE” and the “TO” are split on two different lines.

For those lines where the MOVE is split, display the line above the ERR-CODE-W83 using the “L1” line command as described in the section Excluding Lines of Text.

In our particular example, however, we find that none of the MOVE lines are split.

After manually deleting the unwanted lines, delete all excluded lines by entering:

DEL X ALL

The member now looks like this:

000001                    MOVE 140            TO ERR-CODE-W83 (ERR-SUB-W83) 
000002 MOVE 141 TO ERR-CODE-W83 (ERR-SUB-W83)
000003 MOVE 142 TO ERR-CODE-W83 (ERR-SUB-W83)
000004 MOVE 144 TO ERR-CODE-W83 (ERR-SUB-W83)
000005 MOVE 144 TO ERR-CODE-W83 (ERR-SUB-W83)
000006 MOVE 221 TO ERR-CODE-W83 (ERR-SUB-W83)
000007 MOVE 145 TO ERR-CODE-W83 (ERR-SUB-W83)
000008 MOVE 146 TO ERR-CODE-W83 (ERR-SUB-W83)
000009 MOVE 147 TO ERR-CODE-W83 (ERR-SUB-W83)
000010 MOVE 146 TO ERR-CODE-W83 (ERR-SUB-W83)
000011 * MOVE 010 TO ERR-CODE-W83 (ERR-SUB-W83)
000012 MOVE 146 TO ERR-CODE-W83 (ERR-SUB-W83)
000013 MOVE 146 TO ERR-CODE-W83 (ERR-SUB-W83)
000014 MOVE 147 TO ERR-CODE-W83 (ERR-SUB-W83)
000015 * MOVE 010 TO ERR-CODE-W83 (ERR-SUB-W83)
000016 MOVE 001 TO ERR-CODE-W83 (ERR-SUB-W83)
000017 MOVE 002 TO ERR-CODE-W83 (ERR-SUB-W83)
000018 MOVE 003 TO ERR-CODE-W83 (ERR-SUB-W83)

If I haven’t already done it, I now exclude and delete all lines with asterisk in column 7:

X 7 '*' ALL;DEL X ALL

And now I begin stripping down the resulting member with a series of “change” commands until all that is left is the error code:

C 'MOVE' ' ' ALL


C 'TO ERR-CODE-W83' ' ' ALL


C '(ERR-SUB-W83)' ' ' ALL

Examining the result I find that nearly all extraneous data has been removed from the member. In this example, there are a few lines at the bottom of the listing which have a hard-coded subscript, and I can fix these lines manually.

==CHG>                      140             
==CHG> 141
==CHG> 142
==CHG> 144
==CHG> 144
==CHG> 221
==CHG> 145
==CHG> 146
==CHG> 147
==CHG> 146
==CHG> 146
==CHG> 146
==CHG> 147
==CHG> 001
==CHG> 002
==CHG> 003
==CHG> 004
==CHG> 005

The result is now a member that contains only error codes. However, the error codes are not only unsorted, but scattered in different columns.

I must now align all the error codes into the same column. This is easily accomplished by the << block command, as follows:

Enter <<80 on the top line, and << on the bottom line:

<<80 >                      140            
==CHG> 141
==CHG> 142
==CHG> 144
==CHG> 144
==CHG> 221
==CHG> 145
==CHG> 146
==CHG> 147
==CHG> 146
==CHG> 146
==CHG> 146
==CHG> 147
==CHG> 001
==CHG> 002
==CHG> 003
==CHG> 004
==CHG> 005
.
.
.
==CHG> 125
==CHG> 124
==CHG> 125
==CHG> 124
==CHG> 125
==CHG> 152
==CHG> 152
==CHG> 152
<<CHG> 152
****** **************************** Bottom of Data **

Press enter:

(Ignore the resulting error message “DATA SHIFTING INCOMPLETE”, which tells us that not all lines could be shifted the entire 80 columns to the left).

All data is now aligned in column 2.

Now sort the member with the SORT command:

SORT
==ERR>  001         
==ERR> 002
==ERR> 003
==ERR> 004
==ERR> 005
==ERR> 006
==ERR> 007
==ERR> 008
==ERR> 009
==ERR> 011
==ERR> 012
==ERR> 014
==ERR> 015
==ERR> 016
==ERR> 017
==ERR> 018
==ERR> 019
==ERR> 020

I now have the desired result. I can now page through the list and find numbers that are repeated or skipped. The last line of course shows me the highest value used.


Dimensions, ch.1 | Dimensions, ch.2 | Dimensions, ch.3 | Dimensions, ch.4 | Dimensions, ch.5 | Hypercube formula | Decimals of Primes | Visual Definition of Primes | Calculator Trick | Decimal Equivalents of Fractions | Mental Calendar Trick | Kaleidodigit | Sudoku Cobol | Math | Home Page


Copyright 2008 by Bill Price