RPG Free Format: Single Page Subfile SQLRPGLE Example Program *






 


#IBMiSample

The standard subfile has a limit of 9999 lines and works wery well.

But in case of heavy processing, loading the entire file can take a long time. So, in some cases is better to load one page at a time.

I received several comments to this statement, so I thought I'd clarify my opinion with two examples.


Scenario 1 small file:

The subfilesize is 20.

You have to process a file of 5000 records, so you may think this is a ideal scenario for a standard subfile processing, bat you want to filter only specific records, for example records with a flag=’X’ and creation date between two specific dates. The total number of this records is, for example, 280 so you get the first page after processing the entire file.

With a single page process, you get the first page after finding the first 20 records that match your filters. Faster then standard subfile processing.

Scenario 2 big file

The subfilesize is 20.

You have to process a file of 50 million records, bat obviously you want to filter only specific records, for example records with a flag=’X’ and creation date between two specific dates. The total number of this records is, for example 280, so you get the first page after processing the first 9999 records that match your filters (You scanned 50 million records before an answer!).

With a single page process, you get the first page after finding the first 20 records records that match your filters, and you are able to process the file to the end. Faster then standard subfile processing.

So, in some cases is better to load one page at a time.

That's how.

First of all look at this post and compile and populate these files to use this example.


Then copy e compile the following sources. 

