d-spec d-lights - helpsystems in rpg/400. notice continuation of values. character values continued...

21
Your Partner in System i Education Jon Paris Jon.Paris @ Partner400.com www.Partner400.com SystemiDeveloper.com D-Spec D-Lights Agenda A couple of reminders on basics Mapping Indicators Using the INDDS keyword Overlaying the *IN array D-spec discoveries Lesser known capablities Sorting and searching © Copyright Partner400, 2006 - 2007 D-Spec D-lights - Page: 1-2

Upload: ngokhanh

Post on 08-Apr-2018

223 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: D-Spec D-Lights - HelpSystems in RPG/400. Notice continuation of values. Character values continued with - continue with first column in keywords on the continuation line

Your Partner in System i Education

Jon ParisJon.Paris @ Partner400.comwww.Partner400.comSystemiDeveloper.com

D-Spec D-Lights

Agenda

A couple of reminders on basicsMapping Indicators

Using the INDDS keywordOverlaying the *IN array

D-spec discoveriesLesser known capablities

Sorting and searching

© Copyright Partner400, 2006 - 2007 D-Spec D-lights - Page: 1-2

Page 2: D-Spec D-Lights - HelpSystems in RPG/400. Notice continuation of values. Character values continued with - continue with first column in keywords on the continuation line

External NamesThe system's 10 character limit still appliesRPG is considering adding the ability to use the ALIAS name

But as of V5R4 it hasn't happened

More on mapping file fields to Data Structures later

Internal NamesUp to 4096 characters long

Yes really!

Ellipsis (...) are used to continue names that require multiple linesNot often used except for when a procedure name exceeds 14 charactersOr when the field name is indented by a number of characters

When used the balance of the definition is placed on the next line

D ThisIsAReallyLongProcedureName... D PR

Names on the D-spec

© Copyright Partner400, 2006 - 2007 D-Spec D-lights - Page: 3-4

Page 3: D-Spec D-Lights - HelpSystems in RPG/400. Notice continuation of values. Character values continued with - continue with first column in keywords on the continuation line

Defining Named Constants

Specified by C in DS columnNo length allowedValue specified in the Keyword area

CONST( ..... ) is optionalIBM's examples include it - but why bother !

Literals can be continued in keyword area of next lineCharacter literals require continuation characters

+ (plus) continues at first non-blank- (minus) continues at first position

Numeric literals do not need a continuation character

DName+++++++++++ETDsFrom+++To/L+++IDc.Keywords+++++ +++++++++++++++.....

D Upper C CONST('ABCDEF GHI-D JKLMNOPQRSTUV WXYZ')

D Lower C 'abcdefghijkl mnopqrs+D tuvwxyz '

D BigNumber C CONST(23456D 789)

Named constants are not new except in the way they are defined. However, you will find that due to the use of the new free-format Factor 2 C spec, named constants are not needed as much as they were in RPG/400. Notice continuation of values.

Character values continued with - continue with first column in keywords on the continuation line.Character values continued with + continue with first non-blank column in keywords on continuation line.Numeric values require no continuation character and continue with the first numeric character on continuation line.

© Copyright Partner400, 2006 - 2007 D-Spec D-lights - Page: 5-6

Page 4: D-Spec D-Lights - HelpSystems in RPG/400. Notice continuation of values. Character values continued with - continue with first column in keywords on the continuation line

D-Spec Keywords - OVERLAY

OVERLAY replaces the need for From/To definitionsNote the use of *Next, which was added in V4R4

The field follows the previous one that was OVERLAY'd on the same fieldThis could have been used in place of the "16" in the first example

Note indentation of subfield namesNote particularly the use of a space following the D

We strongly recommend that you follow this practice

Can be used against a field name OR the DS name

D personalData DS INZ D name 30 D firstName 15 Overlay(name ) D lastName 15 Overlay(name :16) D phone_No 10 D area_Code 3 Overlay(phon e_No) D local_No 7 Overlay(phon e_No:*Next) D status 1 INZ('I')

D myDataStruct DS D numField 7s 0 D charField 7a Overlay(myDa taStruct)

Note the use of "floating" subfield names to show structure.

Area_Code overlays first 3 positions of phone number (pos 31-33 of DS). Local_No overlays the last 7 positions of phone number (pos 34-40 of DS). Use of OVERLAY to "subdivide" or redefine fields is recommended because of the increased maintainability. If fields are added to the DS, or the length of a field is changed, fields defined in this way will "self-adjust" - unlike the old From - To method that requires modification whenever such changes are made.

The INZ keyword can be used at the DS level and/or the subfield level. Note the entire DS initialized to blanks except status, initialized to "I".

Rules for OVERLAY use:Optional position parameter may be a numeric literal, numeric named constant, or a built-in function As of V4R4, *Next may be used instead of the fixed position parameter.Length notation must be used on the overlaying field.If an array is overlaid, keyword applies to each element of the array.

© Copyright Partner400, 2006 - 2007 D-Spec D-lights - Page: 7-8

Page 5: D-Spec D-Lights - HelpSystems in RPG/400. Notice continuation of values. Character values continued with - continue with first column in keywords on the continuation line

LIKE and DTAARA Keywords

Alternatives to DEFINE op code (previously DEFN)

LIKE keyword functions similarly to *LIKE DEFINELength, decimal positions and data type are copied

Length adjustments with + or - in To/Len column

May be used with fields, subfields, and arrays Arrays must still specify DIM keyword

i.e. If you reference an array with LIKE ... the DIM is not inherited

// Define a field LIKE an existing one D MonthTotal S 7 2 D TotMonths S +2 LIKE(MonthTo tal) D MonthArray S LIKE(MonthTo tal) DIM(12)

// Define a field LIKE an array element D CompanyArray S 3a DIM(20) D CompanyCode S LIKE(Company Array) D StoreCode S LIKE(Company Code) DTAARA(*LDA) // StoreCode is stored in the first 3 characters of the LDA

Although the dimensions of an array are not inherited along with the LIKE keyword, You can define one array exactly like another by using the built-in function %Elem to copy the number of elements in the parent array.

© Copyright Partner400, 2006 - 2007 D-Spec D-lights - Page: 9-10

Page 6: D-Spec D-Lights - HelpSystems in RPG/400. Notice continuation of values. Character values continued with - continue with first column in keywords on the continuation line

D SaveRec E DS ExtName(Pro duct) D Prefix('SAV .')

Keywords Used for Data Structures

Keyword Description

INZ{(constant{:*ExtDft or *User})} Initialize to a value

OCCURS(number) Number of occurrences in multiple occurrence DS

OVERLAY(name:{pos or *Next}) Redefines subfields in a DS

EXTNAME(name{:fmt_name}{: fieldtype} ) Data Structure is externally described

EXTFLD(fldname) External field name being renamed

PREFIX(prefix_name) Prefix subfields in an externally described DS

QUALIFIED Subfields in DS are qualified by DS name

LIKEDS(DS_name) Creates identical subfields as in DS_name

LIKEREC( fmt_name { : fieldtype} ) Similar to EXTNAME but can be used within a DS

DIM(number) Creates a Data Structure Array

Note that the PREFIX keyword can be used on externally described data structures to rename fields as it does on the F spec. This can be quite useful if the programmer needs to save the values of a record to compare them to the next record's values, for example.

If the prefix value is enclosed in quotes, it can include a "." (period) - this allows a qualified name to be created. This same technique can be used on F-specs. In the example shown, if the record format named PRODUCT contained a field named PRODCD, then that field would be renamed as SAV.PRODCD.

The *EXTDFT parameter is only allowed for externally described data structures. It initializes externally described data-structure subfields with the default values from the DFT keyword in the DDS. You can override the value specified in the DDS by coding INZ with or without a parameter on the subfield specification.

Note that we will be discussing some of the 3 V5R2 keywords in more detail on later charts.

The LIKEREC keyword differs from EXTNAME in one significant aspect - it can only reference a record format used in the program.

© Copyright Partner400, 2006 - 2007 D-Spec D-lights - Page: 11-12

Page 7: D-Spec D-Lights - HelpSystems in RPG/400. Notice continuation of values. Character values continued with - continue with first column in keywords on the continuation line

Keywords Short Description

ALIGN Align Integer & Float on natural boundary

BASED(ptr) The basing pointer (ptr) contains the location of the storage holding the value for the field

DATFMT(format) Specifies the date type for a D field

EXPORTThe storage for the field is allocated in this module, but may be used in other modules in this program

EXTPGM(name) The program defined by this prototype

EXTPROC(name) The procedure defined by this prototype

IMPORT Storage for this item is allocated in another module.

OPTIONS(parm_passing_options) Used in prototypes to determine how parameter is passed

PACKEVEN Zero out the "unused" digit of an even packed field

PROCPTR Defines a pointer as a procedure pointer. Only allowed with data type '*' (pointer)

STATIC The data item is allocated in static storage so that it will retain it's value between procedure calls

TIMFMT Specifies the time type for a T field

Other D Spec Keywords

© Copyright Partner400, 2006 - 2007 D-Spec D-lights - Page: 13-14

Page 8: D-Spec D-Lights - HelpSystems in RPG/400. Notice continuation of values. Character values continued with - continue with first column in keywords on the continuation line

FDisplay CF E WORKSTN INDDS(Ds pInd) D DspInd DS * Response indicators D Exit 3 3N D Return 12 12N * Conditioning indicators D Error 31 31N D StDateErr 32 32N D EndDateErr 33 33N

C If StartDate < Toda y C Eval StDateErr = *On C EndIf

C Eval EndDateErr = End Date < StartDate C Eval Error = StDateEr r or EndDateErr C ExFmt TestRec

C If Exit or Return

Named Indicators and INDDS

Use real names for your display indicators !F-spec keyword INDDS ties the external indicators to the named DS

An alternative approach to the indicator defintion is shown on the next page

This example illustrates the use of the INDDS (indicator Data Structure).

Note the definition of the DSPIND data structure. When this is specified on the F spec, the programmer MUST use the indicators in the data structure and NOT the numbered indicators to control this file. For example, in this program, if the programmer turned on indicator *IN31 directly in the program logic, it would have zero impact on the display file. The program logic must refer to the indicator as "Error" to turn it on or off in order for it to have an impact on the display file.

This is the DDS for the display file used in the RPG example:

INDARA R R TESTREC CF03(03) C F12(12) 5 11'Start Dat e: . .' STARTDATE L 5 27DATFMT(*US A) 32 DSPATR(RI PC) 32 5 39'Date cann ot be earlier than today' 7 11'End Date: . . .' ENDDATE L 7 27DATFMT(*US A) 33 DSPATR(RI PC) 33 7 39'Date must be later than Start Date' 31 10 21'Please co rrect above error'

In the example on the following page, we have also incorporated the associated indicator number in the indicator's name. Some people like this approach as it enables the programmer to see the indicator number without having to look at the Indicator Data Structure

© Copyright Partner400, 2006 - 2007 D-Spec D-lights - Page: 15-16

Page 9: D-Spec D-Lights - HelpSystems in RPG/400. Notice continuation of values. Character values continued with - continue with first column in keywords on the continuation line

FDisplay CF E WORKSTN INDDS(Ds pInd) D DspInd DS * Response indicators D Exit_3 N Overlay( DspInd: 3) D Return_12 N Overlay( DspInd: 12) * Conditioning indicators D Error_31 N Overlay( DspInd: 31) D StDateErr_32 N Overlay( DspInd: 32) D EndDateErr_33 N Overlay( DspInd: 33) /Free If StartDate < Today; StDateErr_32 = *On; EndIf; EndDateErr_33 = EndDate < StartDate; Error_31 = StDateErr_32 or EndDateErr_33; ExFmt TestRec;

If Exit_3 or Return_12;

Named Indicators and INDDS

Use the OVERLAY keyword to avoid From/To notationSome people find this a more better approach

Note: In this case we have incorporated the indicator number in the name

© Copyright Partner400, 2006 - 2007 D-Spec D-lights - Page: 17-18

Page 10: D-Spec D-Lights - HelpSystems in RPG/400. Notice continuation of values. Character values continued with - continue with first column in keywords on the continuation line

Mapping the *IN Array

Don't want to use the INDDS approach?You can always map the standard indicator array with a "Based" DS

Do you use the *INKx Indicators?A similar approach can be used

Use %Addr(*INKA) to initialize the basing pointerDon't foget that there are only 24 indicators in the set!

There is no *INKO See the Notes page for an example of how this is done

