IBM Mainframe Forum Index
 
Log In
 
IBM Mainframe Forum Index Mainframe: Search IBM Mainframe Forum: FAQ Register
 

Question regarding ISPF tables with TBDISPLAY


IBM Mainframe Forums -> TSO/ISPF
Post new topic   Reply to topic
View previous topic :: View next topic  
Author Message
Punki

New User


Joined: 31 Oct 2006
Posts: 10

PostPosted: Fri Sep 12, 2025 2:23 am
Reply with quote

Hi,

I have a table with 6 columns. The first column is to function as a command column. The others are data columns.

The Panel and the data look like:

show ISPF Tab with some Rows Row 1 of 20
COMMAND ===> SCROLL ===> CSR

CMD COL01 COL02 COL03 COL04 COL05
-------------------------------------------------------------------------------
___ COL1_001 COL2_001 COL3_001 COL4_001 COL5_001
___ COL1_002 COL2_002 COL3_002 COL4_002 COL5_002
___ COL1_003 COL2_003 COL3_003 COL4_003 COL5_003
___ COL1_004 COL2_004 COL3_004 COL4_004 COL5_004
___ COL1_005 COL2_005 COL3_005 COL4_005 COL5_005
___ COL1_006 COL2_006 COL3_006 COL4_006 COL5_006
___ COL1_007 COL2_007 COL3_007 COL4_007 COL5_007
___ COL1_008 COL2_008 COL3_008 COL4_008 COL5_008
___ COL1_009 COL2_009 COL3_009 COL4_009 COL5_009
___ COL1_010 COL2_010 COL3_010 COL4_010 COL5_010
___ COL1_011 COL2_011 COL3_011 COL4_011 COL5_011
___ COL1_012 COL2_012 COL3_012 COL4_012 COL5_012
___ COL1_013 COL2_013 COL3_013 COL4_013 COL5_013
___ COL1_014 COL2_014 COL3_014 COL4_014 COL5_014
___ COL1_015 COL2_015 COL3_015 COL4_015 COL5_015
___ COL1_016 COL2_016 COL3_016 COL4_016 COL5_016
___ COL1_017 COL2_017 COL3_017 COL4_017 COL5_017
___ COL1_018 COL2_018 COL3_018 COL4_018 COL5_018
___ COL1_019 COL2_019 COL3_019 COL4_019 COL5_019
___ COL1_020 COL2_020 COL3_020 COL4_020 COL5_020
******************************* Bottom of data ********************************


The table is displayed using TBDISPLAY.

Now I want to select one or more rows in the command column and then process the commands per row (one after the other).

I'll select row 5,7,8 an 10. With the Data in that line (5,7,8 and 10) i'll do something 'special'. All other rows are untouched.

In my REXX I can only act with one row.




Quote:



/* REXX */
ADDRESS ISPEXEC "VGET (ZSYSID) SHARED"
if RC > 0 then say 'after vget(ZSYSID) RC: 'RC
ADDRESS ISPEXEC "VGET (ZSCREEN) SHARED"
if RC > 0 then say 'after vget(ZSCREEN) RC: 'RC
tbname = "$TT"zsysid!!ZSCREEN /* set Table-Name */
ADDRESS ISPEXEC "TBCREATE "TBNAME" KEYS(COL1) " !! ,
"NAMES(COL2,COL3,COL4,COL5)"
IF RC = 8 THEN DO
ADDRESS ISPEXEC "TBCLOSE "TBNAME
ADDRESS ISPEXEC "TBERASE "TBNAME
ADDRESS ISPEXEC "TBCREATE "TBNAME" KEYS(COL1) " !! ,
"NAMES(COL2,COL3,COL4,COL5)"
END
ELSE DO
IF RC > 0 THEN DO
SAY 'after TBCREATE 1 RC: 'RC
END
END
CALL FILL_TAB
DO forever
ADDRESS ISPEXEC "TBTOP" tbname
IF RC > 0 THEN LEAVE /* the user uses PF3 */
ADDRESS ISPEXEC "TBDISPL" tbname "PANEL(PANTEST1) "
IF RC = 8 THEN LEAVE /* the user uses PF3 */
ADDRESS ISPEXEC "TBQUERY "tbname" ROWNUM(nrows)"
IF RC > 0 THEN do
say 'Problem with TBQUERY!'
leave
end
DO j = 1 TO nrows
ADDRESS ISPEXEC "TBTOP "tbname
DO k = 1 TO j
ADDRESS ISPEXEC "TBskip "tbname
END
IF FKT = 'S' THEN say 'FKT found by: ' j
END

END /* do forever */

RETURN


FILL_TAB: /* Procedure */

do i = 1 to 20
FKT = ' '
COL1 = 'COL1_'!!RIGHT(I,3,'0')!!' '
COL2 = 'COL2_'!!RIGHT(I,3,'0')!!' '
COL3 = 'COL3_'!!RIGHT(I,3,'0')!!' '
COL4 = 'COL4_'!!RIGHT(I,3,'0')!!' '
COL5 = 'COL5_'!!RIGHT(I,3,'0')!!' '
ADDRESS ISPEXEC "TBADD "TBNAME" ORDER"
end

RETURN /* FILL_TAB */
[/code]


What i can't understand is the fact, when I enter some commands in the TBDISPLAY panel how is it transfered into my REXX. Can i check row to row
if I can find some action characters. Or how does it work?

I hope you can help me.

Thanks alot.

Greetinge Punki
Back to top
View user's profile Send private message
Willy Jensen

Active Member


Joined: 01 Sep 2015
Posts: 766
Location: Denmark

PostPosted: Fri Sep 12, 2025 12:12 pm
Reply with quote

You need to use the ztdsels variable. Extract from one of my programs, I hope it helps
Code:
"tbdispl" $table "panel(tbdispl1) rowid(tblrow) position(tblpos)"     
cc=rc                                                                 
if cc>8 then call close 8 'table display rc' cc zerrlm                 
if cc>4 then leave                                                     
tbltop=ztdtop                                  /* save 1st displayd*/ 
tblsel.0=ztdsels                               /* # selections     */ 
do tblseln=1 to tblsel.0                       /* over selections  */ 
  if tblseln>1 then "tbdispl" $table "rowid(tblrow) position(tblpos)" 
    . . . handle data . . .
  End                                                                 
end   
Back to top
View user's profile Send private message
Punki

New User


Joined: 31 Oct 2006
Posts: 10

PostPosted: Fri Sep 12, 2025 5:00 pm
Reply with quote

Hi Willy,

your information was a game changer for me! Thanks alot!

So my code is now - and it works with the actual zOS version (3.1).

Code:

/************************** REXX *************************************/
/*                                                                   */
/*********************************************************************/
/* ACTION: test/check TBDISPLAY with PANTEST1                        */
/*********************************************************************/
/*                                                                   */
show = 'NO'                                                           
ADDRESS ISPEXEC "VGET (ZSYSID) SHARED"                                 
if RC > 0 then say 'after vget(ZSYSID) RC: 'RC                         
ADDRESS ISPEXEC "VGET (ZSCREEN) SHARED"                               
if RC > 0 then say 'after vget(ZSCREEN) RC: 'RC                       
tbname = "$TT"zsysid!!ZSCREEN /* set Table-Name */                     
ADDRESS ISPEXEC "TBCREATE "TBNAME" KEYS(COL1) " !! ,                   
                "NAMES(COL2,COL3,COL4,COL5) WRITE"                     
IF RC = 8 THEN DO                                                     
   ADDRESS ISPEXEC "TBCLOSE "TBNAME                                   
   ADDRESS ISPEXEC "TBERASE "TBNAME                                   
   ADDRESS ISPEXEC "TBCREATE "TBNAME" KEYS(COL1) " !! ,               
                   "NAMES(COL2,COL3,COL4,COL5) WRITE"                 
END                                                                   
ELSE DO                                                               
   IF RC > 0 THEN DO                                                   
      SAY 'after TBCREATE 1 RC: 'RC                                   
   END                                                                 
END                                                                   
CALL FILL_TAB                                                           
DO forever                                                             
   ADDRESS ISPEXEC "TBTOP" tbname                                       
   ADDRESS ISPEXEC "TBDISPL" tbname "PANEL(PANTEST1) " !!,             
                   "rowid(tblrow) position(tblpos)"                     
   cc=rc                                                               
   if cc>8 then leave                                                   
   if cc>4 then leave                                                   
   tbltop=ztdtop                                  /* save 1st displayd*/
   tblsel.0=ztdsels                               /* # selections     */
   start = 0                                                           
   do tblseln=1 to tblsel.0                       /* over selections  */
      if tblseln > 1 then ,                                             
      ADDRESS ISPEXEC "tbdispl" TBNAME !!,                             
                      " rowid(tblrow) position(tblpos)"                 
      if show = 'YES' then do                                           
         SAY 'selected in row ' TBLROW                                 
         SAY 'function in row ' "X"!!FKT!!"X"                           
         SAY 'start value     ' start                                   
      end                                                               
      if fkt = 'D' then do                                             
         ADDRESS ISPEXEC "tbdelete" TBNAME                             
      end                                                               
      if fkt = 'U' then do                                             
         tmp= tblrow + 0                                               
         col2 = 'UNDEL'!!RIGHT(TMP,3,'0')!!' '                         
         col3 = 'UNDEL'!!RIGHT(TMP,3,'0')!!' '                         
         col4 = 'UNDEL'!!RIGHT(TMP,3,'0')!!' '                         
         col5 = 'UNDEL'!!RIGHT(TMP,3,'0')!!' '                         
         ADDRESS ISPEXEC "TBMOD" TBNAME                                 
      end                                                               
      if fkt = '//U' & Start = 0 then do /* Start block U */           
         save_row_start = tblrow + 0                                   
         start = 2                                                     
      end                                                               
      if fkt = '//' & Start = 2 then do /* end block U */       
         save_row_end = tblrow + 0                               
         call UPD_rows                                           
         start = 0                                               
      end                                                       
      if fkt = '//U' & Start = 1 then do /* end block */         
         save_row_end = tblrow + 0                               
         call UPD_rows                                           
         start = 0                                               
      end                                                       
                                                                 
      if fkt = '//D' & Start = 0 then do /* Start block D */     
         save_row_start = tblrow + 0                             
         start = 3                                               
      end                                                       
      if fkt = '//' & Start = 3 then do /* end block D */       
         save_row_end = tblrow + 0                               
         call DEL_rows                                           
         start = 0                                               
      end                                                       
      if fkt = '//D' & Start = 1 then do /* end block */         
         save_row_end = tblrow + 0                               
         call DEL_rows                                           
         start = 0                                               
      end                                                       
                                                                 
      if fkt = '//' & Start = 0 then do /* Start block U or D */
         save_row_Start = tblrow + 0                             
         start = 1                                               
      end                                                       
   end                                                           
   fkt = ' '                                                     
                                                                 
END /* do forever */                                             
                                                                 
RETURN                                                           
               
DEL_rows:                                     
                                             
do i = save_row_start to save_row_end         
   ADDRESS ISPEXEC "tbskip" TBNAME "ROW("i")"
   ADDRESS ISPEXEC "tbDELETE" TBNAME         
end                                           
                                             
RETURN                                       
                                             
UPD_rows:                                     
                                             
do i = save_row_start to save_row_end         
   ADDRESS ISPEXEC "tbskip" TBNAME "ROW("i")"
   tmp= i + 0                                 
   col2 = 'UNDEL'!!RIGHT(TMP,3,'0')!!' '     
   col3 = 'UNDEL'!!RIGHT(TMP,3,'0')!!' '     
   col4 = 'UNDEL'!!RIGHT(TMP,3,'0')!!' '     
   col5 = 'UNDEL'!!RIGHT(TMP,3,'0')!!' '     
   ADDRESS ISPEXEC "tbMOD" TBNAME             
end                                           
                                             
RETURN                                       

                                             
FILL_TAB: /* Procedure */                     
                                             
do i = 1 to 20                               
   FKT = ' '                                 
   COL1 = 'COL1_'!!RIGHT(I,3,'0')!!' '       
   COL2 = 'COL2_'!!RIGHT(I,3,'0')!!' '       
   COL3 = 'COL3_'!!RIGHT(I,3,'0')!!' '       
   COL4 = 'COL4_'!!RIGHT(I,3,'0')!!' '       
   COL5 = 'COL5_'!!RIGHT(I,3,'0')!!' '       
   ADDRESS ISPEXEC "TBADD "TBNAME" ORDER"     
end                                           
                                             
RETURN /* FILL_TAB */                         
                                                                                               



The panel source is:

Code:


)ATTR                                                                   
/* DOC: PANEL PANTEST1 ***********************************************/
/* DOC: Panel to check inout in FKT (more than 1 row)                */
/*********************************************************************/
% type(text)    intens(low)  skip(on)  color(white)                     
+ type(text)    intens(low)  skip(on)  color(green)                     
* type(output)  intens(high) skip(on)  color(white)  just(left)         
? type(input)   intens(low)  caps(on)  color(turq)   just(left)         
! type(input)   intens(high) caps(on)  color(yellow) pad(_)             
)BODY expand(//)                                                       
                     +show ISPF Tab with some Rows                     
%COMMAND ===>_ZCMD / / %SCROLL ===>_ZSCR+                               
+                                                                       
+CMD    +COL01    +COL02    +COL03    +COL04    +COL05    +             
+/-/                                                                   
)MODEL                                                                 
!z  +   !z       +!z       +!z       +!z       +!z       +             
)INIT                                                                   
  .ZVARS   = '(FKT COL1 COL2 COL3 COL4 COL5)'                           
)PROC                                                                   
  if (.resp = END)                                                     
     &prc = 1                                                           
  if (.resp = ENTER)                                                   
     &prc = 0                                                           
)END                                                                   



The user can use the function D for delete, U for 'set undelete information' and can
mark with '//', '//U', '//D' the beginning and the end of some rows to delete or modify.

The next challenge for me is to display another panel and to come back to the first panel with the rows.

I'll continue the situation.

Greetings

Punki
Back to top
View user's profile Send private message
Punki

New User


Joined: 31 Oct 2006
Posts: 10

PostPosted: Fri Sep 12, 2025 5:01 pm
Reply with quote

Hi Willy,

your information was a game changer for me! Thanks alot!

So my code is now - and it works with the actual zOS version (3.1).

Code:

/************************** REXX *************************************/
/*                                                                   */
/*********************************************************************/
/* ACTION: test/check TBDISPLAY with PANTEST1                        */
/*********************************************************************/
/*                                                                   */
show = 'NO'                                                           
ADDRESS ISPEXEC "VGET (ZSYSID) SHARED"                                 
if RC > 0 then say 'after vget(ZSYSID) RC: 'RC                         
ADDRESS ISPEXEC "VGET (ZSCREEN) SHARED"                               
if RC > 0 then say 'after vget(ZSCREEN) RC: 'RC                       
tbname = "$TT"zsysid!!ZSCREEN /* set Table-Name */                     
ADDRESS ISPEXEC "TBCREATE "TBNAME" KEYS(COL1) " !! ,                   
                "NAMES(COL2,COL3,COL4,COL5) WRITE"                     
IF RC = 8 THEN DO                                                     
   ADDRESS ISPEXEC "TBCLOSE "TBNAME                                   
   ADDRESS ISPEXEC "TBERASE "TBNAME                                   
   ADDRESS ISPEXEC "TBCREATE "TBNAME" KEYS(COL1) " !! ,               
                   "NAMES(COL2,COL3,COL4,COL5) WRITE"                 
END                                                                   
ELSE DO                                                               
   IF RC > 0 THEN DO                                                   
      SAY 'after TBCREATE 1 RC: 'RC                                   
   END                                                                 
END                                                                   
CALL FILL_TAB                                                           
DO forever                                                             
   ADDRESS ISPEXEC "TBTOP" tbname                                       
   ADDRESS ISPEXEC "TBDISPL" tbname "PANEL(PANTEST1) " !!,             
                   "rowid(tblrow) position(tblpos)"                     
   cc=rc                                                               
   if cc>8 then leave                                                   
   if cc>4 then leave                                                   
   tbltop=ztdtop                                  /* save 1st displayd*/
   tblsel.0=ztdsels                               /* # selections     */
   start = 0                                                           
   do tblseln=1 to tblsel.0                       /* over selections  */
      if tblseln > 1 then ,                                             
      ADDRESS ISPEXEC "tbdispl" TBNAME !!,                             
                      " rowid(tblrow) position(tblpos)"                 
      if show = 'YES' then do                                           
         SAY 'selected in row ' TBLROW                                 
         SAY 'function in row ' "X"!!FKT!!"X"                           
         SAY 'start value     ' start                                   
      end                                                               
      if fkt = 'D' then do                                             
         ADDRESS ISPEXEC "tbdelete" TBNAME                             
      end                                                               
      if fkt = 'U' then do                                             
         tmp= tblrow + 0                                               
         col2 = 'UNDEL'!!RIGHT(TMP,3,'0')!!' '                         
         col3 = 'UNDEL'!!RIGHT(TMP,3,'0')!!' '                         
         col4 = 'UNDEL'!!RIGHT(TMP,3,'0')!!' '                         
         col5 = 'UNDEL'!!RIGHT(TMP,3,'0')!!' '                         
         ADDRESS ISPEXEC "TBMOD" TBNAME                                 
      end                                                               
      if fkt = '//U' & Start = 0 then do /* Start block U */           
         save_row_start = tblrow + 0                                   
         start = 2                                                     
      end                                                               
      if fkt = '//' & Start = 2 then do /* end block U */       
         save_row_end = tblrow + 0                               
         call UPD_rows                                           
         start = 0                                               
      end                                                       
      if fkt = '//U' & Start = 1 then do /* end block */         
         save_row_end = tblrow + 0                               
         call UPD_rows                                           
         start = 0                                               
      end                                                       
                                                                 
      if fkt = '//D' & Start = 0 then do /* Start block D */     
         save_row_start = tblrow + 0                             
         start = 3                                               
      end                                                       
      if fkt = '//' & Start = 3 then do /* end block D */       
         save_row_end = tblrow + 0                               
         call DEL_rows                                           
         start = 0                                               
      end                                                       
      if fkt = '//D' & Start = 1 then do /* end block */         
         save_row_end = tblrow + 0                               
         call DEL_rows                                           
         start = 0                                               
      end                                                       
                                                                 
      if fkt = '//' & Start = 0 then do /* Start block U or D */
         save_row_Start = tblrow + 0                             
         start = 1                                               
      end                                                       
   end                                                           
   fkt = ' '                                                     
                                                                 
