Rpgarraysfortoday Part2
Rpgarraysfortoday Part2
Modernizing IBM i?
Let's Take Another Look at Data Access
Speaker: Bill Langston
Sponsored by:
Together with my partner Susan Gantner, I devote my time to educating developers on techniques and technologies
to extend and modernize their applications and development environments. Together Susan and have authored
many technical articles for a number of publications, including IT Jungle's RPG Guru column (www.itjungle.com).
The easiest way to find our articles is to use our Authory web site authory.com/JonParisAndSusanGantner/
In addition to my work with Partner400 I am also a founding member of the System i Developer (SiD) education
consortium - originators of the highly successful RPG & Db2 Summit. More on SiD's offerings at
SystemiDeveloper.com
salesByMonth = %list( 12: 20: 99: 0: 125: 33: 27: 288: 350: 1234:
765: 552 );
maxValue = %maxarr(salesByMonth);
minValue = %minArr(salesByMonth);
Dsply ( 'High index ' + %char(%maxarr(salesByMonth)) +
' - value: ' + %char(salesByMonth(%maxarr(salesByMonth))));
Dsply ( 'Low index ' + %char(%minarr(salesByMonth)) +
' - value: ' + %char(salesByMonth(%minarr(salesByMonth))));
%MINARR and %MAXARR fill that gap. %MINARR returns the index of the lowest value in the array and
%MAXARR returns the index of the highest. These BIFs can be applied to a conventional array or to a DS array.
The example is a little unrealistic in that it assumes all 200 array entries are filled. In practice, I would expect to have
a count of the number of active elements and use that together with %SubArr to restrict the scope of the BIF to the
number of active elements. e.g something like:
As you will see in part 2 - an even better approach would be to use a dynamically sized array which would avoid the
need for the %SubArr and the active element count.
You could, of course, omit the intermediate step of storing the index if you only wanted one item. For example to
retrieve just the name you could do this:
If there are multiple consecutive spaces they will be ignored so there will be no "empty" array elements returned.
A warning though. %SPLIT ignores consecutive separators. Most of the time that is a good thing but can present a problem in
some circumstances. For example if you were processing a CSV file containing the string "ABC",123,,"DEF" using CPYFRMIMPF
it would result in four fields. “ABC”, 123, blank, and “DEF”. However, %SPLIT would only produce three array elements because
the second comma would be ignored. So, in these circumstances some pre-processing of the input may be required.
// Instead of this:
If ( orderStatus = OVERDUE ) or
( orderStatus = PENDING ) or
( orderStatus = CANCELLED ) or
( orderStatus = COMPLETE );
Modernizing IBM i?
Let's Take Another Look at Data Access
Speaker: Bill Langston
Sponsored by:
Those days are now behind me - I can now make the array potentially massive without using up more memory than I
actually need.
An added benefit is that RPG keeps track of the current capacity of the array and so I can use any array operation
(such as IN, SORTA or %LOOKUP) more easily. No need to concern myself with using %SUBARR to restrict the
operation to active elements. That alone is good enough reason to use this support.
IBM have added this feature while still maintaining the existing array support. So there's nothing new to learn, just
some nice additional capabilities to the things we are already familiar with.
See the Notes page for links to details of the usage of *KEEP
© Copyright Partner400, 2023. Page 23
Notes
The idea that %ELEM can be used on the left or right hand side of an expression takes a bit of getting used to.
For example if we wanted to increase the maximum number of array elements by 50% we could do this:
I have written a few articles on the use of dynamic arrays for ITJungle.
https://www.itjungle.com/2020/07/20/guru-dynamic-arrays-come-to-rpg/
https://www.itjungle.com/2020/08/17/guru-dynamic-arrays-come-to-rpg-the-next-part-of-the-story/
https://www.itjungle.com/2020/10/12/guru-dynamic-arrays-come-to-rpg-limitations-circumventions-and-more/
If you are interested in using dynamic arrays as parameters then the last of those is the one you need to study as it
is an area that I do not cover in the session.
Note that %ELEM cannot increase the number of elements for an array beyond the maximum. So if the array is
defined as:
Dcl-S MYArray Char(12) Dim( *Var : 1000 );
Then
%ELem(MyArray : 1001);
Will also fail because it attempts to increase the current size of the array beyond its declared maximum.
For i = 1 to 50;
VaryArray(*Next) = i;
EndFor;
Exec SQL
Declare animalsCursor cursor for
Select * from ANIMALS where type = :type;
Exec SQL
Open animalsCursor;
Exec SQL
Fetch from animalsCursor for 1000 rows into :results;
You can also use a *VAR type of dynamic array but ...
• I found I had to use an "Insensitive Scroll" cursor in order to be able to obtain
the row count prior to the fetch
• Then use that count to set the number of elements
Exec SQL
Close animalsCursor;
Cannot be ...
• Used as a parameter unless the prototype specifies
Options(*VarSize)
• Used for procedure return values
• Used in prototype parameter definitions
• Used on fixed-form calculations (i.e. the old C-specs)
• And a number of other more esoteric restrictions ...
✦ See the Notes page for the full list
A varying-dimension array can only be a top-level definition, either a standalone array or a data structure array.
Tables, multiple-occurrence data structures, subfields, procedure return values, and procedure parameters are not
allowed.
A varying-dimension array cannot be used in fixed-form calculations.
A varying-dimension array cannot be based on a pointer.
A varying-dimension array cannot be imported or exported.
When a varying-dimension array is passed as a parameter to a prototyped procedure or program, the parameter
must be defined with OPTIONS(*VARSIZE).
A varying-dimension array cannot have type Object.
A varying-dimension array cannot be null-capable.
A subfield of a varying-dimension data structure array cannot be null-capable unless the null-indicator is also a
subfield in the same data structure.
A varying-dimension array cannot appear on an Input specification unless an index is specified.
A varying-dimension array cannot appear on an Output specification unless an index is specified.
A varying-dimension array element cannot appear on a Lookahead Input specification.
A varying-dimension array cannot be a compile-time array or a pre-run array. The CTDATA and FROMFILE
keywords cannot be used.
That's All
Folks
More questions? e-mail me at:
Modernizing IBM i?
Let's Take Another Look at Data Access
Speaker: Bill Langston
Sponsored by: