What is an array
|
Array is short for "an array of variables of the same type."
An array is a way of grouping objects and variables together
so that they are easy to work with. An array consists of
three main parts. Each piece of data in an array is called an
element of an array. Each piece of data in an array is assigned
a unique index value, which will be called upon later. The
last part is the variable name, which is established at the
start of the array and must include the type. There are many
different types of arrays. A basic array consists of one variable
with one set of index numbers. There are more complex multi-dimensional
arrays with one variable but multiple sets of index numbers. You can
also make arrays of objects. Arrays are called upon by first their
variable name and then their index numbers.
|
Defining an Array
To declare an array or table, use the RPG IV definition specification.
The "D spec" allows you to code the array or table on a single line.
The keyword to use is DIM (dimension). This is where you specify the
number of elements in the table or array. For example, to create an
array named ITEMS with 200 elements, each 10 characters in length,
the following Definition spec can be used:
.....DName+++++++++++EUDS.......Length+TDB.Functions++++++++
D Items S 10A Dim(200)
To declare an array that is also used as a data structure subfield,
you must declare the array within the data structure. Unlike RPGIII,
RPG IV does not allow the array to be declared, and then used as a data
structure subfield. The following technique illustrates declaring an
array as a data structure subfield:
.....DName+++++++++++EUDS.......Length+TDc.Functions++++++++
D MyDs DS
D CustNo 7P 0
D MonthlySls 11P 2 Dim(12)
New Data Structure (DS) Facilities
This new DS support builds on the LIKEDS support added in V5R1
and adds a few more interesting capabilities that help round
out the language. Those of you who have been waiting
(and waiting and waiting) for RPG to add the capability for
multidimensional arrays will find that your wishes have
(kind of) been granted.
The first enhancement in this area is that the usage of the
DIM (Dimension) function is extended to allow it to be used
at the DS level <1>. The effect is similar to the use of the
OCCURS keyword but with one significant difference.
Individual occurrences of the DS are now directly accessible
via conventional array subscripting. Previously,
only the current occurrence, established by the OCCUR
operation, could be directly referenced. This meant that,
to perform even the simplest operation, such as comparing the
contents of two occurrences, required copying the data to
another field or DS, or using pointers to be able to
directly access multiple occurrences. The first If statement
below <2> demonstrates how to directly compare two elements.
The second If statement <3> demonstrates how qualified names
(a V5R1 addition for those who haven't been following the script)
can be used in conjunction with the new DS array support to
allow individual fields in different occurrences to be referenced.
<1> D MData DS Dim(12) Qualified
D QtySold 5 0
D Revenue 9 2
<2> C If MData(1) <> MData(2)
* Was average unit sale price for the month > $50?
<3> C If ( MData(Mth).Revenue /
C MData(Mth).QtySold )
C > 50
Example of Compile time Array
*====================================
*
*====================================
d CODE s 2 DIM(8) CTDATA PERRCD(4)
d DESC s 10 DIM(4) CTDATA PERRCD(1)
d x s 3 0
d INCODE s 2
d OUTDSC s 10
*
c eval x = 1
c INCODE LOOKUP CODE(x) 99
c if %Found
c eval OUTDSC = %trim(DESC(X))
c endif
*
c *entry plist
c parm INCODE
c parm OUTDSC
*
C eval *INLR = *on
*====================================
**
A1A2A3A4
**
Import
Local
Production
Return
So how does this lead us to multidimensional arrays?
The answer is the extension of support for complex (or nested)
DSs. For the first time, an RPG DS can now contain another DS.
To specify such a structure, simply use the new LIKEREC
keyword or LIKEDS (another V5R1 addition) within the DS as
shown in example <4> below. The result is that we now
have an array (Month) within the DS array (Year).
To reference the fields in a nested DS, we simply use an
extension of the DSName.FieldName method of qualifying names
that V5R1 introduced. As you will see from the example below,
the syntax is extended to DSName.NestedDSName.FieldName.
Strictly speaking, this does not constitute support for multidimensional
arrays within RPG because, for the purposes of operations such as MOVEA,
an array DS is not considered an array. However, as the following example
illustrates, we can achieve the desired effect.
<4> D Year DS Dim(20) Qualified
D Month LikeDS(Mdata) Dim(12)
C Eval Year(Yr).Month(Mth).Revenue = MonthTotal
If we wish to use three, four, or even more dimensions, we can do so simply
by nesting DSs to the required depth. Note that in the previous example,
even though the original DS Mdata is an array, this characteristic is not
copied by the LIKEDS. Only the individual components of the DS
(QtySold, and Revenue) are copied. Hence, there is a need for the DIM(12)
in the definition of Month.
Those of you who make use of those C functions and system APIs that
utilize nested structures will find this support appealing. It will
make mapping of these structures in RPG a far simpler job.
What else is new in the world of DSs? In addition to being able
to specify that a DS is externally described, we can now use the
keyword LIKEREC to specify that the structure takes on the "shape"
of a named record format. In what way is this different from a
conventional externally described DS? Anyone who has ever tried
to use a display file as the source of an external description
can answer that one. An externally described DS only contains
Input fields. In addition to the record name, the LIKEREC
keyword has an optional second parameter that allows you to
specify that the structure should contain all the fields from
the record format (*ALL), or be limited to input (*INPUT),
output (*OUTPUT), or key (*KEY) fields. These new features
have also been added to the "conventional" externally described
DS by adding the additional parameter to the EXTNAME keyword.
Sorting an Array - Example
D UOMArray 34DIM(100)
D UOMKey 2 OVERLAY(UOMArray)
D UOMDesc 30OVERLAY(UOMArray:3)
D UOMCode 2OVERLAY(UOMArray:33)
Now, you load the fields by saying
UOMKey(index) = xxx, UOMDesc(index) = xxx,
and UOMCode(index) = xxx
This way you have all your fields together.
If you wish to sort the arrays and keep the indecies
intact, simply sort by the subfield of your choice.
For example:
* sort by Description
C SORTA UOMDesc
* sort by Code
C SORTA UOMCode
%LOOKUP - Example
D Array S Like(Key) Dim(500)
D Inz(*AllX'FF')
D SeqArray S Like(Key) Dim(%elem(Array))
D Ascend
. . . . . . . . . . . . . . . .
C If %Lookup(Key: Array: 1: Count) = 0
. . . . . . . . . . . . . . . .
* Entries have been added, sort array and copy to sequenced version
C SortA Array
C Eval SeqArray = Array
. . . . . . . . . . . . . . . .
* Use sorted array for subsequent lookups
C If %Lookup(SearchKey:SeqArray:1:Count) > 0