END /* do forever */                                             
                                                                 
RETURN                                                           
               
DEL_rows:                                     
                                             
do i = save_row_start to save_row_end         
   ADDRESS ISPEXEC "tbskip" TBNAME "ROW("i")"
   ADDRESS ISPEXEC "tbDELETE" TBNAME         
end                                           
                                             
RETURN                                       
                                             
UPD_rows:                                     
                                             
do i = save_row_start to save_row_end         
   ADDRESS ISPEXEC "tbskip" TBNAME "ROW("i")"
   tmp= i + 0                                 
   col2 = 'UNDEL'!!RIGHT(TMP,3,'0')!!' '     
   col3 = 'UNDEL'!!RIGHT(TMP,3,'0')!!' '     
   col4 = 'UNDEL'!!RIGHT(TMP,3,'0')!!' '     
   col5 = 'UNDEL'!!RIGHT(TMP,3,'0')!!' '     
   ADDRESS ISPEXEC "tbMOD" TBNAME             
end                                           
                                             
RETURN                                       

                                             
FILL_TAB: /* Procedure */                     
                                             
do i = 1 to 20                               
   FKT = ' '                                 
   COL1 = 'COL1_'!!RIGHT(I,3,'0')!!' '       
   COL2 = 'COL2_'!!RIGHT(I,3,'0')!!' '       
   COL3 = 'COL3_'!!RIGHT(I,3,'0')!!' '       
   COL4 = 'COL4_'!!RIGHT(I,3,'0')!!' '       
   COL5 = 'COL5_'!!RIGHT(I,3,'0')!!' '       
   ADDRESS ISPEXEC "TBADD "TBNAME" ORDER"     
end                                           
                                             
RETURN /* FILL_TAB */                         
                                                                                               



The panel source is:

Code:


)ATTR                                                                   
/* DOC: PANEL PANTEST1 ***********************************************/
/* DOC: Panel to check inout in FKT (more than 1 row)                */
/*********************************************************************/
% type(text)    intens(low)  skip(on)  color(white)                     
+ type(text)    intens(low)  skip(on)  color(green)                     
* type(output)  intens(high) skip(on)  color(white)  just(left)         
? type(input)   intens(low)  caps(on)  color(turq)   just(left)         
! type(input)   intens(high) caps(on)  color(yellow) pad(_)             
)BODY expand(//)                                                       
                     +show ISPF Tab with some Rows                     
%COMMAND ===>_ZCMD / / %SCROLL ===>_ZSCR+                               
+                                                                       
+CMD    +COL01    +COL02    +COL03    +COL04    +COL05    +             
+/-/                                                                   
)MODEL                                                                 
!z  +   !z       +!z       +!z       +!z       +!z       +             
)INIT                                                                   
  .ZVARS   = '(FKT COL1 COL2 COL3 COL4 COL5)'                           
)PROC                                                                   
  if (.resp = END)                                                     
     &prc = 1                                                           
  if (.resp = ENTER)                                                   
     &prc = 0                                                           
)END                                                                   



The user can use the function D for delete, U for 'set undelete information' and can
mark with '//', '//U', '//D' the beginning and the end of some rows to delete or modify.

The next challenge for me is to display another panel and to come back to the first panel with the rows.

I'll continue the situation.

Greetings

Punki
Back to top
View user's profile Send private message
Willy Jensen

Active Member


Joined: 01 Sep 2015
Posts: 766
Location: Denmark

PostPosted: Fri Sep 12, 2025 7:35 pm
Reply with quote

As to your challenge. What I normally do is saving the selection and row data, and then drive the down-stream processess from the copy. That way I can drive subroutines doing ISPF stuff, even TBDISPLs, which would otherwise destroy my major loop.
So something like this (mostly off the top of my head):
Code:
tblsel.0=ztdsels                               /* # selections     */
do tblseln=1 to tblsel.0                       /* save selections  */
  if tblseln>1 then do
    "tbdispl" $table "rowid(tblrow) position(tblpos)"
    if wordpos(zsel,'D E U')=0 then do
      call IspMsg 'Bad line command' zsel
      zsel='?'
    end
    tblsel.tblseln = zsel tblrow pdata         /* fields in the row plus rowid */
  end                                                                 
end   
do tblseln=1 to tblsel.0                       /* over selections  */
  parse var tblsel.tblseln sel row data   
  select
    when sel='U' then call DoUpdate $table row data
    . .
    otherwise nop                         
  end
end

You of course need to decide if a warning and drop of the selection is enough, or you need to flush all the selections. Using the above scsheme, you can do that before a single selection is actually processed.
Back to top
View user's profile Send private message
Pedro

Global Moderator


Joined: 01 Sep 2006
Posts: 2622
Location: Silicon Valley

PostPosted: Sat Sep 13, 2025 12:35 am
Reply with quote

My suggestion is to include the CMD column in the TBCREATE.

Then when you process a row command, save the row command back to the column, except include an asterisk. Do this so that the user knows what command was issued for that row.

