RPG-ILE FREE (format) subfile pgm (2)

April 25, 2010
By


In February of 2010 I asked my friend Ken Killian to update the RPG program RPG-ILE subfile pgm (1) to FREE FORMAT. (the DSPF and etc. are at “RPG-ILE subfile pgm (1)”)
Now, things are even better. the EVAL opcode is no longer needed. MOVE is not needed. Z-ADD is not needed. You simply write statements, like
If *In26 = *Off;
Count +=1;
...

You can indent blocks of code to easily see the ranges of nested loops and ifs.
It is easy to look up and see where an ENDIF came from! Finally!

[ to see the display file and PF & LF definitions and some sample data you can use, see the previous ILE version ]

       // =============================================================
       //     Program Name:  CUSUPDR    search and update via. subfile.
       //            ~~~~~~~
       //     Author (ID) :  Greg Smith ( SPgks )    INIT. DATE:  10-27-91
       //     converted to RPG-ILE     on  4-22-98
       //     Author (ID)    Ken Killian (ILE RPG Developer)  Date: 02/11/2010
       //     Convert to FREE-Format   on 02-11-2010
       //     Notes: o Convert "Add 1" to " += 1;"
       //            o Convert OpCode "LOOKUP" to "%TLookup"
       //            o Convert OpCode "MOVE"   to "=" statement
       // =============================================================
       //      combined and enhanced example (compile in this order):
       //       1  cufldref   field definitions for all applications
       //       2  cusmst0    customer master file (in # key order)
       //       3  CUSMST2    logical view of 2. in name order
       //       4  cusupdd    display file (DSPF)
       //       5  cusupdr    (this) RPG program
       //       In addition to searching by name and by number,
       //       the prog. enables subfile viewing (2x2 views)
       //       by pageing up (as well as down) and selecting
       //       individual records for viewing and updating.
       //     expanded from  RPG USERS GUIDE, book 26, Chap.8, pg.59 (V1R3)
       //       combining of Sample Programs, book 26  Chap.8, pgms. 3 & 5
       //            and adding to them.
       //      DSPF: CUSMLGD   MLG265D on page 8-55, book 26
       //        PF: CUSMST0   CusMstP on page 8-54, book 26
       //        LF: CUSMST2   not from book: logical view by last name.
       // ===============================================================
       //       If CUSMST0 and CUSMST2 have the same record names,
       //            at least one of them must be renamed.
       // -----------------------------------------------------
       //        PF: CUSMST0 --- record name: CUSMSTR
       //        LF: CUSMST1 --- record name: CUSMSTR
       //        LF: CUSMST2 --- record name: CUSMSTR
       //      DSPF: CUSUPDD
       // ----------------------------------------------------------------
       // -------- := - -  ---      - ------- ------------------------------------
     FCUSUPDD   CF   E             WORKSTN SFILE(SUBCTRL:RREC#)
     FCUSMST1   UF A E           K DISK    RENAME(CUSMSTR:RECNUMR)
     FCUSMST2   IF   E           K DISK    RENAME(CUSMSTR:RECNAME)
       // -------- := - -  ---      - ------- ------------------------------------
       //   The Chain, SetLL, and Read operations are all done on the
       //   internally kRENAME'd record names (RECNUMR & RECNAME).
       // ================================================================
       //   -----------------  1   T A B L E  -----------------------
       //                   TAB# = the reference line message # (see bottom).
       //                                      TABMSG = the message
       //                               3  0 = 3 diget numeric with 0 decimals
       //                         # of lines/Records/strings/messages = 11
       //                              72 character string
       // -----------------------------------------------------------------------
     D TAB#            S              3  0 DIM(11) CTDATA PERRCD(1)         table of msgs
     D TABMSG          S             72    DIM(11) ALT(TAB#)
     D RREC#           S              4  0
     D Count           S              3  0
       // ----------------------------------------------------------------**
       //               C  A  L  C  U  L  A  T  I  O  N  S                **
       // ----------------------------------------------------------------**
       //          I N I T I A L I Z A T I O N s
     C     NUMRKY        KList
     C                   KFLD                    CUST#                      only the 1st
     C     NAMEKY        KList
     C                   KFLD                    NAMEL                      field is used.
       //  set default order here (IN20 on or not)
       //  numeric order is *In20 *On  (otherwise last name order)
       //          **        SETON                     20
      /FREE
       If   *In20 = *On;                                           // logical views.
            SetGT *LoVal RECNUMR;                                  // #LF
            Read RECNUMR;                                          // = empty file.
            *In99 = %EOF;
       Else;
            SetGT *LoVal RECNAME;                                  // NLF
            Read RECNAME;                                          // = empty file.
            *In99 = %EOF;
       EndIf;
       If   *In99 = *On;                                           //   If empty
            *In26 = *On;
            Exsr ADDSUB;                                           // create 1st record
       EndIf;
       If   *In26  = *Off;
            Count +=1 ; // Z-ADD 01 COUNT
            Exsr  RESET;
            Write BOTTOM;                                          // main screen
            EXFMT SUBSCRN;
            //  note: endIf and EndDo; rather than end; are for clarity, not for
            //        control, and are not necessary.  EndSr is necessary.
            // ##############   M A I N L I N E   ################**    C A S E :
            Dow  *In03 = *Off  and                                   // while not F3
                 *In12 = *Off;                                       //     & not F12
                 Count += 1; // ADD 1 COUNT
                 If   *In94 = *On   and                              //  94 = PAGE UP key
                      *In91 = *Off;                                  //  ifnot t.o.f.
                      *In77 = *Off;
                      *In99 = *Off;
                      Exsr PAGEUP;
                 EndIf;
                 If   *In95 = *On   and                              //  95 = PG.DN.key
                      *In99 = *Off;                                  //  If not e.o.f.
                      *In77 = *Off;
                      *In91 = *Off;
                      Exsr PGDOWN;
                 EndIf;
                 If   *In06 = *On;                                   // = add a rec.
                      Exsr ADDSUB;
                 EndIf;
                 If   *In11 = *On;                                   // : switch
                      If   *In21 = *Off;                             // half of record
                           *In21 = *On;
                      Else;                                          // fields viewed)
                           *In21 = *Off;
                      EndIf;
                 EndIf;
                 If   *In10 = *On;                                   // : switch
                      If *In20 = *Off;                               // logical views.
                           *In20 = *On;
                      Else;
                           *In20 = *Off;
                      EndIf;
                      *In77 = *Off;
                      *In99 = *Off;
                 EndIf;
                 If   SFNAME <> *Blanks;                                 //  If there
                      NAMEL = SFNAME; // MOVEL SFNAME NAMEL              //  is a
                      SetLL NAMEKY RECNAME;                              //  NEW NAME
                      ReadP RECNAME;                                     //  to find.
                      *In91 = %EOF;
                      ReadP RECNAME;
                      *In91 = %EOF;
                      If *In91 = *On;
                         NAMEL = *Blanks;             // MOVE *Blanks NAMEL - tof
                         SetLL NAMEKY RECNAME;                             // tof
                      EndIf;
                      *In77 = *Off;
                      Exsr PGDOWN;
                      SFName = *Blanks; // MOVE *Blanks SFNAME
                 EndIf;
                 If   SFNUMR <> 0;                                       // If there is a
                      CUST# = SFNUMR; // Z-ADD SFNUMR CUST#              //  NEW NUMBER
                      SetLL NUMRKY RECNUMR;                              //  to find.
                      ReadP RECNUMR;                                       
                      *In91 = %EOF;
                      ReadP RECNUMR;
                      *In91 = %EOF;
                      If   *In91 = *On;
                           CUST# = *Zeros; 
                           SetLL NUMRKY RECNUMR;                         //  tof
                      EndIf;
                      *In77 = *Off;
                      Exsr PGDOWN;
                      SFNUMR = *Zeros; // Z-ADD 0 SFNUMR
                 EndIf;
                 ReadC SUBCTRL;                                          //  process
                 *In31 = %EOF;
                 //               O P T I O N S :
                 If   *In31 = *Off;
                      Dow  *In31 = *Off;
                           //   turn off error indicators
                           *In35 = *Off; // MOVE *Off *In35              //  SFLNXTCHG
                           *In51 = *Off; // MOVE *Off *In51              //  DSPATR(RI PC)
                           SELECT;
                           WHEN OPTN = '2';
                                Exsr UPDATE;
                           WHEN OPTN = '4';
                                Exsr DELETE;
                           WHEN OPTN = '5';
                                Exsr DSPLAY;
                           OTHER;
                                *In35 = *On; // MOVE *On *In35           //  SFLNXTCHG
                                *In51 = *On; // MOVE *On *In51           //  DSPATR(RI PC)
                                *In77 = %TLookup(010:Tab#:TabMsg); 
                    // 010 LOOKUP TAB# TABMSG 77                 <-- the old code 
                           EndSl;
                           Update SUBCTRL;
                           ReadC SUBCTRL;
                           *In31 = %EOF;
                      EndDo;
                      Chain 1 SUBCTRL;
                      *In52 = NOT %Found;
                      //
                      If   *In20 = *On;
                           SetLL NUMRKY RECNUMR;
                           Exsr PGDOWN;
                      EndIf;
                 EndIf;
                 Exsr RESET;                                           //  re-display
                 Write BOTTOM;                                         //  main screen
                 EXFMT SUBSCRN;
            EndDo;                                                     // while not F3/F12
       EndIf;
       *InLR = *On;
       //             ##     E N D   O F     ##
       // ##############   M A I N L I N E   ################**
       // ==============================================================
       //           S  U  B  R  O  U  T  I  N  E  S
       //         re-display the   MAIN  SCREEN
       BegSr RESET;
       *In71 = *Off;                                                   // top-of-file msg.
       Exsr PAGEUP;
       If   *In91 = *On;                                               // TOF
            *In71 = *On;                                               // top-of-file msg.
       EndIf;
       If   *In99 = *On;                                               // EOF
            *In77 = %TLookup(009:Tab#:TabMsg);         // 009 LOOKUP TAB# TABMSG 77
       EndIf;
       Exsr PGDOWN;
       EndSr;
       // ==============================================================
       //            Read previous records            PAGE  UP
       // ==============================================================
       BegSr PAGEUP;
       Exsr CLRSUB;                             // clear subfile
       Dow  *In89 = *Off;                       // while subf notFull
            If   *In20 = *On;                   // #LF
                 ReadP RECNUMR;                 // = top-of-#file.
                 *In91 = %EOF;
            Else;                               // NLF
                 ReadP RECNAME;                 // = top-of-Nfile.
                 *In91 = %EOF;
            EndIf;
            If   *In91 = *On;                    // TOF
                 *In89 = *On;
                 If   *In20 = *On;               // #LF
                      Chain NUMRKY RECNUMR;
                      *In52 = NOT %Found;
                      SetLL NUMRKY RECNUMR;
                 Else;                           // NLF
                      Chain NAMEKY RECNAME;
                      *In52 = NOT %Found;
                      SetLL NAMEKY RECNAME;
                 EndIf;
            Else;
                 RREC# += 1;                    // ADD 1 RREC#
                 OPTN   = *Blanks;              // MOVE *BLANK OPTN
                 Write SUBCTRL;                 // = subfile filled.
                 *In89  = %EOF;
            EndIf;
       EndDo;
       *In89 = *Off;
       EndSr;
       // =============================================================
       //          clear subfile records
       // =============================================================
       BegSr CLRSUB;
       *In55 = *On;
       Write SUBSCRN;                         //  subfile clear
       *In55 = *Off;
       RREC# = *Zeros; // Z-ADD 0 RREC#
       EndSr;
       // =============================================================
       //           Fill the Subfile (screen/page)    PAGE DOWN
       // =============================================================
       BegSr PGDOWN;
       Exsr CLRSUB;                           // clear subfile
       Dow *In89 = *Off;                      // while subf notFull
            If *In20 = *On;                   // #LF
                 Read RECNUMR;                // = end-of-#file.
                 *In99 = %EOF;
            Else;
                 Read RECNAME;                // = end-of-Nfile.
                 *In99 = %EOF;
            EndIf;
            If *In99 = *On;                   //   end-of-file.
                 If *In20 = *On;              // #LF
                      SetLL NUMRKY RECNUMR;
                 Else;                        // NLF
                      SetLL NAMEKY RECNAME;
                 EndIf;
                 *In89 = *On;
            Else;
                 RREC# += 1;            // ADD 1 RREC#
                 OPTN   = *Blanks;      // MOVE *BLANK OPTN
                 Write SUBCTRL;         //      = subfile filled.
                 *In89 = %EOF;
            EndIf;
       EndDo;
       *In89 = *Off;
       EndSr;
       // ============================================================
       //     4.   subroutine     D E L E T E                 4 = delete option
       // ============================================================
       BegSr DELETE;
       Chain NUMRKY RECNUMR;
       *In52 = NOT %Found;
       If   *In52 = *Off;                       //  If found
            *In07 = *On;
            *In72 = %TLookup(004:Tab#:TabMsg) ;       // 004 LOOKUP TAB#  TABMSG 72
            EXFMT RECDSP;
            If   *In03 = *Off;                  //  If not F3
                 Delete RECNUMR;                //  delete If not F3
            Else;
                 Except RLS;                    //  or release it.
            EndIf;
       Else;
            *In77 = %TLookup(003:Tab#:TabMsg);  // 003 LOOKUP TAB# TABMSG 77
       EndIf;                                   //     end If found
       *In52 = *Off;
       *In07 = *Off;
       OPTN = *Blanks;                          // MOVE *BLANK OPTN
       EndSr;
       // ===========================================================
       //      5.  subroutine     DISPLAY-INQUIRY             5 = display option
       // ===========================================================
       BegSr DSPLAY;
       *In77 = *Off;
       Chain NUMRKY RECNUMR;            // = rec. NOT found
       *In52 = NOT %Found;
       If   *In52 = *Off;               //        If found
            *In07 = *On;
            *In72 = %TLookup(005:Tab#:TabMsg); // 005 LOOKUP TAB# TABMSG 72
            EXFMT RECDSP;
            EXCEPT RLS;
       Else;
            *In77 = %TLookup(003:Tab#:TabMsg); // 003 LOOKUP TAB# TABMSG 77
       EndIf;
       *In52 = *Off;
       *In07 = *Off;
       OPTN = *Blanks; // MOVE *BLANK OPTN
       EndSr;
       // ===========================================================
       //     6.   subroutine     C R E A T E    a new rec. /ADD
       // ===========================================================
       BegSr ADDSUB;
       *In77 = *Off;
       EXFMT GETKEY;                        //      get a rec.key.#
       Dow  *In03  = *Off and               //       If not F3 &
            CUST# <> 0;                     //    key# /= 0
            Chain(E) NUMRKY RECNUMR;        //      51=not yet
            *In51 = %ERROR;
            *In51 = NOT %Found;
            If   *In51 = *On;               //         on file.
                 NAMEF = *Blanks;      // MOVE *BLANK NAMEF
                 NAMEL = *Blanks;      // MOVE *BLANK NAMEL clear all
                 ADDR  = *Blanks;      // MOVE *BLANK ADDR  fields:
                 CITY  = *Blanks;      // MOVE *BLANK CITY
                 STATE = *Blanks;      // MOVE *BLANK STATE Fields not
                 //                 *  MOVE  *BLANK    SRCHC
                 //                 *  MOVE  *BLANK    CUSTY
                 //                 *  Z-ADD *ZERO     ZIP
                 ARBAL = *Zeros;  // Z-ADD *ZERO ARBAL
                 //  function keys could be used to toggle "dup." on and off (41
                 *In72 = %TLookup(006:Tab#:TabMsg); // 006 LOOKUP TAB# TABMSG
                 EXFMT RECDSP;                      //      add a record
                 If   *In03 = *Off;                 //      If not F3
                      Write RECNUMR;                //    Write the rec.
                      *In26 = *Off;
                 EndIf;
                 *In51 = *Off;
                 *In77 = *Off;
            Else;
                 *In77 = %TLookup(007:Tab#:TabMsg); // 007 LOOKUP TAB# TABMSG
            EndIf;                                  //      in51=1
            EXFMT GETKEY;                           //      get a rec.key.#
       EndDo;                                       //      while Not03 & #Not0
       OPTN = *Blanks; // MOVE *BLANK OPTN
       EndSr; // ADDSR EndSr ADDSub
       // ===========================================================
       //     2.   subroutine     UPDATE-CHANGE
       // ===========================================================
       BegSr UPDATE;
       EndSr;
       *In77 = *Off;
       Chain NUMRKY RECNUMR;                   //      52=rec.not found
       *In52 = NOT %Found;
       If   *In52 = *Off;                      //       rec.found
            *In72 = %TLookup(002:Tab#:TabMsg); // 002 LOOKUP TAB# TABMSG 72
            EXFMT RECDSP;
            If *In03 = *Off;                   //      If not F3
                 Update RECNUMR;               //      update the rec.
            Else;
                 EXCEPT RLS;                   //      or release it.
            EndIf;
       Else;
            *In77 = %TLookup(003:Tab#:TabMsg); // 003 LOOKUP TAB# TABMSG 77
            *In52 = *Off;
       EndIf;                                  //       rec.found
       OPTN = *Blanks;                         // MOVE *BLANK OPTN
       EndSr;
      /END-FREE
       // =============================================================
     ORECNUMR   E            RLS
       // =============================================================
** .------.-------.----.----   M E S S A G E S   ----.----.-------.-------.
001.------.-------.----.------=-------|-------=------.----.-------.-------.
002                 <<<<<<    U  P  D  A  T  E    >>>>>>
003 --------------------  The record was not found.  ---------------------
004                 <<<<<<    D  E  L  E  T  E    >>>>>>
005                <<<<<<    D  I  S  P  L  A  Y    >>>>>>
006                 <<<<<<    C  R  E  A  T  E    >>>>>>
007 ------------------  The record is already on file.  ------------------
008 ----------------------<<  THE FILE IS EMPTY  >>-----------------------
009 -------------------------  Bottom of file.  --------------------------
010                    the options are    2, 4, or 5

3 Responses to RPG-ILE FREE (format) subfile pgm (2)

  1. Glenn on January 10, 2011 at 11:51 am

    You could make a couple enhancements:

    - get rid of the KLISTS

    SetLL NUMRKY RECNUMR becomes
    SetLL cust# CUSMST1

    - replace all indicators with named indicators

    Dow *In03 = *Off and *In12 = *Off becomes
    dow not (exit or cancel)

    If *In94 = *On becomes
    If PageUp

    - use named constants

    ’2′ becomes Edit
    ’4′ becomes Delete
    etc.


    these are all good suggestions.
    -ed

  2. vicky on June 5, 2012 at 1:34 am

    hiii
    I am new to Subfile Programming. I want to add data in physical file using the subfile.
    How can I achieve this.
    plz tell me at vickyaggarwal20@gmail.com
    or update here.
    Thanks

  3. Vlad on September 10, 2012 at 11:16 am

    Hi,
    Could somebody please tell me where can I find
    RPG USERS GUIDE, book 26, Chap.8, pg.59 (V1R3)
    combining of Sample Programs, book 26 Chap.8, pgms. 3 & 5?

    Thanks.

Leave a Reply

Your email address will not be published. Required fields are marked. *
Comments will be approved as soon as possible.