D DspInd DS Based(pIndic ators) // Response indicators D Exit N Overlay(DspI nd: 3) D Return N Overlay(DspI nd: 12) // Conditioning indicators D Error N Overlay(DspI nd: 31) D StDateErr N Overlay(DspI nd: 32) D EndDateErr N Overlay(DspI nd: 33) D pIndicators S * Inz(%Addr(*I n))

Unlike the INDDS approach, these named indicators DO directly affect the content of their corresponding *IN indicator. If we EVAL Error = *On, then indicator *IN30 was just turned on. This often makes this a better approach for those who use program described (i.e. O-spec) based files rather than externally described printer files.

Those of you who use the *INKx series of indicators to identify function key usage need not feel left out. A similar technique can be used. IN this case the pointer is set to the address of *INKA. The other 23 function key indicators are in 23 bytes that follow. IBM have confirmed many times that for RPG IV this will always be the case.

D FunctionKeys DS Based(pKxIndicators) D thisIsKC N Overlay(FunctionKeys: 3) D thisISKL N Overlay(FunctionKeys: 12)

D pKxIndicators S * Inz(%Addr(*InKA))

© Copyright Partner400, 2006 - 2007 D-Spec D-lights - Page: 19-20

Page 11: D-Spec D-Lights - HelpSystems in RPG/400. Notice continuation of values. Character values continued with - continue with first column in keywords on the continuation line

An Easy Way to Name Indicators

FCustomer IF E K Disk FCustDisp CF E WorkStn

D ExitRequest C 3 D CustFound C 20

C ExFmt CustDispR

C DoW Not *IN(ExitRequest)

C CustNum Chain Customer C Eval *IN(CustFound) = %Fo und(Customer) C ExFmt CustDispR

C EndDo

This is a technique can be used to gradually name i ndicatorsIt can be readily applied during maintenance

Whereas the previous methods require a greater effort

It takes advantage of the fact that *IN is an arrayConstants can be used to supply the indicator number

Once you discover the purpose of an indicator

NAME IT!

This example uses an old technique that many folks used even in RPG/400. Simply use named constants as indexes into the *IN array. This may be a better solution for modifying existing code, since it can be applied gradually.

As you discover the purpose of an indicator, give it a name and establish a constant for the indicator value. There now - that didn't hurt did it!

Always remember - the next person who needs to know what *IN57 = *On means may be YOU!

© Copyright Partner400, 2006 - 2007 D-Spec D-lights - Page: 21-22

Page 12: D-Spec D-Lights - HelpSystems in RPG/400. Notice continuation of values. Character values continued with - continue with first column in keywords on the continuation line

Hidden talents of the D SpecNo-length fieldsNo-name fieldsIncorporating external fields into a DSGroup fields

A very usefulcapability

The D Spec - Discoveries

This section outlines some features of the D spec that many experienced RPG IV developers are unfamiliar with.

Hopefully you'll find something here of interest to you.

© Copyright Partner400, 2006 - 2007 D-Spec D-lights - Page: 23-24

Page 13: D-Spec D-Lights - HelpSystems in RPG/400. Notice continuation of values. Character values continued with - continue with first column in keywords on the continuation line

Externally Defined Numeric & Date Fields

By default all numeric field types are converted to packedThe only exception is Floating point fieldsThis is why you may experience mismatches on numeric parameters described with the LIKE keyword

Date and Time fields are also converted to a defaul t formatDefault is *ISO but can be overridden by DATFMT on the H-spec

There is NO system value that impacts the format of "real" dates

For record formats with many dates, performance impact is possible

In both cases conversion can be avoidedBy using an externally described DS to contain these fields

External formats will be retained in RPG in this case

Or by (re)defining external date/time fields on a D specWith desired (external) format specified

When externally defined date or time fields are brought into an RPG program, their formats will normally be translated from the external format (specified in DDS or SQL) to the RPG default format for this program if those formats are different. Especially for record formats with several date or time fields, this format translation on every I/O operation could negatively impact performance. In addition, the programmer may simply prefer to work with the externally defined format in the RPG program.

This format translation by RPG can be avoided, if desired, by using the methods described on this chart. Of course, if several different external formats are used in a given program, the option to match the H spec format is not possible. In that case, the best solution in most cases is likely to be using the externally described Data Structure, since it does not require the programmer hard-code the specific field names and formats. Subsequent changes to the external file description will be more easily incorporated.