For example, if the user types 'U', then replace with '*U' when the line is processed. It tells the user what command was issued, and which row was processed.

I do not know if it is necessary but maybe have a column for return code for after a row command is executed. RC=0 for command worked or other code for failures.

I suggest using underscore attribute instead of underscore padding for the input fields.
Back to top
View user's profile Send private message
Willy Jensen

Active Member


Joined: 01 Sep 2015
Posts: 766
Location: Denmark

PostPosted: Sat Sep 13, 2025 2:03 pm
Reply with quote

"include the CMD column in the TBCREATE"
Yeah, I do that sometimes too.
Back to top
View user's profile Send private message
Pedro

Global Moderator


Joined: 01 Sep 2006
Posts: 2622
Location: Silicon Valley

PostPosted: Sat Sep 13, 2025 11:20 pm
Reply with quote

re: "include the CMD column in the TBCREATE"

hmm, actually it is the FKT variable in rexx.

And I do not think your panel will work well without it being in the TBCREATE. For example, if the user types several different row commands (and then presses Enter) you probably cannot tell that they are different.
Back to top
View user's profile Send private message
Willy Jensen

Active Member


Joined: 01 Sep 2015
Posts: 766
Location: Denmark

PostPosted: Sun Sep 14, 2025 2:56 pm
Reply with quote

"you probably cannot tell that they are different"
Yes you can, the the selection variable need not be a table variable. The TBDISPL command will return the entered value of that variable for each selected row, wether it is a table variable or not. Or did I misunderstand your reply?
Back to top
View user's profile Send private message
Punki

New User


Joined: 31 Oct 2006
Posts: 10

PostPosted: Thu Sep 18, 2025 6:43 pm
Reply with quote

Hi together,

now my test-application is ready. I'll share it with you while it took some time to
create, And I hope that some oter persons can use it as a sample for themselves.

First the code for the panels.

Panel Name PANTEST1

Code:

)ATTR
/* DOC: PANEL PANTEST1 ***********************************************/
/* DOC: Panel to check inout in FUNCTION (more than 1 row)           */
/* DOC: AUTOR: OLAF PANKONIN 22.08.2025                              */
/*********************************************************************/
% type(text)    intens(low)  skip(on)  color(white)
+ type(text)    intens(low)  skip(on)  color(green)
* type(output)  intens(high) skip(on)  color(white)  just(left)
? type(input)   intens(low)  caps(on)  color(turq)   just(left)
! type(input)   intens(high) caps(on)  color(yellow) pad(_)
)BODY expand(//)
                     +show ISPF Tab with some Rows
%COMMAND ===>_ZCMD / / %SCROLL ===>_ZSCR+
+
+CMD    +COL01    +COL02    +COL03    +COL04    +COL05    +
+/-/
)MODEL
!z   +   !z       +!z       +!z       +!z       +!z       +
)INIT
  .ZVARS   = '(FUNCTION COL1 COL2 COL3 COL4 COL5)'
)PROC
  if (.resp = END)
     &prc = 1
  if (.resp = ENTER)
     &prc = 0
)END


Panel Name PNLINFO

Code:

)ATTR
/*********************************************************************/
/* ACTION: The REXX PNLINFO displays this Panel!                     */
/*********************************************************************/
/*                                                                   */
% type(text)    intens(low)  skip(on)  color(white)
+ type(text)    intens(low)  skip(on)  color(green)
* type(output)  intens(high) skip(on)  color(white)  just(left)
? type(input)   intens(low)  caps(on)  color(turq)   just(left)
! type(input)   intens(high) caps(on)  color(yellow) pad(_)
)BODY expand(//)
              +display some Information
%COMMAND ===>_ZCMD / / %SCROLL ===>_ZSCR+
+
+&TEXT
+
+/-/
)END


And now the REXX-Application

Code:
/************************** REXX *************************************/
/* ACTION: ISPF Table-Action with 2 Panels and different functions.  */
/*         1. DISPLAY panel PANTEST1. Select functions D,E,S,U,UR    */
/*         and also with clamps // and //D,//E,//S,//U and //UR.     */
/*         The functions shows different actions to the data.        */
/*         With the functions E and S a secound panel is displayed.  */
/*         All functions are described in proc work_on_selection.    */
/*         The PARM show enable some information!                    */
/*********************************************************************/
/*                                                                   */

show = 'NO' /* 'NO' | 'YES' to show some information */

ADDRESS ISPEXEC "VGET (ZSYSID) SHARED"
IF RC > 0 THEN say 'after vget(ZSYSID) RC: 'RC

ADDRESS ISPEXEC "VGET (ZSCREEN) SHARED"
IF RC > 0 THEN say 'after vget(ZSCREEN) RC: 'RC

tbname = "$TT"zsysid!!ZSCREEN /* set Table-Name */

ADDRESS ISPEXEC "TBCREATE "tbname" KEYS(COL1) " !! ,
                "NAMES(COL2,COL3,COL4,COL5) WRITE"

IF RC = 8 THEN DO
   ADDRESS ISPEXEC "TBCLOSE "tbname
   ADDRESS ISPEXEC "TBERASE "tbname
   ADDRESS ISPEXEC "TBCREATE "tbname" KEYS(COL1) " !! ,
                   "NAMES(COL2,COL3,COL4,COL5) WRITE"
END
ELSE DO
   IF RC > 0 THEN DO
      SAY 'after TBCREATE 1 RC: 'RC
   END
END

CALL fill_tab

DROP rowline.0
rowline.0 = 0
count     = 0

