RPG: Passing lists

This Q&A forum allows users to post and respond to "How Do I Do ....." questions. Please do not use to report (suspected) errors - you must use your regional help desk for this. The information contained in this forum has not been validated by LANSA and, as such, LANSA cannot guarantee the accuracy of the information.
Post Reply
mwilliams
Posts: 15
Joined: Sat May 28, 2016 1:45 am

RPG: Passing lists

Post by mwilliams » Thu Sep 26, 2019 7:37 am

I was wondering what the parameter(s) would look like in an rpg program when a working list(s) are passed using PASS_LST. Is it just multi-occurrence data structures or data structure arrays. I'm wanting to send a list to the rpg program and actually receive another list back.

Wondering if there is an example somewhere that I can look at.

atostaine
Posts: 475
Joined: Wed Jan 20, 2016 7:38 am

Re: RPG: Passing lists

Post by atostaine » Thu Sep 26, 2019 10:34 am

Art Tostaine

LANSAGuru
Posts: 68
Joined: Thu Mar 24, 2016 5:31 am

Re: RPG: Passing lists

Post by LANSAGuru » Fri Sep 27, 2019 12:53 am

LANSA calling 3GL is pretty straight foward. See the CALL command with 3GL variation.
Parameters are passed in order defined.

Lists are special and pass 3 variable to the 3 GL, that list, number of enteries, current entry.

https://docs.lansa.com/14/en/lansa015/i ... L_PASS_LST

I can't remember if you pass fields and lists if the fields come first or the list comes first...easy enough to work out with a few examples. There are some caveats, etc... in the doco to be aware of, but simple enough.

As usual write a stand alone sample to make sure you understand it before integrating into your application...it'll save time in the end. And if you feel generous, post the code here for posterity.

Paul

====
found something, I guess this answers the questions, single parms first, followed by all lists passed in order
something like this in RPG...
List has 9999 rows possible (max list size in RDML for this program)
Passing 3 regular parms, and then passing the list (represented by 3 parms)

* Lansa Multiple occurance Data Structure
D VBGData DS OCCURS(9999)
D PartGroupDesc 75a
D MakeDesc 50a
D ModelDesc 50a
D EngineDesc 50a
D YearFrom 2p 0
D YearTo 2p 0
D ApplText 50a
D Applications 3p 0
D PerCarQty 3p 0
D CatLineCode 3a

* Incoming parameters
C *ENTRY Plist
C PARM WSWUSRe 10
C PARM WPartNumber
C Parm WERROR
C PARM VBGData
C Parm WCTR1 7 0
C Parm WCUR1 7 0

mwilliams
Posts: 15
Joined: Sat May 28, 2016 1:45 am

Re: RPG: Passing lists

Post by mwilliams » Sat Sep 28, 2019 8:51 am

Hey thanks, your example is what I was looking for. I do have one issue that I was wondering if you may have an answer to. My program has two lists. One is used as input and the other is used as output. when I call my program from my vlf-one app, if I return 100 rows or less, it seems to work fine, but anything over that and my vlf-one app crashes. The error in the LWEB_JOB job log is "Message : (0192) - Attempt to retrieve list entry from an unallocated page space. Routine : X_Get_Entry_Ext_Simple2." Now if I do a Inz_List on the list that I use as output, then my program doesn't crash but all data after the 100th record gets skewed. I've tried using both data structure arrays and multi occurrence data structures. I was wondering if you may have any clues.

Here is my Server Routine:

Code: Select all