Examples illustrating this phenomenon follow.

As indicated on the chart, RPG has always exhibited this behavior for numeric fields. Zoned and Binary numeric fields from a database file are always translated to packed unless you take steps to avoid it.

© Copyright Partner400, 2006 - 2007 D-Spec D-lights - Page: 25-26

Page 14: D-Spec D-Lights - HelpSystems in RPG/400. Notice continuation of values. Character values continued with - continue with first column in keywords on the continuation line

H DatFmt(*Eur) FDateFlds IF E Disk C Read DateFlds C DateMDY Dsply C DateISO Dsply

* DDS for DateFlds A R RECFMT A DATEISO L A DATEMDY L DATFMT(*MDY )

Example: Externally Defined Dates

DDS for file DateFldsContains 2 date fields: *MDY and *ISO formats

RPG IV translates formats for the date fieldsBoth fields will display in *EUR format

It was set by the H-spec as the default for the program

Defined as *ISO by default

This example illustrates the treatment of externally defined date data type fields when used in RPG programs. In this example, there is no D spec definition or externally described data structure to hold the fields, so the format of the 2 date fields in the file DateFlds is changed to *EUR, which is determined in the H spec to be the default date format for this program.

© Copyright Partner400, 2006 - 2007 D-Spec D-lights - Page: 27-28

Page 15: D-Spec D-Lights - HelpSystems in RPG/400. Notice continuation of values. Character values continued with - continue with first column in keywords on the continuation line

H DatFmt(*Eur) FDateFlds IF E Disk

D Dates E DS ExtName(DateF lds)

C Read DateFlds C DateMDY Dsply C DateISO Dsply

Example: Externally Defined Dates

DDS for file DateFldsSame 2 date fields as before

RPG IV brings in external description for DateFldsFields display with externally described formats: *MDY and *ISOExternally described data structure (Dates) makes the difference

* DDS for DateFlds A R RECFMT A DATEISO L A DATEMDY L DATFMT(*MDY )

Defined as *ISO by default

This example illustrates how to ensure the RPG program retains the externally defined formats for date fields. In this example, there is an externally described Data Structure (called Dates) using the file description of DateFlds. In this case, the two date fields retain their externally defined formats from the DDS description.

The same principal can be applied to numeric fields if it is desired to retain their original format. It is not necessary to use an externally described DS, simply naming the fields in a DS (as we will show you later) will achieve the same result. You might want to do this if (for example) you wanted to be able to redefine a zoned field as character within the program. The DS shown below will achieve this assuming that the field ZONED is defined externally as being a zoned field of 7 digits. More later.

D aDS DS D zoned D charOfZoned 7a Overlay(zoned)

© Copyright Partner400, 2006 - 2007 D-Spec D-lights - Page: 29-30

Page 16: D-Spec D-Lights - HelpSystems in RPG/400. Notice continuation of values. Character values continued with - continue with first column in keywords on the continuation line

D Messages DS D 20a Inz('Invalid Ite m Code') D 20a Inz('Too many se lections') D 20a Inz('Item Code r equired') D 20a Inz('Huh?')

D Msg 20a Overlay(Messages ) Dim(4)

Unnamed Fields and Overlaying a DS

DS subfields do not need to be named!But they can still have INZ values!

Originally, the Overlay keyword only applied to sub fieldsNow, you can overlay the DS itself

Makes a great alternative to using compile-time dat aInitialize the data near the array definition itselfNo need to chase to the end of the source memberThe fields can have names if you wish but they do not have to

Our passionate dislike of compile-time data led us to use this technique as an alternative approach. It certainly makes life much simpler when wanting to see what values are used to intialize the array.

© Copyright Partner400, 2006 - 2007 D-Spec D-lights - Page: 31-32

Page 17: D-Spec D-Lights - HelpSystems in RPG/400. Notice continuation of values. Character values continued with - continue with first column in keywords on the continuation line

D SalesData DS D Q1 D Q2 D Q3 D Q4 D SalesForQtr Overlay(Sale sData) D Like(Q1) Dim (4)

No-Length Subfields

R SALESREC1 CUSTOMER 4 STREET 32 CITY 24 STATE 2 DIVISION 2 Q1 7 2 Q2 7 2 Q3 7 2 Q4 7 2 K CUSTNO