DO FOREVER
   CALL tb_disp01                               /* show initial panel */
   cnt_tbsel = ztdsels                  /* gives number of selections */
   DO tblseln = 1 TO cnt_tbsel          /* when something is selected */
      IF tblseln > 1 THEN call tb_disp02     /* shows the same panel! */

      call info /* show YES | NO */

      IF function = 'D' THEN DO
         call find_selection /* safe function info in List.Var */
      END
      IF function = 'E' THEN DO
         call find_selection /* safe function info in List.Var */
      END
      IF function = 'M' THEN DO
         call find_selection /* safe function info in List.Var */
      END
      IF function = 'R' THEN DO
         call find_selection /* safe function info in List.Var */
      END
      IF function = 'S' THEN DO
         call find_selection /* safe function info in List.Var */
      END
      IF function = 'U' THEN DO
         call find_selection /* safe function info in List.Var */
      END
      IF function = 'RU' THEN DO
         call find_selection /* safe function info in List.Var */
      END
      IF function = '//' THEN DO
         call find_selection /* safe function info in List.Var */
      END
      IF function = '//D' THEN DO
         call find_selection /* safe function info in List.Var */
      END
      IF function = '//E' THEN DO
         call find_selection /* safe function info in List.Var */
      END
      IF function = '//M' THEN DO
         call find_selection /* safe function info in List.Var */
      END
      IF function = '//S' THEN DO
         call find_selection /* safe function info in List.Var */
      END
      IF function = '//R' THEN DO
         call find_selection /* safe function info in List.Var */
      END
      IF function = '//U' THEN DO
         call find_selection /* safe function info in List.Var */
      END
      IF function = '//RU' THEN DO
         call find_selection /* safe function info in List.Var */
      END
   END /* DO tblseln = 1 TO cnt_tbsel */

   IF rowline.0 > 0 THEN ,       /* only when functions are selected! */
      call work_on_selection

   DROP rowline.0
   rowline.0 = 0
   DROP rowfct.0
   rowfct.0 = 0
   count = 0
   function = ' '

END /* DO forever */

RETURN /* MAIN PROC */


WORK_ON_SELECTION:

/* The selected function symbols were stored in list variables.    */
/* IF more than 0 entries were found, the procedure                */
/* 'work_on_selection' is executed for these entries.              */
/* functions that are not in logical order, e.g., more than one    */
/* line starting with // as a block delimiter, are grouped into    */
/* logical blocks and 'errors' are ignored.                        */
/* Example: Line 1 with // and line 5 with //, as well as line 8   */
/* with //D. The bracketing is applied to lines 1 through 8. The   */
/* error in line 5 is ignored. Invalid function combinations are   */
/* not executed (e.g., line 5 //D next bracket line 8 //U).        */

inBracket     = 0
expectCloseU  = ''
expectCloseD  = ''
expectCloseM  = ''
expectCloseE  = ''
expectCloseS  = ''
expectCloseRU = ''

IF show = 'YES' THEN SAY 'in work_on_selection rowline.0 ' rowline.0

