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.
RPG: Passing lists
Re: RPG: Passing lists
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
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
Re: RPG: Passing lists
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:
And my program (currently using multi occurrence ds):
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;
Re: RPG: Passing lists
Are you using entrys(*max)? I’d bet to pass to RPG you need to have a defined number of entries.
Art Tostaine
Re: RPG: Passing lists
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)