DDS

Want to access the fields in a record as an array?The "secret" is to place them in a DSThis technique works even if the fields are not contiguous in the record

No length definition is requiredThe compiler will use the length supplied by the database

Next overlay the array against the DS nameRedefining the fields as an arrayNotice the use of the LIKE keyword

The inspiration for this example comes from one of the most commonly asked questions on RPG programming lists: “How do I directly load fields from a database record into an array?” The question normally arises when each database record contains a series of related values - for example, monthly sales figures.

The DDS for the physical file is shown. One solution is depicted here. We'll look at a different solution on the next chart. Our objective is to access the individual fields Q1-Q4 as an array of four elements after reading a record from the file.

Notice that we’ve incorporated the Quarterly sales fields into the DS by specifying their names. No length or type definition is required. Instead of allocating storage for the file’s fields arbitrarily, the compiler is told to explicitly place the data in the DS. Because the DS no longer contains the Customer and Division data, we can use the simple form of the Overlay keyword. Otherwise, if we had used an externally described DS, we would have needed to place a starting position o the Overlay keyword. The code for that alternative solution is shown below. Unlike the externally described DS, The example on this chart allows you to see exactly which fields form the DS. In addition, the fields in the DS can come from multiple files.

D SalesData E DS ExtName(TestFile) // Define array over Quarterly Sales figures D SalesForQtr Overlay(SalesData: 7) D Like(Q1) Dim(4)

© Copyright Partner400, 2006 - 2007 D-Spec D-lights - Page: 33-34

Page 18: D-Spec D-Lights - HelpSystems in RPG/400. Notice continuation of values. Character values continued with - continue with first column in keywords on the continuation line

D SalesData DS D Customer D Address D Street Overlay(Addres s) D City Overlay(Addres s: *Next) D State Overlay(Addres s: *Next) D Division D QuarterData D Q1 Overlay(Quarte rData) D Q2 Overlay(Quarte rData: *Next) D Q3 Overlay(Quarte rData: *Next) D Q4 Overlay(Quarte rData: *Next)

D SalesForQtr Overlay(Quarte rData) Like(Q1) Dim(4)

Group Fields

Sometimes it is convenient to reference a group of fieldsYou might wish to group Street, City and State under the name Address. That way they can be manipulated as a single entity

This version of the previous example uses this appr oachThe compiler derives the length of the group field from the combined lengths of the subfields that OVERLAY it

Note that neither Address or QuarterData have a length, type definition or LIKE keyword. Nor do they exist in any of the program’s files. Normally you’d expect such definitions to result in Field Not Defined errors, but it doesn’t because the subsequent OVERLAY references inform the compiler that these fields represent a group field.

If you look in detail at QuaterData, you will see that it comprises the fields Q1 though Q4. If you examine the extract from the compiler cross-reference listing below, you’ll see that QuarterData is defined as 28 characters long (i.e., the combined lengths of Q1, Q2, Q3 and Q4):

Q1 S(7,2) 14D . . . . Q2 S(7,2) 15D . . . . Q3 S(7,2) 16D . . . . Q4 S(7,2) 17D . . . . QUARTERDATA A(28) 13D . . . . SALESDATA DS(34) 10D . . . .

SALESFORQTR(4) S(7,2) 19D . . . .

© Copyright Partner400, 2006 - 2007 D-Spec D-lights - Page: 35-36

Page 19: D-Spec D-Lights - HelpSystems in RPG/400. Notice continuation of values. Character values continued with - continue with first column in keywords on the continuation line

Using SORTA with Group Fields

D ProductInfo DS // Note that Dim is specified at the group field levelD ProductData Dim(1000) D Name 8 Overlay(Produ ctData)D UnitPrice 8 Overlay(Produ ctData: *Next)D QtyInStock 9p 0 Overlay(Produ ctData: *Next)

/Free SortA Name; // Sort into Name sequence

SortA UnitPrice; // Sort in Unit Price sequence

Want to sort an array on different keys?Group fields can provide an answer

ProductData is a group fieldIt comprises the fields Name, UnitPrice and QtyInStock

Notice that the DIM is specified at the group levelThis allows the array to be sorted on any of the subfieldsThe associated data will "follow along" and stay in sync