DO i = 1 TO rowline.0
   IF rowfct.i = 'D' THEN DO
      tmprow = rowline.i + 0
      ADDRESS ISPEXEC "tbskip" tbname "ROW("tmprow")"
      ADDRESS ISPEXEC "tbdelete" tbname
      rowfct.i  = ' '
      rowline.i = ' '
   END
   IF rowfct.i = 'E' THEN DO
      tmprow = rowline.i + 0
      ADDRESS ISPEXEC "tbskip" tbname "ROW("tmprow")"
      text = 'SHOW-row-number with VAL ' rowline.i
      ADDRESS ISPEXEC "DISPLAY PANEL(PNLINFO)"
      rowfct.i  = ' '
      rowline.i = ' '
   END
   IF rowfct.i = 'M' THEN DO
      tmprow = rowline.i + 0
      ADDRESS ISPEXEC "tbskip" tbname "ROW("tmprow")"
      text = 'SEND Mail with the Job-Information ' tmprow
      ADDRESS ISPEXEC "DISPLAY PANEL(PNLINFO)"
      rowfct.i  = ' '
      rowline.i = ' '
   END
   IF rowfct.i = 'S' THEN DO
      tmprow = rowline.i + 0
      ADDRESS ISPEXEC "tbskip" tbname "ROW("tmprow")"
      text = 'SHOW-row-number with VAL ' tmprow
      ADDRESS ISPEXEC "DISPLAY PANEL(PNLINFO)"
      rowfct.i  = ' '
      rowline.i = ' '
   END
   IF rowfct.i = 'U' THEN DO
      tmprow = rowline.i + 0
      ADDRESS ISPEXEC "tbskip" tbname "ROW("tmprow")"
      col2 = 'UPD2_'!!RIGHT(TMProw,3,'0')!!' '
      col3 = 'UPD3_'!!RIGHT(TMProw,3,'0')!!' '
      col4 = 'UPD4_'!!RIGHT(TMProw,3,'0')!!' '
      col5 = 'UPD5_'!!RIGHT(TMProw,3,'0')!!' '
      ADDRESS ISPEXEC "TBMOD" tbname
      rowfct.i  = ' '
      rowline.i = ' '
   END
   IF rowfct.i = 'RU' THEN DO
      tmprow = rowline.i + 0
      ADDRESS ISPEXEC "tbskip" tbname "ROW("tmprow")"
      col2 = 'COL2_'!!RIGHT(TMProw,3,'0')!!' '
      col3 = 'COL3_'!!RIGHT(TMProw,3,'0')!!' '
      col4 = 'COL4_'!!RIGHT(TMProw,3,'0')!!' '
      col5 = 'COL5_'!!RIGHT(TMProw,3,'0')!!' '
      ADDRESS ISPEXEC "TBMOD" tbname
      rowfct.i  = ' '
      rowline.i = ' '
   END

   /* open bracket for all multiple rows */
   IF (rowfct.i = '//' & inBracket = 0) THEN DO
      save_start_row = rowline.i + 0
      inBracket = 1
      expectCloseU  = '//U'
      expectCloseD  = '//D'
      expectCloseS  = '//S'
      expectCloseE  = '//E'
      expectCloseM  = '//M'
      expectCloseRU = '//RU'
      rowfct.I  = ' '
      rowline.I = ' '
   END

   IF (rowfct.i = '//U' & inBracket = 0) THEN DO
      save_start_row = rowline.i + 0
      inBracket = 1
      expectCloseU = '//'
   END
   IF (rowfct.i = '//D' & inBracket = 0) THEN DO
      save_start_row = rowline.i + 0
      inBracket = 1
      expectCloseD = '//'
   END
   IF (rowfct.i = '//M' & inBracket = 0) THEN DO
      save_start_row = rowline.i + 0
      inBracket = 1
      expectCloseM = '//'
   END
   IF (rowfct.i = '//E' & inBracket = 0) THEN DO
      save_start_row = rowline.i + 0
      inBracket = 1
      expectCloseE = '//'
   END
   IF (rowfct.i = '//S' & inBracket = 0) THEN DO
      save_start_row = rowline.i + 0
      inBracket = 1
      expectCloseS = '//'
   END
   IF (rowfct.i = '//RU' & inBracket = 0) THEN DO
      save_start_row = rowline.i + 0
      inBracket = 1
      expectCloseRU = '//'
   END

   /* closed bracket U */
   IF (rowfct.i = '//' & expectCloseU = '//') THEN DO
      save_END_row = rowline.i + 0
      DO a = save_start_row TO save_END_row
         tmprow = a
         ADDRESS ISPEXEC "tbskip" tbname "ROW("tmprow")"
         col2 = 'UPD2_'!!RIGHT(TMProw,3,'0')!!' '
         col3 = 'UPD3_'!!RIGHT(TMProw,3,'0')!!' '
         col4 = 'UPD4_'!!RIGHT(TMProw,3,'0')!!' '
         col5 = 'UPD5_'!!RIGHT(TMProw,3,'0')!!' '
         ADDRESS ISPEXEC "TBMOD" tbname
         rowfct.I  = ' '
         rowline.I = ' '
      END
      inBracket = 0
      expectCloseU = ''
   END
   IF (rowfct.i = '//U' & expectCloseU = '//U') THEN DO
      save_END_row = rowline.i + 0
      DO a = save_start_row TO save_END_row
         tmprow = a
         ADDRESS ISPEXEC "tbskip" tbname "ROW("tmprow")"
         col2 = 'UPD2_'!!RIGHT(TMProw,3,'0')!!' '
         col3 = 'UPD3_'!!RIGHT(TMProw,3,'0')!!' '
         col4 = 'UPD4_'!!RIGHT(TMProw,3,'0')!!' '
         col5 = 'UPD5_'!!RIGHT(TMProw,3,'0')!!' '
         ADDRESS ISPEXEC "TBMOD" tbname
         rowfct.I  = ' '
         rowline.I = ' '
      END
      inBracket = 0
      expectCloseU = ''
   END

   /* closed bracket D */
   IF (rowfct.i = '//' & expectCloseD = '//') THEN DO
      save_END_row = rowline.i + 0
      DO a = save_start_row TO save_END_row
         tmprow = a
         ADDRESS ISPEXEC "tbskip" tbname "ROW("tmprow")"
         ADDRESS ISPEXEC "tbdelete" tbname
         rowfct.I  = ' '
         rowline.I = ' '
      END
      inBracket = 0
      expectCloseD = ''
   END
   IF (rowfct.i = '//D' & expectCloseD = '//D') THEN DO
      save_END_row = rowline.i + 0
      DO a = save_start_row TO save_END_row
         tmprow = a
         ADDRESS ISPEXEC "tbskip" tbname "ROW("tmprow")"
         ADDRESS ISPEXEC "tbdelete" tbname
         rowfct.I  = ' '
         rowline.I = ' '
      END
      inBracket = 0
      expectCloseD = ''
   END

   /* closed bracket E */
   IF (rowfct.i = '//' & expectCloseE = '//') THEN DO
      save_END_row = rowline.i + 0
      DO a = save_start_row TO save_END_row
         tmprow = a
         ADDRESS ISPEXEC "tbskip" tbname "ROW("tmprow")"
         text = 'SHOW-row-number with VAL ' a
         ADDRESS ISPEXEC "DISPLAY PANEL(PNLINFO)"
         rowfct.I  = ' '
         rowline.I = ' '
      END
      inBracket = 0
      expectCloseE = ''
   END
   IF (rowfct.i = '//E' & expectCloseE = '//E') THEN DO
      save_END_row = rowline.i + 0
      DO a = save_start_row TO save_END_row
         tmprow = a
         ADDRESS ISPEXEC "tbskip" tbname "ROW("tmprow")"
         text = 'SHOW-row-number with VAL ' a
         ADDRESS ISPEXEC "DISPLAY PANEL(PNLINFO)"
         rowfct.I  = ' '
         rowline.I = ' '
      END
      inBracket = 0
      expectCloseE = ''
   END

   /* closed bracket M */
   IF (rowfct.i = '//' & expectCloseM = '//') THEN DO
      save_END_row = rowline.i + 0
      DO a = save_start_row TO save_END_row
         tmprow = a
         ADDRESS ISPEXEC "tbskip" tbname "ROW("tmprow")"
         say 'SEND Mail ' tmprow
         rowfct.I  = ' '
         rowline.I = ' '
      END
      inBracket = 0
      expectCloseM = ''
   END
   IF (rowfct.i = '//M' & expectCloseM = '//M') THEN DO
      save_END_row = rowline.i + 0
      DO a = save_start_row TO save_END_row
         tmprow = a
         ADDRESS ISPEXEC "tbskip" tbname "ROW("tmprow")"
         say 'SEND Mail ' tmprow
         rowfct.I  = ' '
         rowline.I = ' '
      END
      inBracket = 0
      expectCloseM = ''
   END

   /* closed bracket S */
   IF (rowfct.i = '//' & expectCloseS = '//') THEN DO
      save_END_row = rowline.i + 0
      DO a = save_start_row TO save_END_row
         tmprow = a
         ADDRESS ISPEXEC "tbskip" tbname "ROW("tmprow")"
         say 'Show Job ' tmprow
         rowfct.I  = ' '
         rowline.I = ' '
      END
      inBracket = 0
      expectCloseS = ''
   END
   IF (rowfct.i = '//S' & expectCloseS = '//S') THEN DO
      save_END_row = rowline.i + 0
      DO a = save_start_row TO save_END_row
         tmprow = a
         ADDRESS ISPEXEC "tbskip" tbname "ROW("tmprow")"
         say 'Show Job ' tmprow
         rowfct.I  = ' '
         rowline.I = ' '
      END
      inBracket = 0
      expectCloseS = ''
   END

   /* closed bracket RU */
   IF (rowfct.i = '//' & expectCloseRU = '//') THEN DO
      save_END_row = rowline.i + 0
      DO a = save_start_row TO save_END_row
         tmprow = a
         ADDRESS ISPEXEC "tbskip" tbname "ROW("tmprow")"
         col2 = 'COL2_'!!RIGHT(TMProw,3,'0')!!' '
         col3 = 'COL3_'!!RIGHT(TMProw,3,'0')!!' '
         col4 = 'COL4_'!!RIGHT(TMProw,3,'0')!!' '
         col5 = 'COL5_'!!RIGHT(TMProw,3,'0')!!' '
         ADDRESS ISPEXEC "TBMOD" tbname
         rowfct.I  = ' '
         rowline.I = ' '
      END
      inBracket = 0
      expectCloseRU = ''
   END
   IF (rowfct.i = '//RU' & expectCloseRU = '//RU') THEN DO
      save_END_row = rowline.i + 0
      DO a = save_start_row TO save_END_row
         tmprow = a
         ADDRESS ISPEXEC "tbskip" tbname "ROW("tmprow")"
         col2 = 'COL2_'!!RIGHT(TMProw,3,'0')!!' '
         col3 = 'COL3_'!!RIGHT(TMProw,3,'0')!!' '
         col4 = 'COL4_'!!RIGHT(TMProw,3,'0')!!' '
         col5 = 'COL5_'!!RIGHT(TMProw,3,'0')!!' '
         ADDRESS ISPEXEC "TBMOD" tbname
         rowfct.I  = ' '
         rowline.I = ' '
      END
      inBracket = 0
      expectCloseRU = ''
   END

   /* no more fuctions */

