Midrange News for the IBM i Community


Posted by: Harold Blaisdell
RPG Data Structures / Files
has no ratings.
Published: 12 Jan 2012
Revised: 23 Jan 2013 - 4109 days ago
Last viewed on: 24 Apr 2024 (12240 views) 

Using IBM i? Need to create Excel, CSV, HTML, JSON, PDF, SPOOL reports? Learn more about the fastest and least expensive tool for the job: SQL iQuery.

RPG Data Structures / Files Published by: Harold Blaisdell on 12 Jan 2012 view comments(8)

I have been asked to write several programs using some files that have 536 amount type fields as well as some key fields(The amount field are all identically defined). I need to get the 536 fields into an array. Code wise the only way I see to do it is create a data structure with the first field being a DIM(536) and then the rest of the array would be the actual names of the 536 fields. When I do my read the fields would get populated and then I could use the DIM field. I'm sure there is an easier way to create this Data Structure / Array but I am not sure how. Does someone have a better way????

 

Thanks in advance

Harold  

Return to midrangenews.com home page.
Sort Ascend | Descend

COMMENTS

(Sign in to Post a Comment)
Posted by: neilrh
Premium member *
Jackson, MI
Comment on: RPG Data Structures / Files
Posted: 12 years 3 months 13 days 7 hours 12 minutes ago

 

d fileds          ds                  likerec(filerec)
d arrVals         s                   like(fld001)
d                                     dim(536)
d                                     based(ptrVals)
d ptrVals         s               *   inz(%addr(fileds.fld001))

 

The above defines a DS like your file record format.  Then creates an array of 536 elements with attributes like fld001 (assume your first numeric field in the file), but we are not reserving memory space for this array we'll place it at the address contained in ptrVals.  ptrVals is initialised to the address for the first numeric field in the data structure.  Now the array will overlay the 536 file fields and you can reference then either by the fileds.[fieldname] OR by the array element name.  To load the ds just: 

chain (keyfld1:keyfld2) file fileds;

 and of course you can change the chain to read, reade, etc

Posted by: DaleB
Premium member *
Reading, PA
Comment on: RPG Data Structures / Files
Posted: 12 years 3 months 13 days 6 hours 28 minutes ago
Edited: Thu, 12 Jan, 2012 at 12:13:51 (4486 days ago)

Neil's solution is a good one, but assumes the 536 amount fields are contiguous in the file.

If not contiguous, is there a pattern? For example, if it's key001, amt001, key002, amt002, etc., you can modify Neil's definition:

     Dfileds           DS                  LIKEREC(filerec)
     DarrVals          DS                  DIM(536)
     D                                     BASED(ptrVals)
     D key                                 LIKE(fileds.key001)
     D amt                                 LIKE(fileds.fld001)
     DptrVals          S               *   INZ(%ADDR(fileds.key001))

If the fields are not contiguous, and there's no pattern, I'm afraid you will need to name them, and overlay with an array. Perhaps a /COPY member?

     Damtfields        DS
     D fld001
     D fld002
     D* ...
     D fld536
     D arrVals                             LIKE(fld001)
     D                                     DIM(536)
     D                                     OVERLAY(amtfields:1)

Posted by: hblaisdell
Premium member *
Comment on: RPG Data Structures / Files
Posted: 12 years 3 months 12 days 13 hours 36 minutes ago

This works. Thanks a million.

 

Harold

Posted by: bobcozzi
Site Admin ****
Chicagoland
Comment on: RPG Data Structures / Files
Posted: 12 years 3 months 12 days 8 hours 58 minutes ago
Edited: Fri, 13 Jan, 2012 at 09:43:29 (4485 days ago)

 

.....D myArr        DS
     D arrVals                             LIKE(fld001)
     D                                     DIM(536)

     D fldCnt       S            3S 0
      /free
        mySQL = 'SELECT ';
        for i = 1 to %elems(arrVals);
           fldCnt = i;
           mySql += 'FLD' + %editc(fldcnt:'X');
           if (i < %elems(arrVals)); 
             mySQL += ',';
           endif;
       endfor;
       mySQL = ' FROM MYFILE';
 
        // Do the declare cursor, open, thingy here...
       exec sql FETCH csr INTO :myArr;

 

I wrote this in this Comment, so I have (A) never tried it before, and (B) never testing it to see if its even valid... just a random thought.

Posted by: DaleB
Premium member *
Reading, PA
Comment on: RPG Data Structures / Files
Posted: 12 years 3 months 12 days 8 hours 30 minutes ago

Great idea. This is also off the cuff, not tested, but around line 16 I think you'll need:

       Exec SQL PREPARE stm FROM :mySQL;
       Exec SQL DECLARE csr CURSOR FOR stm;
       Exec SQL OPEN csr;

And, eventually, a CLOSE csr.

Posted by: neilrh
Premium member *
Jackson, MI
Comment on: RPG Data Structures / Files
Posted: 12 years 3 months 12 days 6 hours 38 minutes ago

I believe I did something like that at my former employers.  But they really hated dynamic SQL for frequent run or interactive stuff - it used to hog resources building the access each time, and they had a seriously in need of rewrite order entry process that was a system hog also - that 90% of the system users were using at any given time.

While I like those neat dynamic sql functions - there are limits to their usability on systems that are creaking at the seams.

Posted by: bobcozzi
Site Admin ****
Chicagoland
Comment on: RPG Data Structures / Files
Posted: 12 years 3 months 12 days 3 hours 55 minutes ago

Neil,

I've switched to nearly always using dynamic for Inquiry programs (subfile or web page lists) results. I do NOT notice a bit of difference at v5r4 and later.

Posted by: neilrh
Premium member *
Jackson, MI
Comment on: RPG Data Structures / Files
Posted: 12 years 3 months 12 days 3 hours 12 minutes ago

I agree it's generally not too big a deal - where it all breaks down is when your production box is running at 99.9% capacity with poorly written 20 year old RPG programs, being used by the vast majority of your users.  It's just enough to push things over the edge where it is noticable.

I could write dynamic sql and have no problems on development or warehousing box.  But put it live on the order entry machine and everything just died.  Then again if the buyers were working against a production deadline the entire systen would slow to a snails pace as they were all bashing the keyboards at a fevered pace.