Note that when using this technique all of the other fields in the array (i.e. those that are part of the group) will be "pulled along" with their associated values.

ASCEND or DESCEND can be specified as normal along with the DIM keyword. So, while you can sort on any of the fields in the group, you can only sort ascending OR descending sequence on any given array.

In order to allow alternate sequencing you could use a pointer to base a second version of the array as shown in the example below:

D ProductInfo DS D ProductData Dim(1000) Acsend D Name 8 Overlay(ProductData)D UnitPrice 8 Overlay(ProductData: *Next)D QtyInStock 9p 0 Overlay(ProductData: *Next)

// Use a Based version of the DS to allow the alternate sorting seq.

D AlternateView DS Based(pProductInfo) D ProductDataD Dim(1000) DescendD NameD 8 Overlay(ProductDataD)D UnitPriceD 8 Overlay(ProductDataD: *Next)D QtyInStock 9p 0 Overlay(ProductDataD: *Next)

D pProductInfo S * Inz(%Addr(ProductInfo))

© Copyright Partner400, 2006 - 2007 D-Spec D-lights - Page: 37-38

Page 20: D-Spec D-Lights - HelpSystems in RPG/400. Notice continuation of values. Character values continued with - continue with first column in keywords on the continuation line

Sorting Subfile Data

How to sort subfile data easily?Load the data destined for the subfile into an array defined using the subfile record formatLoad the subfile from the arrayWhen user requests a different sequence, sort the data on that key and then re-load the subfile from the array

D SubRecData E Ds ExtName(ProdS flDsp:SflRec)

D SflDS DsD SflRecs Like(SubRecDa ta) Dim(999) D Sort_Name Like(Name) Ov erlay(SflRecs)D Sort_Price Like(Price) O verlay(SflRecs:*Next)D Sort_Qty Like(Qty) Ove rLay(SflRecs:*Next)

If SortByName; SortA Sort_Name; ElseIf SortByQty; SortA Sort_Qty; ElseIf SortByPrice; SortA Sort_Price; EndIf;

A common request is to easily sort subfile data on the screen. Using this sorting technique, this can be fairly simply accomplished. The data is first loaded into the array, then the subfile is loaded from the array. If/when the user requests a different sequence to the data in the subfile, don't retrieve it again from the file. Instead simply re-sequence the array data using the simple SORTA technique and reload the subfile from the array.

This is of course only good for data that does not need to be up to the minute. The time the data is in the array any changes being made to the data in the database files is not reflected.

© Copyright Partner400, 2006 - 2007 D-Spec D-lights - Page: 39-40

Page 21: D-Spec D-Lights - HelpSystems in RPG/400. Notice continuation of values. Character values continued with - continue with first column in keywords on the continuation line

What if ...What if the array isn't full?

Use the V5R3 BIF %SubArr to sort only the filled portionPrior to V5R3, initialize all elements to Hival or use the qsort C function

What if the array sometimes gets very large?Base it on a pointer Then use either dynamic memory allocation or put it in a user space

D SubRecData E Ds ExtName(ProdS flDsp:SflRec)

D SflDS Ds Based(pSflDS)D SflRecs Like(SubRecDa ta) Dim(999) D Sort_Name Like(Name) Ov erlay(SflRecs)D Sort_Price Like(Price) O verlay(SflRecs:*Next)D Sort_Qty Like(Qty) Ove rLay(SflRecs:*Next)

If SortByName; SortA %SubArr(Sort_Name:1:SflNoRecords); ElseIf SortByQty; SortA %SubArr(Sort_Qty:1:SflNoRecords); ElseIf SortByPrice; SortA %SubArr(Sort_Price:1:SflNoRecords); EndIf;

Of course, most of the time, the entire subfile will not be full, so the SORTA operation will have trouble with the "empty" array elements. In V5R3, the new %SubArr built-in is a big help here. Prior to that, you would need to initialize the array to high values before loading it to ensure the sorting works properly.

We don't have the time here to show the details of putting the array data into a User Space or to use dynamic memory allocation on it, but either of those techniques would work well if you are concerned that the data destined for the subfile is too large to allow for in each user's job.

© Copyright Partner400, 2006 - 2007 D-Spec D-lights - Page: 41-42