END /* DO i = 1 TO rowline.0 */

RETURN /* Proc work_on_selection */



FIND_SELECTION: /* save TB-Row-Nr and function in List-Variable */

IF show = 'YES' THEN SAY 'in find_selection: ' tblrow function

count         = count + 1
rowline.0     = count
rowline.count = tblrow
rowfct.0      = count
rowfct.count  = function

RETURN /* Proc find_selection */



INFO: /* display stacked functions */

IF show = 'YES' THEN DO
   SAY 'how many rows   ' cnt_tbsel
   SAY 'selected in row ' TBLROW
   SAY 'function in row ' function
END

RETURN /* INFO */



TB_DISP02: /* re-display panel PANTEST1 */

ADDRESS ISPEXEC "tbdispl" tbname "ROWID(TBLROW) POSITION(TBLPOS)"
cc=rc
CALL check_exit

RETURN /* Proc TB_DISP02 */



TB_DISP01: /* display panel PANTEST1 */

ADDRESS ISPEXEC "TBTOP" tbname
ADDRESS ISPEXEC "TBDISPL" tbname "PANEL(PANTEST1) " !!,
                "ROWID(TBLROW) POSITION(TBLPOS)"
cc=rc
CALL check_exit

RETURN /* Proc TB_DISP01 */



CHECK_EXIT: /* check the return-code after TBSERVICE e.g. EXIT */

IF cc > 8 THEN EXIT
IF cc > 4 THEN EXIT

RETURN /* Proc CHECK_EXIT */



FILL_TAB: /* Procedure */

DO i = 1 TO 20
   function = ' '
   COL1 = 'COL1_'!!RIGHT(I,3,'0')!!' '
   COL2 = 'COL2_'!!RIGHT(I,3,'0')!!' '
   COL3 = 'COL3_'!!RIGHT(I,3,'0')!!' '
   COL4 = 'COL4_'!!RIGHT(I,3,'0')!!' '
   COL5 = 'COL5_'!!RIGHT(I,3,'0')!!' '
   ADDRESS ISPEXEC "TBADD "tbname" ORDER"
END

RETURN /* Proc FILL_TAB */





Copy the code into the needed liebraries and execute the REXX. Then you can
select the command character D-delete, E-Edit, S-Show, U-set NO-DELETE-sign,
RU-remove NO-DELETE-sign.

In combination with // you can combine some rows.

Enyou it!

Greetings

Punki
Back to top
View user's profile Send private message
Willy Jensen

Active Member


Joined: 01 Sep 2015
Posts: 766
Location: Denmark

PostPosted: Thu Sep 18, 2025 9:15 pm
Reply with quote

Thanks. I would suggest tidying up the code a bit, nothing to do with TBDISPL, just standard coding technique.
Instead of a bunch of
Code:
 IF function = 'D' THEN DO
       call find_selection /* safe function info in List.Var */
  END

Do something like
Code:
 select
   when function = 'D' THEN call find_selection
   . . .
   otherwise say 'Invalid function' function
 end
Back to top
View user's profile Send private message
Punki

New User


Joined: 31 Oct 2006
Posts: 10

PostPosted: Thu Sep 18, 2025 10:07 pm
Reply with quote

Hi Willy,

yes, you are right... I simply vorget to use select.

Greeting

Punki
Back to top
View user's profile Send private message
View previous topic : : View next topic  
Post new topic   Reply to topic All times are GMT + 6 Hours
Forum Index -> TSO/ISPF

 


Similar Topics
Topic Forum Replies
No new posts To join 2 tables and to join 3rd tabl... DB2 8
No new posts Extract ISPF table column headings CLIST & REXX 2
No new posts OPC scheduling question IBM Tools 0
No new posts Preserve changes to ISPF Panel Variables TSO/ISPF 5
No new posts can an ISPF appl save user changes in... TSO/ISPF 14
Search our Forums:


Back to Top