Def_List Name(#SearchSQLs) Fields(#STD_TEXTL) Counter(#STD_INT) Type(*WORKING) Entrys(*MAX)
Def_List Name(#InstanceList_Columns) Fields(#shdn04 #shnm37 #shnm39 #shtx56) Type(*WORKING) Entrys(*MAX)

Def_List Name(#iList) Fields(#STD_TEXTL) Type(*WORKING) Entrys(25)
Def_List Name(#oList) Fields(#shdn04 #shnm37 #shnm39 #shtx56) Counter(#oListCnt) Type(*WORKING) Entrys(500)
Define Field(#oListCnt) Type(*DEC) Length(7) Decimals(0)

Clr_List Named(#iList)
Clr_List Named(#oList)
Clr_List Named(#InstanceList_Columns)


* load input list
Selectlist Named(#SearchSQLs)
  Add_Entry To_List(#iList)
Endselect

* grab data
Call Pgm(OPR3700) Pass_Lst(#ilist #olist)

* load return list
Selectlist Named(#olist)
  Add_Entry To_List(#InstanceList_Columns)
Endselect

* cleanup
Clr_List Named(#iList)
Clr_List Named(#oList)



And my program (currently using multi occurrence ds):

Code: Select all

       ctl-opt option(*srcstmt: *nodebugio) debug;
     F*------------------------------------------------------------------------*
     F*N PROGRAM NAME - OPR3700                                                *
     F*------------------------------------------------------------------------*
     F*P Copyright Kerridge Commercial Systems 2018                            *
     F*------------------------------------------------------------------------*
     F*D SD-One: PDF Search                                                    *
     F*------------------------------------------------------------------------*
     F*S PURPOSE:                                                              *
     F*S    This program is the backend program for the PDF search option in   *
     F*S    SD-One.  It is called from a lansa server module and communicates  *
     F*S    via Lansa exchange lists.                                          *
     F*S                                                                       *
     F*S SPECIAL NOTES:                                                        *
     F*S                                                                       *
     F*M ----------------------------------------------------------------------*
     F*M TASK       DATE   ID  DESCRIPTION                                     *
     F*M ---------- ------ --- ------------------------------------------------*
     F*V 8000013444 092519 275 MINCRON MSS/HD RELEASE 12.2                     *
     F*M ----------------------------------------------------------------------*
       //‚----------------------------------------------------------------------
       //‚Files
       //‚----------------------------------------------------------------------
       dcl-f shqhfop usropn;

       //‚----------------------------------------------------------------------
       //‚Constants
       //‚----------------------------------------------------------------------

       dcl-c TRUE                      const('1');
       dcl-c FALSE                     const('0');
       dcl-c SQL_SUCCESS               const('00');

       //‚----------------------------------------------------------------------
       //‚Working fields
       //‚----------------------------------------------------------------------
       dcl-s pssr         ind;
       dcl-s i            int(10) inz;
       dcl-s j            int(10) inz;
       dcl-s sqlRowCount  int(10) inz(%elem(sqlRows));
       dcl-s rowCount     int(10);
       dcl-s lastRow      int(10);
       dcl-s sql          varchar(1024);
       dcl-s whereClause  varchar(512);

       dcl-ds pgmds psds;
         pgmq *proc;
         MsgID    char(7)  pos(40);
         MsgData  char(80) pos(91);
       end-ds;

       dcl-s inListCnt      packed(7: 0);
       dcl-s inListCur      packed(7: 0);
       dcl-s outListCnt     packed(7: 0);
       dcl-s outListCur     packed(7: 0);
       dcl-ds inList  likeds(inList_t) occurs(25);
       dcl-ds outList likeds(outList_t) occurs(500);
       dcl-ds sqlRows likeds(outList_t) dim(500) inz;

       dcl-ds inList_t qualified template;
         inSql            char(75);
       end-ds;

       dcl-ds outList_t qualified template;
         formTitle        like(shdn04);
         formTran         like(shnm37);
         formType         like(shnm39);
         formPath         like(shtx56);
       end-ds;

       //‚----------------------------------------------------------------------
       //‚Procedure Prototypes
       //‚----------------------------------------------------------------------

       //‚----------------------------------------------------------------------
       //‚Entry parameter list prototype and declaration
       //‚----------------------------------------------------------------------
       //dcl-pi *n;
       //  inList         likeds(inList_t) Dim(25);
       //  inListCnt      packed(7: 0);
       //  inListCur      packed(7: 0);
       //  outList        likeds(outList_t) Dim(500);
       //  outListCnt     packed(7: 0);
       //  outListCur     packed(7: 0);
       //end-pi;
     c     *entry        plist
     c                   parm                    inList
     c                   parm                    inListCnt
     c                   parm                    inListCur
     c                   parm                    outList
     c                   parm                    outListCnt
     c                   parm                    outListCur

       /free
         exsr loadList;

         exsr eoj;
         return;
       //‚----------------------------------------------------------------------
       //‚Eoj - Handle program termination/cleanup
       //‚----------------------------------------------------------------------
       begsr eoj;

         if (%open(shqhfop));
           close shqhfop;
         endif;

         *inlr = TRUE;

       endsr;
       //‚----------------------------------------------------------------------
       //‚Eoj - Load up the list of pdf entries based off of the query
       //‚----------------------------------------------------------------------
       begsr loadList;

         //‚Build the query string
         for i = 1 to inListCnt;
           %occur(inList) = i;
           if (whereClause <> *blanks);
             whereClause += ' AND ';
           endif;

           whereClause += inList.inSql;
           //whereClause += inList(i);
         endfor;

         sql  = 'Select SHDN04, SHNM37, SHNM39, SHTX56 ';
         sql += 'From OPQOP023A ';
         sql += 'Where ' + whereClause;

         //‚Load the data into the outList array
         exec sql close csr;
         exec sql prepare stmt from :sql;
         exec sql declare csr cursor for stmt;

         reset sqlRows;
         exec sql open csr;
         exec sql fetch csr for :sqlRowCount rows into :sqlRows;
         exec sql get diagnostics :rowcount = ROW_COUNT,
                                  :lastrow = DB2_LAST_ROW;

         j = 0;

         dow (rowcount > 0 and j < %elem(outList));
           for i = 1 to rowcount;
             j += 1;

             if (j <= %elem(outList));
               //eval-corr outList(j) = sqlRows(i);
               %occur(outList) = j;
               eval-corr outList = sqlRows(i);
             else;
               leave;
             endif;
           endfor;

           rowcount = 0;
           if (lastrow <> 100 and j < %elem(outList));
             clear sqlRows;
             lastrow = 0;
             exec sql fetch csr for :sqlRowCount rows into :sqlRows;
             exec sql get diagnostics :rowcount = ROW_COUNT,
                                      :lastrow = DB2_LAST_ROW;
           endif;
         enddo;

         exec sql close csr;

         //‚Set counters for lansa server module
         %occur(inList) = 1;
         %occur(outList) = 1;
         outListCnt = j;
         outListCur = 0;

       endsr;
       //‚----------------------------------------------------------------------
       //‚*inzsr - initialize
       //‚----------------------------------------------------------------------
       begsr *inzsr;

         if (1 <> 1);
           open shqhfop;
         endif;

       endsr;
       //‚----------------------------------------------------------------------
       //‚*pssr - exception
       //‚----------------------------------------------------------------------
       begsr *pssr;

         if (not pssr);
           pssr =  TRUE;
           dump(a);
           exsr eoj;
         endif;

         return;

       endsr; 

atostaine
Posts: 475
Joined: Wed Jan 20, 2016 7:38 am

Re: RPG: Passing lists

Post by atostaine » Sat Sep 28, 2019 11:10 am

Are you using entrys(*max)? I’d bet to pass to RPG you need to have a defined number of entries.
Art Tostaine

mwilliams
Posts: 15
Joined: Sat May 28, 2016 1:45 am

Re: RPG: Passing lists

Post by mwilliams » Sat Sep 28, 2019 10:49 pm

No, I've got my ilist defined as 25 entries and my olist defined as 500 entries.

Code: Select all

Def_List Name(#iList) Fields(#STD_TEXTL) Type(*WORKING) Entrys(25)
Def_List Name(#oList) Fields(#shdn04 #shnm37 #shnm39 #shtx56) Counter(#oListCnt) Type(*WORKING) Entrys(500)

Post Reply