Guru: 7.4 Brings New RPG Goodies
June 3, 2019 Jon Paris
As I’m sure you know by now, IBM recently announced version 7.4 of IBM i. Along with major enhancements such as Db2 Mirror, we also got a number of new RPG features. In this tip I’ll cover those that are already available in 7.3 via PTF. The 7.4-only enhancements will be covered in a subsequent tip.
Before we get into the details of the 7.3 features, just a hint of what is to come . . . 7.4 brings the long-awaited arrival of dynamic arrays known to IBM as varying dimension arrays. No more do you have to compromise between memory usage and safety! And it makes so many other things easier, too. But while this is a terrific feature, due to the complexity of the changes required to support it, it will not be PTF’d back into 7.3. So the majority of us will not be able to get our hands on it for a month or three. That is why I decided to focus this first tip on the RPG enhancements that are available now in 7.3 and I will review the array enhancements in a later tip.
RPG has added two additional fields to the PSDS. This feature has also been made available for the 7.2 release. The one that most people will find a use for is the 8-character system name that appears in positions 396 to 403. The second is the 16 byte Internal Job ID, which can be found in positions 380 to 395. This ID is used for, among other things, socket communications or retrieving spool file information for the job. Previously the simplest way to obtain it was to call the QUSRJOBI API. Having it readily accessible in the PSDS is clearly a lot easier. Here’s how it looks:
// Internal job ID, in positions 380 to 395 // System name, in positions 396 - 403 Dcl-Ds PSDS; jobId Char(16) Pos(380); systemName Char(8) Pos(396); End-Ds;
New Keyword SAMEPOS
This one is deceptively simple but has so many potential uses. In most cases it doesn’t do anything we couldn’t do before, but it makes it simpler and more obvious. Let’s start by making a simple comparison with the OVERLAY keyword.
Take a look at these two structures. In both cases the separate day, month, and year fields are being grouped together in a single date field. In the first case the date field is defined first and the component fields are specified as overlaying it. It works, but it looks clumsy.
Dcl-DS overlayDS; orderDate char(8); orderDay zoned(2) Overlay( orderDate ); orderMonth zoned(2) Overlay( orderDate: *Next ); orderYear zoned(4) Overlay( orderDate: *Next ); End-Ds; Dcl-DS samePosDS; orderDay zoned(2); orderMonth zoned(2); orderYear zoned(4); // Overlay day, month and year as single field orderDate char(8) SamePos(orderDay); End-Ds;
In the second case the component fields are specified first, and the combined date field uses SAMEPOS to specify that it starts in the same position as the orderDay field. I think that you will agree that the second version is a lot cleaner.
As these samples demonstrate, the primary difference between OVERLAY and SAMEPOS is that with OVERLAY the field being defined must be totally contained within the referenced parent field. With SAMEPOS we are simply saying that the field “starts in the same place as” the referenced field. Basically it is a “soft” version of the POS keyword which accepts a field name rather than an absolute position — and anything that helps avoid hard-coding is a good thing.
SAMEPOS really comes into its own when used with an externally described data structure. For example, suppose in the example above the separate day, month, and year fields were in the database. We could still use SAMEPOS to create the orderDate field like this:
Dcl-Ds orderData Ext; orderDate Char(8) SamePos(orderDay); End-Ds;
In a similar manner you can also use it to create an array over a series of fields. Not that any of our readers have databases that are not fully normalized, but just in case . . .
Suppose that the table contains quantity and value fields for sales for each day of the week, i.e., MONQUANTITY, MONVALUE, TUEQUANTITY, TUEVALUE, etc., all the way to SUNVALUE. We can use SAMEPOS to create a DS array within the main DS like this:
Dcl-Ds dailySales Ext Qualified; Dcl-Ds daySales Dim(7) SamePos(MONQUANTITY); quantity Like(MONQUANTITY); value Like(MONVALUE); End-Ds; End-Ds;
The daily quantity and value fields for each day can now be accessed as array elements.
One other use that immediately came to my mind concerned its applicability to dealing with multi-format data, i.e. where you have a fixed portion of the record (perhaps a Customer number and Order number, together with a record identifier. Header, detail, total, etc.) You’d think that this was a style of data definition that we had left behind with punch cards and mag tapes but it continues to be used. In particular I’ve encountered it recently with EDI data.
SAMEPOS makes this kind of definition far easier than the alternatives of copying data to the appropriately defined layout, or using pointers to map different layouts to the same data. Here’s basically how it would work.
Dcl-Ds Record Qualified; RecordType Char(1); // Additional common data such as customer Id Dcl-Ds HeaderInfo; // Definitions for header layout End-Ds; Dcl-Ds DetailInfo SamePos(HeaderInfo); // Definitions for detail layout End-Ds; Dcl-Ds TotalInfo SamePos(HeaderInfo); // Definitions for total layout End-Ds; End-Ds;
As you’ve seen, there is a lot you can do with this new support. You can find details of the required PTF numbers in the RPG Cafe at these links — ibm.biz/rpg_samepos_keyword and ibm.biz/rpg_psds_int_job_sys_name.
In my next tip I’ll take a look at the new array support. In the meantime, if you have any questions or comments about these features please let me know via the comments section.
Jon Paris is one of the world’s foremost experts on programming on the IBM i platform. A frequent author, forum contributor, and speaker at User Groups and technical conferences around the world, he is also an IBM Champion and a partner at Partner400 and System i Developer. He hosts the RPG & DB2 Summit twice per year with partners Susan Gantner and Paul Tuohy.