Display file:
OT04SFV.DSPF
      * Description... Template Single Page Subfile SQLRPGLE Program
      * File Name..... OT04SF.DSPF
      * Author........ Aldo SUCCI from  idea of Nick Litten
      *                (https://www.nicklitten.com)
      * https://www.nicklitten.com/example-of-an-ibm-i-rpg-single-page-subfile
      * Date.......... Jan 21th 2019
      * Compile Instructions:
      * CRTDSPF FILE(YourLib/OT04SFV) SRCFILE(YourLib/OT04) SRCMBR(OT04SFV)
      *
     A                                      DSPSIZ(27 132 *DS4)
     A                                      REF(*LIBL/OTORD00F)
     A                                      PRINT
     A                                      INDARA
     A                                      ERRSFL
     A                                      HELP(01)
     A                                      CA03(03)
     A                                      CA05(05)
     A                                      CA12(12)
     A                                      PAGEUP(25)
     A                                      PAGEDOWN(26)
     A          R SFL01                     SFL
     A            SFLRRN         5S 0H
     A            S1OPT          1A  B  5  2
     A            OTCOR0    R        O   + 1EDTCDE(4)
     A            OTDTA0    R        O   + 1EDTWRD('  /  /  ')
     A            OTDTP0    R        O   + 1EDTWRD('  /  /  ')
     A            OTCCM0    R        O   + 1
     A            OTTIP0    R        O   + 1
     A            CLNOM0    R        O   + 1REFFLD(CLANA/CLNOM0 CLANA00F)
     A          R CTL01                     SFLCTL(SFL01)
     A                                      SFLSIZ(0019)
     A                                      SFLPAG(0019)
     A                                      OVERLAY
     A  30                                  SFLDSP
     A  31                                  SFLDSPCTL
     A  32                                  SFLCLR
     A                                  1  3'Template Single Page Subfile SQLRP-
     A                                      GLE Program'
     A                                      COLOR(WHT)
     A                                  3 12'__Chk_in'
     A                                   + 1'__ChkOut'
     A                                   + 1'RoomNb'
     A                                   + 1'Tr'
     A                                   + 1'Name'
     A          R CMD01
     A                                      OVERLAY
     A                                 25  3'F3=Exit  F5=Refresh'
     A            ERRORMSG     120A  O 26  2COLOR(RED)

RPG Free Program:
OT04SF.SQLRPGLE

      **FREE
       // Description... Template Single Page Subfile SQLRPGLE Program
       // File Name..... OT04SF.SQLRPGLE
       // Author........ Aldo SUCCI from  idea of Nick Litten
       //                (https://www.nicklitten.com)
       // https://www.nicklitten.com/example-of-an-ibm-i-rpg-single-page-subfile
       // Date.......... Jan 21th 2019
       //
       // Compile Instructions:
       // CRTSQLRPGI OBJ(YourLib/OT04SF) SRCFILE(YourLib/QRPGLESRC) SRCMBR(OT04SF)
       // OBJTYPE(*PGM)                                                                   //
       // Run instruction:
       // call OT04SF
       ctl-opt
        debug
        option(*nodebugio:*srcstmt)
        datfmt(*iso-) timfmt(*iso.)
        indent('| ') truncnbr(*yes) expropts(*resdecpos)
        copyright('| TEMPLATE Single Page Subfile SQLRPGLE Program')
        dftactgrp(*NO)
       ;
       dcl-f CLANA01L keyed usage (*input); // Customer File
       dcl-f OT04SFV workstn sfile(SFL01:rrn)  indDs(dspf); // Displayfile
       dcl-s p_Indicators pointer inz(%addr(*in));
       dcl-ds dspf qualified based(p_Indicators);
         help     ind pos(01);
         exit     ind pos(03);
         refresh  ind pos(05);
         previous ind pos(12);
         pageup   ind pos(25);
         pagedown ind pos(26);
         sflclr   ind pos(32);
         sfldsp   ind pos(30);
         sflctl   ind pos(31);
         sflEnd   ind pos(35);
       end-ds;
       dcl-s Position like(OTCOR0) ;
       dcl-s IndexPag like(OTCOR0) ;
       dcl-s PaginaST like(OTCOR0) dim(10000) ;
       dcl-s PaginaEN like(OTCOR0) dim(10000) ;
       dcl-s EndOfData char(1);
       dcl-ds dsp_fields extname('OTORD00F') end-ds;
       dcl-s rrn like(sflrrn);
       dcl-s pagesize zoned(2) inz(19);
       // *********************************************************************
       // PGM start
       // *********************************************************************
       exec sql
         set option commit = *none,
                               closqlcsr = *endmod;
       // initially let's force a refresh to load first page
       dspf.refresh = *on;
       dou dspf.exit or dspf.previous;
         if dspf.refresh;
           // Pointer of current page displayed
           IndexPag = 1;       // Page number
           PaginaST = 0;       // First record key of x Page
           PaginaEN = 9999999; // Last record key of x Page
           clearSubfile();
           setPage();
           loadSubfile();
         elseif dspf.pageUp;
           setPage();          // Return to the previous page
           pageUp();
         elseif dspf.pagedown;
           pageDown();         // Go to next page
         endif;
         showSubfile();        // show screen
       enddo;
       *inlr = '1';
       return;
       // *********************************************************************
       // Clear Subfile procedure...
       // *********************************************************************
       dcl-proc clearSubfile;
         dspf.sflEnd = *off;
         dspf.sflclr = *on;
         write ctl01;
         dspf.sflclr = *off;
       end-proc;
       // *********************************************************************
       // Build Subfile procedure...
       // *********************************************************************
       dcl-proc loadSubfile;
         dspf.sflEnd = *off;
         rrn = 0;
         exec sql
           fetch next from mycursor
             into :dsp_fields;
       // Start pointer of current page
         if sqlcode < 0 or sqlcode >= 100;
           OTCOR0 = 0;
         endif;
         PaginaST(IndexPag)= OTCOR0;
         dow sqlcode >= 0 and sqlcode < 100;
           GetCustomer(); // Get Customer name
           rrn += 1;
           write SFL01;
           if rrn = pagesize;
             leave;
           endif;
           // get next record
           exec sql
             fetch next from mycursor
               into :dsp_fields;
         enddo;
       // End pointer of current page
         PaginaEN(IndexPag)= OTCOR0; // Chiave x prossimo SETLL+1
         // if we didnt load a full page then set END OF SUBFILE
         if rrn < pagesize;
           dspf.sflEnd = *on;
         endif;
       end-proc;
       // *********************************************************************
       // Display Subfile procedure...
       // *********************************************************************
       dcl-proc showSubfile;
         if rrn < pagesize;
           errormsg = 'Start of data';
         endif;
         if rrn > 0;
           dspf.sfldsp = *on;
         else;
           dspf.sfldsp = *off;
           errormsg = 'No more data from OTORD00F!';
         endif;
         dspf.sflctl = *on;
         write cmd01;
         exfmt ctl01;
         clear ERRORMSG;
       end-proc;
       // *********************************************************************
       // Get Customer...
       // *********************************************************************
       dcl-proc GetCustomer;
         chain (OTCCL0) CLANA;
         if %found(CLANA01L);
         else;
           clear CLNOM0;
         endif;
       end-proc;

       // *********************************************************************
       // Declare cursor procedure...
       // *********************************************************************
       dcl-proc setPage;
         position = 0;
         if (IndexPag>1);
           position = PaginaEN(IndexPag-1)+1;
           if (dspf.pageup);
             position = PaginaST(IndexPag-1);
           endif;
         endif;
         exec sql
           close mycursor;
         exec sql
           declare mycursor scroll cursor for
             select *
               from OTORD00F
               where OTCOR0 >= :position
               order by OTCOR0
               limit 19
               for read only;
         exec sql
           open mycursor;
       end-proc;
       // *********************************************************************
       // Page up procedure...
       // *********************************************************************
       dcl-proc pageUp;
         // set start cursor RRN at first row of previous page
           clear position;
           EndofData = ' ';
       //  if rrn = pagesize;
           if IndexPag > 1;
             IndexPag = IndexPag - 1;
           endif;
       //  else;
       //    clear position;
       //  endif;
         // Build the subfile starting at *position*
         clearSubfile();
         loadSubfile();
         // If the cursor already in the top the list
         if rrn <= pagesize;
       //    errormsg = 'Start of customer list';
         endif;
         if IndexPag <= 1;
           errormsg = 'Start of customer list';
         endif;
       end-proc;
       // *********************************************************************
       // Page down procedure...
       // *********************************************************************
       dcl-proc pageDown;
         if (EndOfData='Y');
         else;
           IndexPag = IndexPag + 1;
         endif;
         // Build the subfile starting at *position*
         clearSubfile();
         setpage();
         loadSubfile();
         // If more to read then show sflend
         EndofData = ' ';
         if rrn < pagesize;
           errormsg = 'You have reached the bottom of the customer list.';
           EndofData = 'Y';
         endif;
       end-proc;

Don't forget to set the screen to 132 columns!


I appreciate all the comments made on this blog.

Comments

  1. Great job, thanks for clearing this out!

    ReplyDelete
  2. Replies
    1. Hi Nick, I just wanted to say thank you so much for providing me with that RPG source code. It was really helpful in getting the example I needed. I appreciate your willingness to help out and share your expertise. Thanks again!

      Delete

Post a Comment

Popular posts from this blog

(IBM i fans only) Efficient WRKSPLF with WSF - How to Search string into spooled files, Sort, and Generate PDFs on IBMi

(IBM i fans only) Detecting and Handling Non-Printable Characters in DB2 SQL Using LOCATE() and REPLACE() Functions

(IBM i fans only) How to Sniff User Access