An Introduction to ILE RPG

March 27, 2017 | Author: c1456634 | Category: N/A
Share Embed Donate


Short Description

An Introduction to ILE RPG...

Description

An Introduction to ILE RPG: Part 1 Written by Charlie Massoglia

Monday, 28 February 1994

Brief: Early last year, IBM officially announced the Integrated Language Environment (ILE) and plans for a new generation of AS/400 languages. Even before the ILE announcement, the RPG programming community was aware of major changes being considered by IBM's language developers. Now, a new RPG language is close to completion in IBM's Toronto laboratory with a projected delivery date during the third quarter of 1994. Starting with this article, Midrange Computing will present a comprehensive tutorial on the new features and functions that define ILE RPG. This month's article provides an overview of the changes that pervade the new language and an in-depth look at changes to Control and File description specifications. Since the announcement of the AS/400, we have seen many significant enhancements made to RPG/400, including the addition of string-handling capabilities, a number of new structured operation codes, named and hexadecimal constants, read with no update, and more. Despite these enhancements, RPG/400 still has its critics. Six-character field names can result in cryptic, difficult-to-understand abbreviations. Complex formulas are difficult at best to code with a single operation per Calculation specification. Other criticisms abound. We are about to see enhancements which will make RPG/400 seem as archaic and difficult to use as RPG II may now seem to experienced RPG/400 programmers. The programming language that will deliver these enhancements is Integrated Language Environment RPG (ILE RPG). ILE RPG should be announced as part of V3R1M0 of OS/400. You may also hear ILE RPG referred to as RPG IV or NPM (New Program Model) RPG. An important benefit of the new ILE program model is the ability to bind programs. Binding programs means compiling programs separately as nonexecutable modules which can be combined (bound together) to form a single, executable program object. This facilitates modularity and makes it possible to create reusable components without the performance penalty of external program calls. Calls to a program which is bound to the calling program can execute with the speed of a subroutine. You no longer have to code the same subroutine in multiple programs because you are afraid of the performance hit associated with calling an external program. Programs written in one language can call programs written in a different language with consistent operation and error handling. A common source-level debugger will service all ILE languages. Resources can be better controlled by partitioning a job into activation groups and controlling file opens, file sharing and program loads within an activation group. All of these benefits are part of the underlying ILE enhancements included in V2R3M0. They will be available for each new ILE language as it is released. ILE C/400 is the first ILE language and was introduced in V2R3M0. In addition to all of the ILE benefits, the RPG language itself has been substantially enhanced. It will take some time and perhaps some education to become as comfortable with the new ILE RPG as you now are with RPG II, RPG III or RPG/400. "Why?" you ask. Do you use arrays? Guess what? Arrays and tables still exist, but there are no Extension specifications (E-specs) in ILE RPG! For that matter, there are no longer any Line Counter

specifications (L-specs) either. Do you think you know the external file input/output operation codes? The DELET, UPDAT, UNLCK and REDPE operation codes no longer work. They've been changed to DELETE, UPDATE, UNLOCK and READPE. And if you're a real long-time expert, remember the D specification from System/3 RPG? Well, as we'll see, it doesn't mean dump in ILE RPG! Even with these changes, there's no need to worry. An RPG/400-to-ILE RPG source conversion utility will be provided. This utility should completely automate conversion unless you use /COPY in RPG/400 or Auto Report. (More about this in a later article.) All you really need is a little education. This series of articles provides some concentrated education about ILE RPG to make you comfortable with the new language. While the ILE RPG language definition is still subject to change, any changes made subsequent to the writing of this article will probably be minor. At first glance, ILE RPG might seem very different from the current version of RPG/400. However, very shortly you'll understand why the changes were made and learn how the new ILE RPG will make programming easier and more efficient. General Changes o One of the most frequent complaints about RPG is its six-character limit for field names. ILE RPG now supports 10-character file, format, field, constant, data structure, key list, subroutine, label and other symbolic names. ILE RPG has generated some criticism because it only supports 10-character field names, while OS/400 supports longer field names. In fact, DDS directly supports only 10-character field names. Longer field names are supported only through the ALIAS keyword. For example, when defining DDS for a file, the field name EMP_NUM might have an ALIAS of EMPLOYEE_NUMBER. While ILE RPG will not support alias field names, it will support native field names for any file on the AS/400. o The underscore (_) is now valid in a symbolic name but cannot be the first character. EMP_NAME is a valid field name, but _NAME is not. o Array subscripts are specified using parentheses instead of a comma. ARR,X in RPG/400 becomes ARR(X) in ILE RPG. o Upper- and lowercase characters can be used anywhere in an ILE RPG program. The field names EmpName and location are now valid. The operation codes CHAIN, Chain, and chain all perform the same function. The use of lowercase is optional. The compiler will translate all source-with a few exceptions-from lowercase characters ("a" to "z") to uppercase characters. Comments, literals (with the exception of hexadecimal literals) and compile-time array and table data will not be translated. Also not translated are: the currency symbol, date and time edit values on the Control specification (H-spec), date and time separator characters on Input specifications (I-specs) (we'll address separator characters in a later article), and comparison characters on Record Identification entries on I-specs. Hexadecimal literals will be translated, so coding x'f0' is the same as coding X'F0'. Compile listings will show upper- and lowercase as entered by the user. The cross-reference listing will appear in uppercase only.

o The maximum length of named constants has increased from 256 to 1,024 characters. Numeric variables will now support up to 30 decimal positions, up from 9. The field length of character variables has also increased, in answer to criticism of RPG/400's 256-character limitation. Character variables and array elements can now be up to 32,767 characters in length. o Other limits have also been in-creased. The maximum record length of a program-described file has been increased from 9,999 bytes to 99,999 bytes. Externally described files can have even larger record lengths. The number of elements in a table or array has been increased from 9,999 to 32,767. The maximum length of a single-occurrence data structure has changed from 9,999 to 9,999,999 while the maximum number of occurrences in a multiple-occurrence data structure has changed from 9,999 to 32,767. Finally, the length of compile-time table and array data has increased from 80 to 100 characters. o Some limits have been virtually eliminated. In RPG/400, the number of files is limited to 50. The maximum number of arrays is 200. And, believe it or not, there is a maximum program size. In ILE RPG, there are no practical limits for these values. 1 summarizes changes to limits. Figure 1 summarizes changes to limits. o Source statements which are blankin positions 6 to 80 will be treated as comments. An asterisk (*) in position 7 will also force a statement to be a comment just as it does in RPG/400. In general, positions 81 to 100 are treated as comments in source statements except for compile-time table and array data defined as longer than 80 characters. o The default source file name has changed from QRPGSRC to QRPGLESRC and the record length has expanded from 92 to 112 bytes. The existing six-character date and SEU sequence-number fields remain unchanged. The increase of the source statement length from 80 to 100 characters will accommodate the longer file and field names as well as the comments in positions 81 to 100. Having reviewed general changes which affect all specifications in ILE RPG, we now can take a look at the details. In the balance of this article, we will address the H-specs and File description specifications (F-specs). The next article will address the new Data specification (D-spec) and builtin functions. Future articles will round up our review with Input, Calculation, and Output specifications (I-specs, C-specs and O-specs) together with expressions, new operation codes and date manipulation. Control Specifications (H-specs) A quick look at an H-spec (2) introduces ILE RPG keyword notation which you'll see repeatedly as we cover each specification type. The keyword notation used in ILE RPG is very similar to the keyword notation found in CL. A quick look at an H-spec (Figure 2) introduces ILE RPG keyword notation which you'll see repeatedly as we cover each specification type. The keyword notation used in ILE RPG is very similar to the keyword notation found in CL. For example, instead of specifying a D in position 15 of the H-spec, the keyword DEBUG is now used to enable DEBUG and DUMP operations. The use of DEBUG or DEBUG(*YES) enables

DEBUG and DUMP operations. Not specifying the DEBUG keyword at all or specifying DEBUG(*NO) disables DEBUG and DUMP operations. The currency symbol in position 18 is now specified using the CURSYM keyword with a single character enclosed in quotes. If CURSYM is not specified, the currency symbol defaults to '$'. The date format and date edit in positions 19 and 20 are replaced with the DATEDIT keyword to specify the order of month, day and year of UDATE and *DATE as well as the separator character for the Y edit-code. *MDY, *DMY and *YMD formats can be specified. An optional separator character may be specified for *DMY, *YMD and *MDY format dates. The separator character is added to the date format. For example, specifying DATEDIT(*MDY.) causes dates to appear as MM.DD.YY when the Y edit- code is used. The DECEDIT keyword replaces the decimal notation in position 21. Alternate collating sequence is now specified with the ALTSEQ keyword instead of an A in position 26. The FORMSALIGN parameter replaces the 1 in position 41 to request first-page forms alignment. FORMSALIGN and FORMSALIGN(*YES) enable first-page forms alignment. Not specifying the FORMSALIGN keyword, or specifying FORMSALIGN(*NO), disables first-page forms alignment. A file translation table is indicated using the FTRANS keyword instead of the 'F' in position 43. The transparency (graphic) check in position 57 is no longer required. The default program name is now specified using the DFTNAME keyword instead of using positions 75 to 80. If DFTNAME is not specified or if the specified name is invalid, RPGOBJ will be used as the default program name. At compile time, a program name is normally specified as the same name as the source member, so DFTNAME does not need to be specified in most cases. The DATFMT keyword is used to indicate the format and separator for date literals which are required to support the new date and timestamp data types. (Date, time and timestamp data types and operations will be described in a later article.) *MDY, *DMY and *YMD support the traditional, eight-character MM/DD/YY, DD/MM/YY and YY/MM/DD date formats. A number of other formats are also supported. The TIMFMT keyword is used to indicate the format and separator for time literals which are used to support the new time and timestamp data types. 3 summarizes the changes in the H-spec. The TIMFMT keyword is used to indicate the format and separator for time literals which are used to support the new time and timestamp data types. Figure 3 summarizes the changes in the H-spec. What's in the future for H-specs? It is easy to see that the new keyword notation has eliminated any format or length restrictions since multiple lines of specifications can be used. What about compile options? Aren't they specified in keyword notation on the compile commands? Wouldn't it be nice to include compile options in the source and never again have to prompt and

change parameters on a compile command? Perhaps we'll see this capability in a later release of ILE RPG. File Description Specifications (F-specs) A simple F-spec sample in 4 shows further use of keyword notation in ILE RPG. The file information data structure DSMBID is now defined as a parameter of the INFDS keyword: INFDS(DSMBID) A simple F-spec sample in Figure 4 shows further use of keyword notation in ILE RPG. The file information data structure DSMBID is now defined as a parameter of the INFDS keyword: INFDS(DSMBID) In a similar manner, the information subroutine SUBRER is now specified as a parameter on the INFSR keyword: INFSR(SUBRER) The rename of a record format is a two-part parameter of the RENAME keyword: RENAME(COPMB1:COLMBID1) The F-spec in ILE RPG has been modified to accommodate expanded lengths. For example, the eight-character file name in positions 7 to 14 has been expanded to 10 characters in positions 7 to 16. The four-character record length in positions 24 to 27 has been expanded to five characters in positions 23 to 27. And the two-character key length in positions 29 to 30 has been expanded to five characters in positions 29 to 33. There are many other changes of this type. 5 summarizes all the Fspec changes. The F-spec in ILE RPG has been modified to accommodate expanded lengths. For example, the eight-character file name in positions 7 to 14 has been expanded to 10 characters in positions 7 to 16. The four-character record length in positions 24 to 27 has been expanded to five characters in positions 23 to 27. And the two-character key length in positions 29 to 30 has been expanded to five characters in positions 29 to 33. There are many other changes of this type. Figure 5 summarizes all the F-spec changes. Date, time and timestamp keys are now supported by specifying a D, T or Z. These key formats are indicated using the DATFMT and TIMFMT keywords in F-specs with values similar to those that can be specified in the DATFMT and TIMFMT keywords in the H-specs. The USROPN and EXTIND keywords shown in 6 are now used to condition the opening of files. The UC in positions 71 to 72 has been changed to the USROPN keyword for the file COLMBDS. The U8 external indicator for COLMBID has been changed to EXTIND(U8). You specify that a file allows additions with an A in position 20 rather than position 66. This will probably take a while to get used to! The USROPN and EXTIND keywords shown in Figure 6 are now used to condition the opening of files. The UC in positions 71 to 72 has been changed to the USROPN keyword for the file COLMBDS. The U8 external indicator for COLMBID has been changed to EXTIND(U8). You specify that a file allows additions with an A in position 20 rather than position 66. This will probably take a while to get used to! Prefix Keyword

One of the most significant F-spec enhancements involves the use of the same record format multiple times in a program. In ILE RPG, as in RPG/400, if you want to use a physical file and a logical file based on the physical file in the same program, you have to rename the record format of one of the files. However, in RPG/400, if you want to read a record from the physical file and then read a record from the logical file without altering the values of the fields from the physical file, you have to rename the fields in the I-specs. This is no longer true in ILE RPG. In our sample in 7, we have renamed the record format COPMB1 to COLMBID1 for the file COLMBID in both RPG/400 and ILE RPG. But we only changed the fields MBDELT to M2DELT, MBID to M2ID, and MBNAME to M2NAME in the RPG/400 sample. Instead of having to individually list each field in the file, ILE RPG now supports the PREFIX keyword to perform a global field rename function. By specifying PREFIX(M2_), we have implicitly renamed MBDELT to M2_MBDELT, MBID to M2_MBID and MBNAME to M2_MBNAME. In our sample in Figure 7, we have renamed the record format COPMB1 to COLMBID1 for the file COLMBID in both RPG/400 and ILE RPG. But we only changed the fields MBDELT to M2DELT, MBID to M2ID, and MBNAME to M2NAME in the RPG/400 sample. Instead of having to individually list each field in the file, ILE RPG now supports the PREFIX keyword to perform a global field rename function. By specifying PREFIX(M2_), we have implicitly renamed MBDELT to M2_MBDELT, MBID to M2_MBID and MBNAME to M2_MBNAME. Fields that are explicitly re-named on I-specs are not affected by the PREFIX keyword. Also, if the addition of the prefix to the field name results in a field name which exceeds 10 characters, a compile error will occur. Not only will the PREFIX global rename capability save a tremendous amount of coding time, it will also eliminate the need to check your programs when you add a field to a file. The added field will automatically be prefixed (e.g., M2_NEWFLD) when the program is recompiled. Nice job, IBM! Selecting Record Formats The IGNORE keyword can be used to ignore a record format from an externally defined file in both RPG/400 and ILE RPG. Each format to be ignored must be specified in RPG/400. Our sample in 8 shows formats FORMAT2, FORMAT3 and FORMAT4 being ignored. In addition to the IGNORE keyword in ILE RPG, an INCLUDE keyword is also provided. Any record format not specified using the INCLUDE keyword is ignored. If you do not specify INCLUDE or IGNORE, all records formats will be included. In our ILE RPG sample, we included FORMAT1 instead of explicitly ignoring FORMAT2, FORMAT3 and FORMAT4. The IGNORE keyword can be used to ignore a record format from an externally defined file in both RPG/400 and ILE RPG. Each format to be ignored must be specified in RPG/400. Our sample in Figure 8 shows formats FORMAT2, FORMAT3 and FORMAT4 being ignored. In addition to the IGNORE keyword in ILE RPG, an INCLUDE keyword is also provided. Any record format not specified using the INCLUDE keyword is ignored. If you do not specify INCLUDE or IGNORE, all records formats will be included. In our ILE RPG sample, we included FORMAT1 instead of explicitly ignoring FORMAT2, FORMAT3 and FORMAT4. Commitment Control

The COMIT keyword in RPG/400 has been changed to COMMIT in ILE RPG. Commitmentcontrol processing has been substantially enhanced through the ability to specify a single-character field as a parameter on the COMMIT keyword to condition the use of commitment control. If the field contains a 1, the file will be opened with commitment control. Otherwise, the file will be opened without commitment control. The field value must be set prior to opening the file and can be passed as an *ENTRY parameter. If the file is shared and is already open, this keyword has no effect. In the commitment-control sample in 9, the file COLMBID is always opened under commitment control in RPG/400. The field C_COLMBID is implicitly defined as a one-byte character field in the ILE RPG sample. If passed as an *ENTRY parameter with a value of '1', the file COLMBID is opened under commitment control. Otherwise, the file COLMBID will be opened but commitment control will not be used. For files opened under user control, the value of C_COLMBID could be set in the RPG program prior to opening the file. In the commitment-control sample in Figure 9, the file COLMBID is always opened under commitment control in RPG/400. The field C_COLMBID is implicitly defined as a one-byte character field in the ILE RPG sample. If passed as an *ENTRY parameter with a value of '1', the file COLMBID is opened under commitment control. Otherwise, the file COLMBID will be opened but commitment control will not be used. For files opened under user control, the value of C_COLMBID could be set in the RPG program prior to opening the file. ADDROUT Files Since E-specs have been eliminated, coding ADDROUT files in ILE RPG has changed. The ADDROUT file record length which was coded in positions 24 to 27 is now coded in positions 23 to 27. The key length has been moved from positions 29 to 30 and expanded to five characters in positions 29 to 33. The T representing file organization in position 32 has been moved to position 35. The TOFILE keyword replaces the E-spec. In our sample in 10, TOFILE(OS6MASTR) relates the file ADDROUT to the file OS6MASTR. Since E-specs have been eliminated, coding ADDROUT files in ILE RPG has changed. The ADDROUT file record length which was coded in positions 24 to 27 is now coded in positions 23 to 27. The key length has been moved from positions 29 to 30 and expanded to five characters in positions 29 to 33. The T representing file organization in position 32 has been moved to position 35. The TOFILE keyword replaces the E-spec. In our sample in Figure 10, TOFILE(OS6MASTR) relates the file ADDROUT to the file OS6MASTR. Line Counter Functions The L-spec has also been eliminated from ILE RPG and its function has been moved to F-specs using the FORMLEN and FORMOFL keywords. In the sample in 11, the overflow indicator is now coded using OFLIND(OF). The forms length of 51 lines and overflow line number of 44, both of which used to be coded in the L-spec, are coded in the F-spec using FORMLEN(51) and FORMOFL(44). The L-spec has also been eliminated from ILE RPG and its function has been moved to F-specs using the FORMLEN and FORMOFL keywords. In the sample in Figure 11, the overflow indicator is now coded using OFLIND(OF). The forms length of 51 lines and overflow line number of 44, both of which used to be coded in the L-spec, are coded in the F-spec using FORMLEN(51) and FORMOFL(44).

The PRTCTL keyword is still used to define a data structure to access the current line value and dynamically control a program-described printer file, but it has been expanded to accommodate longer fields. Instead of coding skip and space before and after in Output specifications (O-specs), these values can be set in a PRTCTL data structure. Specifying PRTCTL(DSname:*COMPAT) will retain the RPG/400 definitions. Not specifying *COMPAT will change the format of PRTCTL as summarized in 12. The PRTCTL keyword is still used to define a data structure to access the current line value and dynamically control a program-described printer file, but it has been expanded to accommodate longer fields. Instead of coding skip and space before and after in Output specifications (O-specs), these values can be set in a PRTCTL data structure. Specifying PRTCTL(DSname:*COMPAT) will retain the RPG/400 definitions. Not specifying *COMPAT will change the format of PRTCTL as summarized in Figure 12. Other File Continuation Keywords The PGMNAME keyword specifies the name of the program which gets control for a SPECIAL file. The PLIST keyword is still used to specify a parameter list for the program to handle a SPECIAL file. Changes have also been made to other file continuation keywords. The ID keyword that defines a field to contain the name of the program device has been changed to DEVID. Saved indicators are now specified using the new SAVEIND keyword instead of the old IND keyword. The SAVDS (save data structure) keyword has been changed to SAVEDS. The NUM parameter used to specify the maximum number of acquired devices for a WORKSTN file has been changed to MAXDEV and has been substantially enhanced. Instead of having to recompile the program to increase the maximum number of acquired devices, MAXDEV(*FILE) can be specified to cause this value to be taken from the display file at run time. In this case, SAVEDS and SAVEIND space allocation take place at run time. MAXDEV(*ONLY) is the default which indicates a single device file. The actual number of devices can no longer be specified- only *FILE and *ONLY are valid. Some keywords remain the same. The PASS keyword used to control passing of indicators to data management, the RECNO keyword used to specify a relative record number for files processed by relative record number and the SLN keyword used to specify a starting line number for a WORKSTN file are all unchanged. What's Next? As you can see, numerous modifications were required just to handle the change from six-character to 10-character symbolic names. Introducing keyword notation has not only freed up space to accommodate longer fields in F-specs, it has also made the coding of H- and F-specs much easier for us and much easier for IBM to enhance in the future. As you'll see in the remaining articles in this series, the changes to accommodate longer names are minor compared to other changes in ILE RPG. In our next article, we will tackle I-specs and the newly reincarnated D-specs.

Charlie Massoglia is president of Massoglia Technical Consulting, Inc. in Okemos, Michigan. Author of a number of midrange books, Charlie is a frequent speaker throughout the United States, Canada, Europe and Australia. An Introduction to ILE RPG: Part 1

Figure 1 Changes to Limits Description of Changed Limit

RPG/400 Limit

ILE RPG Limit

Field name

6

10

Table and array name

6

10

File name

8

10

File record format name

8

10

Valid characters in A-Z, 0-9, $, # and @ symbolic name (First character may not be 0-9 or _)

A-Z, 0-9, $, #, @ and _

Use of upper- and lowercase

Upper- and lowercase

Uppercase

Length of character field and array element

256

32,767

Length of named constants

256

1,024

9

30

Number of decimal positions Number of files

50

No practical limit

Number of arrays

200

No practical limit

Varies

No practical limit

Program size Program-described file record length

9,999

99,999

Number of elements in table or array

9,999

32,767

Length of single-occurrence data structure

9,999

9,999,999

Number of occurrences in a multiple-occurrence data structure

9,999

32,767

80

100

Length of compile-time table and array data

An Introduction to ILE RPG: Part 1

Figure

2 H-spec Sample Code

RPG/400 *.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 10 H........1..CDYI....S..............1.F...............................Pgm-id H D $M D A 1 F ILE RPG *.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 10 HFunctions++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Comm ents++++++++++++ H DEBUG(*YES) CURSYM('$') DATEDIT(*MDY) DECEDIT('.') H ALTSEQ(*SRC) FORMSALIGN(*YES) FTRANS(*SRC) DFTNAME(name) H DATFMT(*MDY/) TIMFMT(*ISO)

An Introduction to ILE RPG: Part 1

Figure

RPG/400 Position 15 18 19 20 21 New New 26 41 43 57 75-80

3 Changes to H-specs

SEU Format Abbreviation 1 C D Y I S 1 F Pgm-id

Explanation Debug and Dump Currency Symbol Date Format UDATE Edit Decimal Notation Date Literals Format Time Literals Format Alternate Collating Sequence First-page Forms Alignment File Translation Transparency Check Default Program Name

ILE RPG Keyword DEBUG CURSYM DATEDIT DATEDIT DECEDIT DATFMT TIMFMT ALTSEQ FORMSALIGN FTRANS No longer needed DFTNAME

An Introduction to ILE RPG: Part 1

Figure

4 INFDS, INFSR and RENAME

RPG/400 *.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 10 FFilenameIPEAF....RlenLK1AIOvKlocEDevice+......KExit++Entry+A....U1....... FCOLMBID UF E K DISK KINFDS DSMBID

F............Ext-recfmt..................Recno+KOptionEntry+............... F KINFSR SUBRER F COPMB1 KRENAMECOLMBID1 ILE RPG *.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 10 FFilename++IPEASFRlen+LKlen+AIDevice+.File continuation++++++++++++++++++++Comments++++++++++++ FCOLMBID UF E K DISK INFDS(DSMBID) INFSR(SUBRER) F RENAME(COPMB1:COLMBID1)

An Introduction to ILE RPG: Part 1

Figure

RPG/400 Position

5 Changes to F-specs

ILE RPG Position

SEU Format Abbreviation

7-14 15 16 17 18 19 24-27 28 29-30 31 32 33-34 35-38

7-16 17 18 19 21 22 23-27 28 29-33 34 35 Keyword Keyword

Filename I P E A F Rlen L K1 A I Ov Kloc

39

Keyword

E

40-46 53-65 66 71-72

36-42 44-80 20 Keyword

Device KExit++Entry+ A U1

75-80

81-100

Comments

Explanation

New Keyword

File name File type File designation End of file control Match field sequence File format Record length Limits processing Key field length Record address type File organization Overflow indicator Key field starting location Extension code

OFLIND KEYLOC TOFILE FORMLEN FORMOFL

Device type File continuation keywords File addition File condition EXTIND USROPN Comments

An Introduction to ILE RPG: Part 1

Figure

6 USROPN and EXTIND

RPG/400 *.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8

...+... 9 ...+... 10 FFilenameIPEAF....RlenLK1AIOvKlocEDevice+......KExit++Entry+A....U1....... FCOLMBDS IF E K DISK UC FCOLMBID UF E K DISK A U8 ILE RPG *.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 10 FFilename++IPEASFRlen+LKlen+AIDevice+.File continuation++++++++++++++++++++Comments++++++++++++ FCOLMBDS IF E K DISK USROPN FCOLMBID UF A E K DISK EXTIND(U8)

An Introduction to ILE RPG: Part 1

Figure

7 RENAME and PREFIX

RPG/400 *.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 10 FFilenameIPEAF....RlenLK1AIOvKlocEDevice+......KExit++Entry+A....U1....... FCOPMB UF E K DISK FCOLMBID IF E K DISK F............Ext-recfmt..................Recno+KOptionEntry+............... F COPMB1 KRENAMECOLMBID1 IFilenameSqNORiPos1NCCPos2NCCPos3NCC....................................... ICOLMBID I..............Ext-field+......................Field+L1M1..PlMnZr.......... I MBDELT M2DELT I MBID M2ID I MBNAME M2NAME ILE RPG *.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 10 FFilename++IPEASFRlen+LKlen+AIDevice+.File continuation++++++++++++++++++++Comments++++++++++++ FCOPMB UF E K DISK FCOLMBID IF E K DISK RENAME(COPMB1:COLMBID1) PREFIX(M2_)

An Introduction to ILE RPG: Part 1

Figure

8 IGNORE and INCLUDE

RPG/400 *.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 10 FFilenameIPEAF....RlenLK1AIOvKlocEDevice+......KExit++Entry+A....U1....... FALLMBID IF E K DISK KIGNOREFORMAT2

F F

KIGNOREFORMAT3 KIGNOREFORMAT4

ILE RPG *.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 10 FFilename++IPEASFRlen+LKlen+AIDevice+.File continuation++++++++++++++++++++Comments++++++++++++ FALLMBID IF E K DISK INCLUDE(FORMAT1)

An Introduction to ILE RPG: Part 1

Figure

9 COMMIT

RPG/400 *.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 10 FFilenameIPEAF....RlenLK1AIOvKlocEDevice+......KExit++Entry+A....U1....... FCOLMBID UF E K DISK KCOMIT ILE RPG *.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 10 FFilename++IPEASFRlen+LKlen+AIDevice+.File continuation++++++++++++++++++++Comments++++++++++++ FCOLMBID UF A E K DISK COMMIT(C_COLMBID)

An Introduction to ILE RPG: Part 1

Figure

10 TOFILE

RPG/400 *.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 10 FFilenameIPEAF....RlenLK1AIOvKlocEDevice+......KExit+ +Entry+A....U1.......FOS6M ASTRIP E DISK FADDROUT IR F 3 3 T EDISK E....FromfileTofile++ArrnamN/rN/rbLenPDSArrnamLenPDSComments............... E ADDROUT OS6MASTR ILE RPG *.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 10 FFilename++IPEASFRlen+LKlen+AIDevice+.File continuation++++++++++++++++++++Comments++++++++++++ FOS6MASTR IP E DISK FADDROUT IR F 3 3 TDISK TOFILE(OS6MASTR)

An Introduction to ILE RPG: Part 1

Figure

11 OFLIND, FORMLEN and FORMOFL

RPG/400 *.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 10 FFilenameIPEAF....RlenLK1AIOvKlocEDevice+......KExit++Entry+A....U1....... FINVOICESO F 132 OF LPRINTER LFilenameFlnFlOlnOl........................................................ LINVOICES 51FL 44OL ILE RPG *.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 10 FFilename++IPEASFRlen+LKlen+AIDevice+.File continuation++++++++++++++++++++Comments++++++++++++ FINVOICES O F 132 PRINTER OFLIND(OF) FORMLEN(51) FORMOFL(44)

An Introduction to ILE RPG: Part 1

Figure

12 Changes to the PRTCTL Data Structure

RPG/400 Description Space before

Positions 1-1

ILE RPG Length 1

Positions 1-3

Length 3

Space after

2-2

1

4-6

3

Skip to line number before

3-4

2

7-9

3

Skip to line number after

5-6

2

10-13

3

Current line count

7-9

3

13-15

3

An Introduction to ILE RPG: Part 2 This is the second article in a multipart series on the ILE RPG language planned for release later this year. In each article, we will cover specific changes to RPG coding and some of the broader design issues resulting from the new features and underlying ILE facilities. IN THIS ARTICLE... The new Definition Specifications.

COMING NEXT MONTH... I-specs, C-specs and O-specs. Brief: In the second installment of our indepth coverage of ILE RPG, we'll look at the new Definition Specifications (D-specs). D-specs consolidate definitions for arrays, data structures, named constants, data areas and work fields that are not part of any file. They replace E-specs and take over some functions from RPG/400, I-specs and C-specs. In addition, D-specs provide new ways to define some data constructs. Last month, we introduced the new ILE (Integrated Language Environment) RPG which should be announced as part of V3R1M0. We saw that a lot of changes are in store for the RPG programmer. Field, file and other symbolic names can now be up to 10 characters long. Upper- and lowercase field names are now supported. Many limits have been increased and others virtually eliminated. Control Specifications (H-specs) have been transformed from fixed format to keyword notation. Line Counter Specifications (L-specs) have been eliminated and their function moved to File Description Specifications (F-specs). And the F-specs themselves have undergone major changes, not just to accommodate longer file names and larger record and key lengths, but also due to the use of keyword notation for file continuation keywords and other file attributes. We're about to see even more radical changes. Extension Specifications (E- specs) have been eliminated entirely. Array and table definitions have been moved to the new Definition Specifications (D-specs). Named constant and data structure definitions have been moved from Input Specifications (I-specs) to the D-specs. Definitions for LIKE fields and data areas are also supported in D-specs. 1 illustrates the overall design of a D-spec and where each entry is coded. We're about to see even more radical changes. Extension Specifications (E- specs) have been eliminated entirely. Array and table definitions have been moved to the new Definition Specifications (D-specs). Named constant and data structure definitions have been moved from Input Specifications (I-specs) to the D-specs. Definitions for LIKE fields and data areas are also supported in D-specs. Figure 1 illustrates the overall design of a D-spec and where each entry is coded. Let's take a look at D-specs and see how they can improve your productivity. Definition Specifications (D-specs) The D-specs are designed to consolidate all data definitions in one section of your program. Although you can still define fields in C-specs, your code will be easier to maintain if you define all your work fields and literals in D- specs. You may hear some people refer to D-specs as Data Specifications. While D-specs do define data, the proper terminology is Definition Specific-ation so that's what we'll try to remember to use. In the following sections, we'll begin by looking at simple data constructs such as named constants and work fields. Then, we'll look at more complex examples such as data structures and arrays. Both an RPG/400 and an ILE RPG solution are shown whenever possible. However, the explanation of each example concentrates on the ILE RPG implementation. Named Constants

In RPG/400, named constants can appear anywhere in I-specs, even within a data structure definition. This is not true in ILE RPG. Named constants cannot appear within a data structure definition. If the RPG/400-to-ILE RPG source- conversion utility finds named constants embedded in a data structure, it moves the named constants outside of the data structure as part of the sourceconversion process. 2 shows the definition of several named constants: the character constants CMPNY and LWR, the numeric constant TWENTY, and the hexadecimal constant DUP. Only a few entries are required: Figure 2 shows the definition of several named constants: the character constants CMPNY and LWR, the numeric constant TWENTY, and the hexadecimal constant DUP. Only a few entries are required: o The C in position 24 defines a named constant. o The value you enter for the CONST keyword defines the value of the constant. Although a value is required for the constant, you do not have to preface the value with the CONST keyword. The first constant, CMPNY, uses the CONST keyword to define a character string. The second example includes several variations: o The CONST keyword is omitted and the character constant is defined by enclosing the literal value in single quotes. o The trailing hyphen indicates that the value continues on the next line, starting with the first character of the functions section (position 44). The final two examples show the definition of noncharacter constants. The numeric constant TWENTY is defined by specifying a numeric value not enclosed in single quotes. Hexadecimal constants can be defined by specifying an X followed by a valid hexadecimal value enclosed in single quotes. In the example, DUP is defined as a hexadecimal constant with a value of X'1C' to represent the character returned when the DUP key is pressed. The actual CONST keyword is optional for all constants, regardless of their data type. Stand-alone Fields Traditionally, RPG programmers have defined work fields in C-specs. Although this is still possible using ILE RPG, you can define stand-alone fields that are not part of any file or data structure in Dspecs. We'll look at several examples in 3. One special entry is required for stand-alone fields: We'll look at several examples in Figure 3. One special entry is required for stand-alone fields: o An S in column 24 of the D-spec defines a stand-alone field. The first example is a seven-digit, work field (PACK72). It is stored in packed-decimal format and has two decimal places. In RPG/400 you are forced to make this field part of a data structure even though it does not logically need to be associated with any other field.

o The length of the field is coded in positions 33 to 39 rather than using starting and ending positions. The positions within the D-specs are different than those for I-Specs but contain the same type of entries. Our second example defines LRGROS based on the field PRGROS. LRGROS is defined as two characters larger than PRGROS. ILE RPG permits you to use either the LIKE keyword in D-specs or the *LIKE DEFINE operation in C-specs to define a field based on the characteristics of another field. The final example of a stand-alone field illustrated in 3 defines XXNAME with the same characteristics as the field PRNAME. One new keyword is added for this example: The final example of a stand-alone field illustrated in Figure 3 defines XXNAME with the same characteristics as the field PRNAME. One new keyword is added for this example: o The INZ keyword specifies the value to which a field is initialized. Initializing fields using this method is more efficient than initializing them in the C-specs. When the INZ keyword is not specified, the default value is blank for character fields and zero for nu-meric fields. Data Structures Complex data organizations are one of the primary reasons for adding D-specs to the RPG language definition. The first of these more complex forms that we'll examine is the data structure. 4 illustrates two ways to code a data structure in ILE RPG. In the first example, the ILE RPG code is very similar to the RPG/400 code. It uses absolute notation to designate the starting and ending positions of each subfield. The differences between the RPG/400 example and this ILE RPG example are based on general rules for formating ILE RPG. Figure 4 illustrates two ways to code a data structure in ILE RPG. In the first example, the ILE RPG code is very similar to the RPG/400 code. It uses absolute notation to designate the starting and ending positions of each subfield. The differences between the RPG/400 example and this ILE RPG example are based on general rules for formating ILE RPG. o The subfields may be indented to make the data structure easier to understand. o You can use lowercase or uppercase field names at your discretion. As we mentioned last month, lowercase field names will be automatically translated to uppercase by the compiler. The second ILE RPG sample takes advantage of a several new features. o Length notation is used instead of specifying the starting and ending positions for each field. The length of each subfield is specified in positions 33 to 39. The rest of the syntax is identical to absolute notation (e.g., coding a 'P' for packed data, specifying decimal positions, and so forth). o The OVERLAY keyword further subdivides a subfield within a data structure. The first parameter indicates the name of the subfield whose storage is to be overlaid. This subfield must have been previously defined in the same data structure. The second parameter specifies the starting position within the field. The starting position is optional and defaults to 1.

As shown in this example, OVERLAY(GLNUM) is specified for the field glcmpy. Since glcmpy has a length of 2 and the starting position defaults to 1, the field glcmpy is defined as the first two positions of the field glnum. For the field glmain, we specified OVERLAY(GLNUM:3). Since glmain has a length of 4 and the starting position is 3, the field glmain is defined as positions 3 to 6 of the field glnum. Finally, the field glsub is defined as positions 7 to 11 of the field glmain. When using the OVERLAY keyword, the subfield being defined may not extend beyond the end of the field being overlaid. In our sample, specifying OVERLAY(GLNUM:8) for the field glsub would cause an error. Because glsub is a five-character field, starting in position 8 would extend this field to position 12. Since glnum is only 11 characters in length, an error would occur. If length notation is used, any changes to starting position within the field glnum will not affect subsequent fields that aren't part of glnum. Overlaid fields, however, will be affected. For example, if you increase the length of glnum to 13 and of glmain to 6, you should change the starting position of glsub so that glmain and glsub do not overlap. But no changes are required for the fields glclas and glcat. Length notation can make future modifications easier than using absolute notation. When the length of a field changes, the subsequent fields do not have to be modified. In this example, the field gldesc could be expanded to 40 positions without making any changes to the definition of glnum or its subfields. Nice job, IBM! 5 illustrates an externally defined data structure. The ILE RPG portion of this example uses several keywords that were shown in previous examples or in last month's article on H-specs and F-specs. One new keyword is introduced. Figure 5 illustrates an externally defined data structure. The ILE RPG portion of this example uses several keywords that were shown in previous examples or in last month's article on H-specs and Fspecs. One new keyword is introduced. o The E in column 22 specifies that this is an externally defined data structure. o The EXTNAME keyword indicates that the data structure is defined based o the definition of the first (or only) record format of the file OELPMNM. To explicitly define the record to be used, you might code EXTNAME (OELPMNM:OELPMNM9), indicating the record format OELPMNM9 should be used even if it is not the first record format in the file. o The PREFIX keyword implicitly renames the fields in the data structure. This global rename function is similar to what we covered in F-specs last month. PMFNUM is renamed P2_PMFNUM, PMTNUM is renamed P2_PMTNUM, PMFZIP is renamed P2_PMFZIP, and PMTZIP is renamed P2_PMTZIP. o The INZ keyword was specified for the data structure DSSEL to initialize numeric subfields to zero and character subfields to blank. The INZ keyword on the subfield lines for P2_PMTNUM and P2_PMTZIP overrides the default initialization for the data structure DSSEL. Finally, we have explicitly renamed the field PMFLAG to XXPMFLAG. The PREFIX keyword does not affect an explicitly renamed field; so there will be a field named XXPMFLAG in the program, but there will not be fields named P2_PMFLAG or PMFLAG unless they are defined elsewhere.

The example in 6 associates a data structure with an external data area. It uses one new keyword. The example in Figure 6 associates a data structure with an external data area. It uses one new keyword. o The U in position 23 indicates the data structure is a data area. o The DTAARA keyword can be used to specify the name of a data area. Special parameter values for this keyword are *LDA for the local data area and *PDA for the PIP (program initialization parameters) data area. ILE RPG permits you to use either the DTAARA keyword in D-specs or the *DTAARA DEFINE operation in C-specs to associate external data areas with internal program structures. Tables and Arrays In this section, we'll look at several examples of arrays and tables and the new capabilities that ILE RPG provides for them. The essential definition of arrays has not changed. ILE RPG supports the three types of arrays (compile-time, prerun-time and run-time) currently available with RPG/400, and the same basic rules apply. However, ILE RPG uses keywords to define the number of elements, from and to files, and the type of array. As in RPG/400, an array becomes a table if its name begins with the letters TAB. We'll refer to tables and arrays generically as arrays unless an example specifically uses a table. 7 shows a run-time array coded in RPG/400 using an E-spec, and coded in ILE RPG using a Dspec. This example illustrates the new structure of array definitions. Figure 7 shows a run-time array coded in RPG/400 using an E-spec, and coded in ILE RPG using a D-spec. This example illustrates the new structure of array definitions. o The S in position 24 of the D-spec has the same meaning as it has for stand-alone fields. It indicates that the array is not part of a data structure. o The length for each element is coded in positions 33 to 39. o The DIM keyword defines the dimension (the number of elements) of the array. 8 shows a compile-time array. Several new keywords are required to define how the compile-time array data is included in the source code. Figure 8 shows a compile-time array. Several new keywords are required to define how the compile-time array data is included in the source code. o The CTDATA keyword indicates the array will be loaded from compile-time data included at the end of the source member. o The PERRCD keyword is used for compile-time and prerun-time arrays to specify the number of elements loaded from each record. The default is PERRCD(1) when CTDATA is specified, so this parameter does not have to be coded. It is included here to make the code easier to understand.

o Finally, the ASCEND keyword signifies that the array is in ascending sequence. Use of the DESCEND keyword would designate descending sequence. 9 introduces several additional concepts. This example loads two tables (everything in this example is valid for arrays as well as tables) from a file at prerun-time. The data is loaded the first time the program is called. There are three new keywords: Figure 9 introduces several additional concepts. This example loads two tables (everything in this example is valid for arrays as well as tables) from a file at prerun-time. The data is loaded the first time the program is called. There are three new keywords: o The ALT keyword is specified to associate the alternating table TABTOT with the primary table TABDPT. o FROMFILE(OLDDEPT) causes the tables TABDPT and TABTOT to be loaded from the file OLDDEPT when the program is called for the first time. o The EXTFMT keyword can be used to specify the external data format for compile-time and prerun-time arrays. In this example, EXTFMT(P) specified for the table TABTOT indicates that data elements of this table are stored in packed, decimal format in the file OLDDEPT. Other formats, including the new date and timestamp formats, are also valid. In this example, the PERRCD(1) keyword must be coded. PERRCD(1) specifies that one element of each table is loaded from each record of the file OLDDEPT. The keywords for the table TABDPT continue on a second line. If positions 7 to 43 of a D-spec are blank, the compiler assumes the line is a continuation of the previous line. In fact, a keyword can be coded on one line and its parameter coded on the next line, as in the case of the keyword FROMFILE and its parameter OLDDEPT. However, you should not code in this manner since it can be confusing; the code is included here for illustration purposes only. ILE RPG also permits spaces between the keyword and its parameter, as shown with the PERRCD keyword. 10 shows the run-time array SRT. Because this is a run-time array, the PERRCD keyword is not used. There is one new keyword in this example: Figure 10 shows the run-time array SRT. Because this is a run-time array, the PERRCD keyword is not used. There is one new keyword in this example: o The INZ keyword permits different initialization values to be specified for the array. In the ILE RPG example, we have specified a default value of *HIVAL at compile time, instead of using a MOVE in C-specs at run time as you see in the RPG/400 sample. The INZ keyword causes the array to be initialized with the specified value the first time the program is called. If the program returns without setting on LR and is called again, the INZ keyword has no effect the second time the program is called so the array still has the same value it had when the program last returned. By default, the initialization values are based on the data typeblanks for character data and zeroes for numeric data. To illustrate this point, the sample explicitly defines SRT as a character array with the data type of A in position 40. The data type is optional because, as in DDS, a field with no decimal positions specified defaults to a character field.

With the constraints of RPG/400 E-specs removed, what's in the future for arrays in ILE RPG? How about a two-dimensional array coded with a technique such as DIM(99:12)? In our sample, this might indicate 99 elements in the first dimension and 12 in the second. Perhaps we'll see this support in a future ILE RPG release. What's Next? The new D-specs permit us to consolidate data definitions in a single place in our programs, which can make them easier to understand and modify. In addition, the OVERLAY, PREFIX and length notations provide substantial usability improvements in ILE RPG. What does the future hold? Since we can define any field or array in D-specs, how about permitting D-specs at the start of a subroutine to define local variables? Wouldn't it be nice to be able to use fields or arrays in a subroutine and not have to worry if they are used elsewhere in the program? Perhaps we'll see local variables implemented in a future ILE RPG release. In our next article, we will tackle I-specs, C-specs, O-specs, and introduce Built-In Functions (BIFs). Charlie Massoglia, president of Massoglia Technical Consulting, Inc. in Okemos, Michigan, has authored a number of midrange books. His cowboy hat is his trademark for his frequent speaking tours throughout the United States, Canada, Europe and Australia. Charlie can be reached at 517676-9700. An Introduction to ILE RPG: Part 2

Figure 1 D-spec Layout UNABLE TO REPRODUCE GRAPHICS

An Introduction to ILE RPG:

Figure

Part 2

2 Named Constants

... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 0 I..............Namedconstant+++++++++C.........Fldnme...................... I 'Midrange Computing' C CMPNY I 'abcdefghijklmnopqrs- C LWR I 'tuvwxyz' I 20 C TWENTY I X'1C' C DUP

An Introduction to ILE RPG:

Part 2

Figure

3 Stand-alone Fields

... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 0 IDsname....NODsExt-file++.............OccrLen+............................. I DS I..............Ext-field+............PFromTo++DField+...................... I P 1 42PACK72 CL0N01N02N03Factor1+++OpcdeFactor2+++ResultLenDHHiLoEqComments+++++++...... C *LIKE DEFN PRGROS LRGROS+ 2 C *LIKE DEFN PRNAME XXNAME C MOVEL'Missing' XXNAME P P=Pad with blanks

An Introduction to ILE RPG:

Figure

Part 2

4 Data Structures

... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 0 IDsname....NODsExt-file++.............OccrLen+............................. IGLDS DS I..............Ext-field+............PFromTo++DField+...................... I 1 30 GLDESC I 31 41 GLNUM I 31 32 GLCMPY I 33 36 GLMAIN I 37 41 GLSUB I 42 44 GLCLASS I 45 48 GLCAT

An Introduction to ILE RPG:

Figure

Part 2

5 Externally Defined Data Structures

... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 0 IDsname....NODsExt-file++.............OccrLen+............................. IDSSEL EIDSOELPMNM I..............Ext-field+............PFromTo++DField+...................... I PMFNUM P2FNUM I PMTNUM P2TNUM I PMFZIP P2FZIP I PMTZIP P2TZIP CL0N01N02N03Factor1+++OpcdeFactor2+++ResultLenDHHiLoEqComments+++++++...... C *INZSR BEGSR

C C C

MOVE *ALL'9' MOVE *ALL'9' ENDSR

An Introduction to ILE RPG:

Figure

P2TNUM P2TZIP

Part 2

6 Data Areas

... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 0 IDsname....NODsExt-file++..............OccrLen+............................ IINV#DS DS I............Ext-field+..............PFromTo++DField+L1M1..PlMnZr.......... I 1 70$INV# I 8 8 $ISTS CL0N01N02N03Factor1+++OpcdeFactor2+++ResultLenDEHiLoEqComments+++++++...... C *NAMVAR DEFN INV#DS OEAIN Invoice # DTAARA

An Introduction to ILE RPG:

Figure

Part 2

7 Run-time Array

... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 0 E....FromfileTofile++Name++N/rN/tbLenPDSArrnamLenPDSComments+++++++++...... E DEPT 10 2

An Introduction to ILE RPG:

Figure

Part 2

8 Compile-time Array

... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 0 E....FromfileTofile++Name++N/rN/tbLenPDSArrnamLenPDSComments+++++++++...... E DEPT 1 10 2 A

An Introduction to ILE RPG:

Part 2

Figure

9 Prerun-time Arrays

... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 0 E....FromfileTofile++Name++N/rN/tbLenPDSArrnamLenPDSComments+++++++++...... E OLDDEPT TABDPT 1 100 3 0ATABTOT 9P2

An Introduction to ILE RPG:

Figure

Part 2

10 Initializing an Array

... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 0 E....FromfileTofile++Name++N/rN/tbLenPDSArrnamLenPDSComments+++++++++...... E SRT 99 10 CL0N01N02N03Factor1+++OpcdeFactor2+++ResultLenDEHiLoEqComments+++++++...... C *INZSR BEGSR C MOVE *HIVAL SRT C ENDSR

An Introduction to ILE RPG: Part 3 Brief: Our third installment on ILE RPG covers changes to I-specs, C-specs and O-specs. All three have been modified to accommodate the longer field name, field length and decimal position entries. We'll focus on C-specs where free- form expressions can greatly simplify the code for both logical and arithmetic comparisons and calculations. You'll see that the basic components of RPG/400 have been retained but significant new function has been added to the language with these changes. Last month we continued our review of the new Integrated Language Environment RPG (ILE RPG) which will be announced as part of V3R1M0. We saw the elimination of Extension specifications (E-specs) with array and table definition moved to the new Definition specifications (D-specs). Named constant and data structure definition has been moved from Input specifications (I-specs) to D-specs. Our programs should be more maintainable with the ability to consolidate all data definition into a single location-D-specs.

Substantial productivity gains should result from the introduction of the OVERLAY and PREFIX keywords and the ability to use length notation in data structures. What's left? We'll see minor changes to I-specs and Output specifications (O- specs). However, radical changes abound in Calculation specifications (C- specs). For example, ILE RPG C-specs can use symbolic operators that may not be familiar to RPG programmers. Combine this with lowercase variable names and free-form expressions-C-specs don't look the same. Let's take a quick look at I-specs and then move on to explore the tremendous productivity gains offered by the changes in C-specs. We'll finish with a review of O-specs. Input Specifications (I-specs) Several major changes have been made to I-specs in ILE RPG. Most obvious are the changes required to accommodate 10-character file and field names, longer field lengths, and two positions for the number of decimal digits. While adjusting to these changes will be almost intuitive, other changes will require some education. The ability to specify date and time format and separator characters has been added to I-specs for program described files. As we discussed last month, data structures, data structure subfields and named constants are no longer defined in I-specs. Their definition has been moved to the new D-specs. Externally Described Files Most native RPG/400 programs do not require I-specs for files. The same is true of ILE RPG programs. The only time you need to code I-specs for externally described files is when you want to assign indicators or rename fields. When you start using ILE RPG, hopefully your files will all be externally described so you do not have to use program described files. Contrary to conventional wisdom, our shop does use control level indicators for reports since there is no easier way to produce subtotals and we have found negligible performance differences between input primary and full procedural files. Without getting into a debate about whether or not control level indicators should be used, let's refer to 1 for a sample of assigning these indicators in RPG/400 and ILE RPG. Contrary to conventional wisdom, our shop does use control level indicators for reports since there is no easier way to produce subtotals and we have found negligible performance differences between input primary and full procedural files. Without getting into a debate about whether or not control level indicators should be used, let's refer to Figure 1 for a sample of assigning these indicators in RPG/400 and ILE RPG. In this simple example, we have assigned record identifying indicator 01 to record format ARPCM1 in our ARPCM customer master file. In addition, control level indicator L6 has been assigned to the customer number field ARCUST. Except for positioning and the ability to specify 10-character record format and field names, the RPG/400 and ILE RPG I-spec record and field layouts are identical for externally described files.

If you are using I-specs to rename all of the fields in a record format, you can accomplish this globally by specifying the new PREFIX keyword on the F- specs. (See Part 1 of this series if you need a refresher.) Also, field names with lengths that exceed six characters no longer need to be renamed since ILE RPG supports 10-character field names. Program Described Files 2 shows that the only changes to the I-spec record layout for a program described file are support for a 10-character file name and 99,999-byte record length. In the example, we have assigned record identifying indicator 01 to records with the character A in position 1 and record identifying indicator 02 to records with the character C in position 1. Figure 2 shows that the only changes to the I-spec record layout for a program described file are support for a 10-character file name and 99,999-byte record length. In the example, we have assigned record identifying indicator 01 to records with the character A in position 1 and record identifying indicator 02 to records with the character C in position 1. The I-spec field layout shows similar changes to accommodate 10-character field names, from and to positions up to 99,999, and decimal positions up to 30. The 14 positions for the field name will make it easier to specify array indices. In the RPG/400 example, the field TRDATE is defined as a character field with a length of eight. In the ILE RPG example, we have modified the definition of this field by adding *MDY in positions 31 to 34 to denote an external date/time type of MMDDYY, a slash (/) in position 35 to indicate the date/time separator character, and a D in position 36 to define the data type of date. These additions define the field TRDATE as a date field in MMDDYY format with a slash (/) as the separator character. ILE RPG now directly supports date (D), time (T) and timestamp (Z) data types. *DMY, *YMD, *JUL, *HMS and several other formats can be specified. We'll go into more detail on the use of these data types next month. Figures 3 and 4 summarize changes to I-specs for program described files. Calculation Specifications (C-specs) C-specs have undergone major modification in ILE RPG. Many changes were required to accommodate relaxed limits in ILE RPG, while other changes provide substantial usability improvements. 5 shows factor 1, factor 2 and the result field have all been increased to 14 characters to handle 10character symbolic names with extra space for an array index when needed. Other changes are also apparent. Figure 5 shows factor 1, factor 2 and the result field have all been increased to 14 characters to handle 10-character symbolic names with extra space for an array index when needed. Other changes are also apparent. The operation code has been increased to six characters, but the implementation is not consistent. REDPE has been changed to READPE but, for some reason, the DIV operation has not been

changed to DIVIDE. Somewhat confusing, isn't it? The old five-character operation codes will no longer work in C-specs. 6 summarizes changes to operation codes. The operation code has been increased to six characters, but the implementation is not consistent. REDPE has been changed to READPE but, for some reason, the DIV operation has not been changed to DIVIDE. Somewhat confusing, isn't it? The old five-character operation codes will no longer work in C-specs. Figure 6 summarizes changes to operation codes. The operation extender has been moved to follow the operation code and must be enclosed in parentheses (). Operation extenders include H for half adjust, N for read with no lock and P for pad with blanks. As in I-specs, decimal positions up to 30 are now supported in C-specs. In our ILE RPG sample (5), we have modified the number of decimal positions for the field XRATIO from 9 to 15 and its length from 19 to 23. As in I-specs, decimal positions up to 30 are now supported in C-specs. In our ILE RPG sample (Figure 5), we have modified the number of decimal positions for the field XRATIO from 9 to 15 and its length from 19 to 23. Only a single conditioning indicator is permitted. If you have old code which uses more than one conditioning indicator, the RPG/400-to-ILE RPG source- conversion utility will automatically put each indicator on a separate statement. Having to put resulting indicators such as the end-of-file indicator in positions 75 to 76 is going to cause some problems for those of us with 80- character terminals. The only way to key something beyond position 71 in SEU on an 80-character terminal is to prompt the statement or window to the right. And remember, comments are in positions 81 to 100 for all ILE RPG specifications. Perhaps now is the time to start thinking about budgeting to replace those 80- column clunkers with 132column terminals or PCs. Free-form Arithmetic Expressions ILE RPG supports free-form expressions in C-specs. Instead of having to code a complex formula a single step at a time, the new EVAL operation code can be used with an extended factor 2. Standard arithmetic operators supported include: + * / **

Addition Subtraction Multiplication Division Exponentiation

Factor 1 must be blank. The half adjust operation code extender (H) may be used with EVAL but N and P are not valid. While conditioning indicators may be used, as with all C-specs they should be avoided if possible. If you're using control level indicators in your I-specs, use a single, control level indicator in your C-specs to control execution of a subroutine. Because RPG is not an indicator- optimized compiler, indicators should be referenced as little as possible. Blanks can be freely interspersed between operands and operators to make the code easier to understand. In some cases, blanks are required-for example to differentiate between exponentiation

and multiplication of a reserved word beginning with an asterisk. Consider the following expression: A**TIME This expression is interpreted as the field A raised to the power of the field TIME. If multiplication by the new reserved word, *TIME, is intended, the expression should be coded in one of these two ways: A* *TIME A * *TIME We'll address date and time data types including the *TIME reserved word next month. We'll look at some simple samples of EVAL in 7. The first sample replaces a single calculation. The field oecost is computed as the value of the field oeqty times the field impric. The half adjust operation extender has been enclosed in parentheses and moved next to the operation code. We'll address date and time data types including the *TIME reserved word next month. We'll look at some simple samples of EVAL in Figure 7. The first sample replaces a single calculation. The field oecost is computed as the value of the field oeqty times the field impric. The half adjust operation extender has been enclosed in parentheses and moved next to the operation code. The second sample is a two-part calculation. The field oewght is computed as the value of the field oeqty times the field imwght, with the field pkwght added to the result. Based upon the rules of precedence, the use of parentheses is optional. Remember high school algebra? It finally has some value. The order of precedence for arithmetic operations in ILE RPG free-form expressions is the same as it was in high school algebra: o o o o

parentheses exponentiation multiplication and division addition and subtraction

In the last sample in 7, the field oestax is computed as the value of the field oecost minus the field oedisc, with the field sttax multiplied by the result. The parentheses in this case are required. Without them, the field oedisc would be multiplied by the field sttax and the result would be subtracted from the field oecost, yielding erroneous results. In the last sample in Figure 7, the field oestax is computed as the value of the field oecost minus the field oedisc, with the field sttax multiplied by the result. The parentheses in this case are required. Without them, the field oedisc would be multiplied by the field sttax and the result would be subtracted from the field oecost, yielding erroneous results. To make your code more readable, feel free to use parentheses even if they are not required. Some complex formulae can require several lines of code. Or sometimes it's convenient to break up your code into several lines to make them more readable. 8 shows such an example.

Some complex formulae can require several lines of code. Or sometimes it's convenient to break up your code into several lines to make them more readable. Figure 8 shows such an example. We want to compute the total of first-, second- and third-shift pay, remembering to add in shift premium before multiplying rate times hours. We can replace seven RPG/400 calculations with a single ILE RPG expression. Nice job, IBM! If the field tmpay is not large enough to hold the result, a numeric overflow exception occurs and the status code in the program status data structure is set to 103. This produces a run-time halt. If numeric overflow occurs in ILE RPG in arithmetic operations such as Z-ADD which do not involve expressions, truncation without a halt will occur just as it does in RPG/400. Specifying TRUNCNBR(*NO) when compiling an ILE RPG program will force a run-time halt any time numeric overflow occurs. Continued Literals The ILE RPG example in 9 contains two expressions with continued literals. The first uses a plus sign (+) continuation character which means the literal is continued with the first non-blank character in positions 36 to 80 of the next line. The second example uses a hyphen (-) continuation character which means the literal is continued in position 36 of the next line even if it contains a blank. The fields des1 and des2 will both have the same value. The ILE RPG example in Figure 9 contains two expressions with continued literals. The first uses a plus sign (+) continuation character which means the literal is continued with the first non-blank character in positions 36 to 80 of the next line. The second example uses a hyphen (-) continuation character which means the literal is continued in position 36 of the next line even if it contains a blank. The fields des1 and des2 will both have the same value. An expression can be continued over multiple lines. Continued lines must be blank in positions 7 to 35. No special continuation character is required unless a literal is being continued. Comment lines with an asterisk (*) in position 7 can be interspersed between continued lines. Blank lines can also be used. Free-form Logical Expressions In addition to the EVAL operation, ILE RPG also supports free-form expressions for the new DOU, DOW, IF and WHEN operations. These operations are functionally equivalent to the DOUxx, DOWxx, IFxx and WHENxx operations except instead of comparing factor 1 to factor 2, the extended factor 2 entry is used for the comparison. Valid operators include: = >= > ) have a lower order of precedence than arithmetic operators; consequently, the arithmetic is done first, followed by the comparison. If AND or OR is used, these logical operations are performed last because they are lowest in order of precedence. 13 summarizes changes to C-specs. Figure 13 summarizes changes to C-specs. Output Specifications (O-specs) Many of the changes to O-specs are very similar to what we saw in I-specs. 14 shows the expanded space to support ending positions up to 99,999 and names for 10-character files, record formats, fields and except labels. Unlike C-specs, all three conditioning indicators have been retained in Ospecs. Many of the changes to O-specs are very similar to what we saw in I-specs. Figure 14 shows the expanded space to support ending positions up to 99,999 and names for 10-character files, record formats, fields and except labels. Unlike C-specs, all three conditioning indicators have been retained in O-specs. In the ILE RPG example, we have also modified the definition of our field TRDATE by adding a D in position 52 and *MDY/ in positions 53 to 57 to denote an external date data type of month/day/year with a slash (/) separator character. 15 shows some of the changes in O-specs for coding program described printer files. RPG/400 only supports zero to three space before or space after lines. Our RPG/400 example therefore requires two exception output statements to space five lines before printing-one statement to space three lines and another to space two lines. Figure 15 shows some of the changes in O-specs for coding program described printer files. RPG/400 only supports zero to three space before or space after lines. Our RPG/400 example therefore requires two exception output statements to space five lines before printing-one statement to space three lines and another to space two lines. ILE RPG requires only a single line since values from 0 to 255 are supported for space before and space after lines. In addition, skip before and skip after line numbers can now be from 0 to 255. Constants or edit words can be continued on multiple lines in positions 53 to 80. The line being continued must end with a plus sign (+) or hyphen (-). A plus sign (+) means continuation starts with the first nonblank character in or past position 53 of the next line. A hyphen (-) means continuation starts in position 53 of the next line even if it is blank. The continuation line must contain an O in position 6 and be blank in positions 7 to 52. Blank separator lines and comment lines are permitted between continued lines.

16 summarizes changes to O-specs. Figure 16 summarizes changes to O-specs. What's Next? We've seen many of the changes to the I-specs, C-specs and O-specs were required to accommodate the change from 6-character to 10-character symbolic names and the support of increased file record lengths, field lengths and number of decimal positions. The new EVAL, DOU, DOW, IF and WHEN operations and the introduction of expressions to C-specs provide even more usability improvements to ILE RPG. In our next article, we introduce built-in functions (BIF) and tackle date/time data types including the new date/time arithmetic operation codes. Charlie Massoglia, president of Massoglia Technical Consulting, Inc. in Okemos, Michigan, has authored a number of midrange books. His cowboy hat is his trademark for his frequent speaking tours throughout the United States, Canada, Europe and Australia. Charlie can be reached at 517676-9700. An Introduction to ILE RPG: Part 3

Figure 1 I-spec Externally Described File

*. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 FFilenameIPEAF....RlenLKlAIOvKlocEDevice+......Kexit++Entry+A....U1........ FARPCM IP E DISK IRcdname+....In............................................................ IARPCM1 01 I..............Ext-field+......................Field+L1M1..PlMnZr.......... I ARCUSTL6

+

*. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...

FFilename++IPEASFRlen+LKlen+AIDevice+.File_continuation+++++++++++++++++++ +Comme FARPCM IP E DISK IRcdname++ +....Ri..........................................................Comme IARPCM1 01 I..............Ext-field+..................Field++++++++ +L1M1..PlMnZr......Comme I ARCUST L6

An Introduction to ILE RPG: Part 3

Figure

2 I-spec Program Described File

*. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 IFilenameSqNORiPos1NCCPos2NCCPos3NCC....................................... IARTRAN NS 01 1 CA I OR 02 1 CC I....................................PFromTo++DFldnmeL1M1FrPlMnZr......... I 1 1 TRCODE I 2 80TRCUST I 9 16 TRDATE I P 17 212TRAMT

+

*. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...

IFilename+ +SqNORiPos1+NCCPos2+NCCPos3+NCC..................................Comme IARTRAN NS 01 1 CA I OR 02 1 CC I........................Fmt+SPFrom+To+++DcField++++++++ +L1M1FrPlMnZr......Comme I 1 1 TRCODE I 2 8 0TRCUST I *MDY/D 9 16 TRDATE I P 17 21 2TRAMT

An Introduction to ILE RPG: Part 3

Figure 3 Changes to I-spec Record Layout for Program Descri

RPG/400 || ILE RPG || SEU Format Position || Position || Abbreviation || Explanat ----------+-------------+------------------+------------------------------7-14 || 7-16 || Filename || File n 15-16 || 17-18 || Sq || Sequence check 17 || 19 || N || Num 18 || 20 || O || Opt 19-20 || 21-22 || Ri || Record identifying indica 21-24 || 23-27 || Pos1 || Posit 28-31 || 31-35 || Pos2 35-38 || 39-43 || Pos3 25 || 28 || N || 32 || 36 || 39 || 44 || 26 || 29 || C || C 33 || 37 || 40 || 45 || 27 || 30 || C || Charac

34 41 75-80

|| || ||

38 46 81-100

|| || ||

||

Comme

An Introduction to ILE RPG: Part 3

Figure 4 Changes to I-spec Field Layout for Program Describ

RPG/400 || ILE RPG || SEU Format Position || Position || Abbreviation || Explanat ----------+-------------+------------------+------------------------------New || 31-34 || Fmt || External date/time for New || 35 || S || Date/Time separator charac 43 || 36 || P || External data for 44-47 || 37-41 || From || From posit 48-51 || 42-46 || To || To posit 52 || 47-48 || D || Decimal positi 53-58 || 49-62 || Field || Field n 59-60 || 63-64 || L1 || Control level indica 61-62 || 65-66 || M1 || Matching record indica 63-64 || 67-68 || Fr || Field record relation indica 65-66 || 69-70 || Pl || Positive field indica 67-68 || 71-72 || Mn || Negative field indica 69-70 || 73-74 || Zr || Zero field indica 75-80 || 81-100 || || Comme

An Introduction to ILE RPG: Part 3

Figure

5 C-spec Operation Extender and Decimal Positions

*. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 CL0N01N02N03Factor1+++OpcdeFactor2+++ResultLenDHHiLoEqComments+++++++...... C K#DS REDPEARPDS 50 C *IN50 IFNE *ON C OECOST DIV DSAMT XRATIO 199H C ENDIF

+

*. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...

CL0N01Factor1+++++++Opcode(E)+Factor2+++++++Result++++++++Len+ +D+HiLoEq....Comme C K#DS READPE ARPDS C *IN50 IFNE *ON C OECOST DIV(H) DSAMT XRATIO 2315 C ENDIF

50

An Introduction to ILE RPG: Part 3

Figure

6 Renamed and Expanded Operation Codes

RPG/400 || ILE RP --------------+-------------BITOF || BITOF CHEKR || CHECK COMIT || COMMI DEFN || DEFIN DELET || DELET EXCPT || EXCEP LOKUP || LOOKU OCUR || OCCU REDPE || READP RETRN || RETUR SELEC || SELEC SETOF || SETOF UNLCK || UNLOC UPDAT || UPDAT WHxx || WHENx

An Introduction to ILE RPG: Part 3

Figure

7 C-spec Free-Form Expressions

*. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 CL0N01N02N03Factor1+++OpcdeFactor2+++ResultLenDHHiLoEqComments+++++++...... C OEQTY MULT IMPRIC OECOST H Get extended cost * C OEQTY MULT IMWGHT OEWGHT Get Item Weight C ADD PKWGHT OEWGHT Add Package Weight * C OECOST SUB OEDISC XXCOST Get Discounted Cost C XXCOST MULT STTAX OESTAX Get Sales Tax

*. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ... +

... 9 ...+... 0 CL0N01Factor1+++++++Opcode(E)+Extended-factor2++++++++++++++++++++++++++++ +Comme nts++++++++++++ C eval(h) oecost = oeqty * impric Get extended cost

C line item weight C as prev ine

eval

oewght = (oeqty * imwght) + pkwght

Get

eval

oewght = oeqty * imwght + pkwght

Same

C tax on disc cost C Incorrect result

eval

oestax = (oecost - oedisc) * sttax

Get

eval

oestax = oecost - oedisc * sttax

An Introduction to ILE RPG: Part 3

Figure

8 C-spec Continuation

*. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 CL0N01N02N03Factor1+++OpcdeFactor2+++ResultLenDHHiLoEqComments+++++++...... C TMSFT1 MULT EMRATE TMPAY Shift 1 pay * C EMRATE ADD EMPRE2 XRATE Shift2 rate + premium C TMSFT2 MULT XRATE XWAGET Shift2 wages C ADD XWAGET TMPAY Shift1+2 pay * C EMRATE ADD EMPRE3 XRATE Shift3 rate + premium C TMSFT3 MULT XRATE XWAGET Shift3 wages C ADD XWAGET TMPAY Shift1+2+3 pay

*. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 .8 ....+....9 CL0N01Factor1+++++++Opcode(E)+Extended-factor2++++++++++++++++++++++Comments+++ +

C wages C wages * premium C wages * premium

eval

tmpay = tmsft1 * emrate

Shift1

+ (emrate + empre2) * tmsft2

Shift2

including + (emrate + empre3) * tmsft3

Shift3

including

An Introduction to ILE RPG: Part 3

Figure

9 Literals Continuation

*. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ... +

CL0N01Factor1+++++++Opcode(E)+Extended-factor2++++++++++++++++++++++++++++ +Comme C eval des1 = 'Notice the difference between plus + C sign and hyphen continuation for + C literals.' C eval des2 = 'Notice the difference between plus C sign and hyphen continuation for literals.'

An Introduction to ILE RPG: Part 3

Figure

10 C-spec DOW and WHEN

*. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 CL0N01N02N03Factor1+++OpcdeFactor2+++ResultLenDHHiLoEqComments+++++++...... C Y DOWLT50 C IN,X ANDNE*BLANKS C MOVE IN,X OUT,Y C ADD 1 X C ADD 1 Y C ENDDO

+

*. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...

CL0N01Factor1+++++++Opcode(E)+Extended-factor2++++++++++++++++++++++++++++ +Comme C dow y < 50 AND in(x) ' ' CL0N01Factor1+++++++Opcode(E)+Factor2+++++++Result++++++++Len+ +D+HiLoEq....Comme C move in(x) out(x) C add 1 x C add 1 y C enddo

An Introduction to ILE RPG: Part 3

Figure

11 Complex Logical Expressions

*. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 CL0N01N02N03Factor1+++OpcdeFactor2+++ResultLenDHHiLoEqComments+++++++...... C SELEC C TRCODE WHEQ 'A' Add transaction C MOVEL'Add' $ACTN P C TRCODE WHEQ 'C' Change transaction C TRCODE OREQ 'D' Delete transaction C MOVEL'Update' $ACTN P C OTHER Error transaction C MOVEL'Error' $ACTN P

C

ENDSL

*. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+....6 .. 8 ...+... 9 ...+... 0

CL0N01Factor1+++++++Opcde(E)+Extended-factor2+++++++++++++++Comments C select C when trcode = 'A' Add transaction C eval $actn = 'Add' C when trcode = 'C' OR trcode = 'D' Change or delete C eval $actn = 'Update' transaction C other C eval $actn = 'Error' Error transaction C endsl

An Introduction to ILE RPG: Part 3

Figure

12 C-spec IF

*. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 CL0N01N02N03Factor1+++OpcdeFactor2+++ResultLenDHHiLoEqComments+++++++...... C OECOST ADD CMBAL XCHECK Add order cost to AR C XCHECK IFGT CMCRED balance. If credit C MOVE 'N' OEOKAY limited exceeded, C ENDIF reject order

+

*. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...

... 9 ...+... 0 CL0N01Factor1+++++++Opcode(E)+Factor2+++++++Result++++++++Len+ +D+HiLoEq....Comme nts++++++++++++ C if oecost + cmbal > cmcred order cost + bal C eval oeokay = 'N' exceeds credit limit C endif reject order.

An Introduction to ILE RPG: Part 3

Figure

13 Changes to C-specs

RPG/400 || ILE RPG || SEU Format Position || Position || Abbreviation ----------+------------+---------------+-----------------------------------7-8 || 7-8 || L0

||

Explanat

||

Control le

If

9-17 18-27 28-32 33-42 43-48 49-51 52 53 54-55 56-57 58-59 60-74

|| || || || || || || || || || || || || || ||

9-11 12-25 26-35 36-49 50-63 64-68 69-70 26-35 71-72 73-74 75-76 36-79 81-100

|| || || || || || || || || || || || || || ||

N01N02N03 Factor1 Opcde Factor2 Result Len D H Hi Lo Eq Comments

|| || || || || || || || || || || || || || ||

Conditioning indicat (reduced to a single indicat Facto Operation and exten Facto Result fi Field len Decimal positi Operation exten (e.g., half adju High/No record found indica Low/Error indica Equal/End-of-file indica Extended facto Comme

An Introduction to ILE RPG: Part 3

Figure

14 O-spec Program Described Disk File

*. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 OName++++DFBASbSaN01N02N03Excnam........................................... OARTRAN EADD ADDTRN O................N01N02N03Field+YBEnd+PConstant/editword+++++++++.......... O TRCODE 1 O TRCUST 8 O TRDATE 16 O TRAMT 21P *. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ... +

OFilename++DF..N01N02N03Excnam++++B++A+ +Sb+Sa+.............................Comme OARTRAN EADD ADDTRN O..............N01N02N03Field+++++++++YB.End++PConstant/editword/DTformat+ +Comme O TRCODE 1 O TRCUST 8 O TRDATE 16D*MDY/ O TRAMT 21P

An Introduction to ILE RPG: Part 3

Figure

15 O-spec Program Described Printer File

*. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 OName++++DFBASbSaN01N02N03Excnam........................................... OQSYSPRT E 3 PRTTRN OQSYSPRT E 21 PRTTRN O................N01N02N03Field+YBEnd+PConstant/editword+++++++++.......... O TRCODE 1 O TRCUSTZ 10 O TRDATE 20 O TRAMT 3 32 O 57 'This constant continues' O 80 'over a number of lines' O 105 'requiring multiple lines' O 114 'of code.' *. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ... +

OFilename++DF..N01N02N03Excnam++++B++A+ +Sb+Sa+.............................Comme OQSYSPRT E PRTTRN 5 2 O..............N01N02N03Field+++++++++YB.End++PConstant/editword/DTformat+ +Comme O TRCODE 1 O TRCUST Z 10 O TRDATE 20 O TRAMT 3 32 O 113 'This constant continues + O over a number of lines + * Comment lines are permitted * in between continuation lines. O using the new continuaO tion feature.

An Introduction to ILE RPG: Part 3

Figure

16 Changes to O-specs

RPG/400 || ILE RPG || SEU Format Position || Position || Abbreviation ----------+------------+---------------+-----------------------------------7-14 || 7-16 || Name 15 || 17 || D to || || 16 || 18 || F || || 17 || 40-42 || B 18 || 43-45 || A 19-20 || 46-48 || Sb 21-22 || 49-51 || Sa 23-31 || 21-29 || N01N02N03 32-37 || 30-39 || Excnam

||

Explanat

|| ||

Filename or Record format n Type of line (header,detail,

|| || || || || || || || ||

or exce Fetch overflow or release dev after out Space before(0-2 Space after(0-2 Skip bef Skip af Output indicat EXCPT n

32-37 38 39 40-43 44 45-70 75-80

|| || || || || || || ||

30-43 44 45 47-51 52 53-80 81-100

|| || || || || || || ||

Field Y B End P Constant/ editword

|| || || || || ||

Field n Edit c Blank af Ending posit Field for Constant or editw

||

Comme

An Introduction to ILE RPG: Part 4 Last month we saw minor changes to Input specifications (I-specs) and Output specifications (Ospecs) necessary to accommodate 10-character file and field names, longer field lengths, and two positions for the number of decimal digits. We reviewed major changes to Calculation specifications (C-specs) including six-character operation codes and free-form arithmetic and logical expressions. Our programs should be easier to code and maintain with the ability to code complex logic in a single EVAL, DOW or DOU calculation continued over multiple lines as necessary. What now? We continue our coverage of C-specs and Definition specifications (D- specs) with the introduction of built-in functions. Then next month we'll look at the new date, time and timestamp data types and arithmetic operations. Built-in Functions CL has supported built-in functions for some time. These CL functions serve as a reference point that can help you understand ILE RPG built-in functions. In CL, %SST performs a substring function, %BIN provides a binary conversion, and %SWITCH tests job switches. Similar functions are available in ILE RPG. Built-in functions in ILE RPG begin with a percent sign (%) and are followed by one or more arguments enclosed in parentheses. In ILE RPG, multiple arguments are separated by a colon (:), consistent with other keywords we have examined. (Why Rochester's CL is smart enough to use a blank as a delimiter for arguments while Toronto's ILE RPG requires you to key in a colon remains a mystery!)

Built-in functions are supported in D-specs in the keyword entry in positions 44 to 80. Only compile-time values can be used for arguments. Variables that are computed at run time cannot be used in an argument. When used in conjunction with the keywords DIM, OCCURS, OVERLAY and PERRCD, all arguments must be previously defined in the program. C-specs also support built-in functions in the extended factor 2 entry. Free- form expressions may be used as the argument of a built-in function and may include other built-in functions. So what does a built-in function really do? Let's take a look at a comparison of the substring built-in function in CL, RPG/400 and ILE RPG. %SUBST Used to Retrieve a String The substring built-in function in CL can be used to retrieve or modify a portion of a character string contained in a CL character variable or in the local data area. Either %SST or %SUBSTRING can be used in an expression or as the VAR or VALUE parameter of the Change Variable (CHGVAR) command. The character variable name or *LDA, starting position and length must be specified as arguments. In the CL sample in 1, four characters are extracted from the variable &BEG, starting in position 2. The variable &END contains a value of 'BCDE' if the variable &BEG has the value 'ABCDEF'. Because it exceeds the number of characters in the substring, the variable &END is automatically padded with blanks. In the CL sample in Figure 1, four characters are extracted from the variable &BEG, starting in position 2. The variable &END contains a value of 'BCDE' if the variable &BEG has the value 'ABCDEF'. Because it exceeds the number of characters in the substring, the variable &END is automatically padded with blanks. RPG/400 and ILE RPG support the substring operation in C-specs. The character variable from which a value is to be extracted is specified in factor 2. The start position can optionally be specified in factor 2 following the variable. A colon (:) separates these two elements in factor 2. If not specified, the start position defaults to one. The length to be extracted can optionally be specified in factor 1. If not specified, it defaults to the length of the string from the start position. The variable to contain the substring is specified in the result field. In the RPG/400 sample in 1, four characters are extracted from the variable BEG starting in position 2. The variable END contains the value 'BCDE' if the variable BEG has the value 'ABCDEF'. Because the length of the variable END is greater than the substring length, the operation extender P is specified to pad with blanks. ILE RPG supports the SUBST operation code which is identical in function to the RPG/400 version. In the RPG/400 sample in Figure 1, four characters are extracted from the variable BEG starting in position 2. The variable END contains the value 'BCDE' if the variable BEG has the value 'ABCDEF'. Because the length of the variable END is greater than the substring length, the operation extender P is specified to pad with blanks. ILE RPG supports the SUBST operation code which is identical in function to the RPG/400 version. In contrast, the ILE RPG sample in 1 uses the substring built-in function and is a close comparison to the CL sample. %SUBST is used in ILE RPG instead of the %SST or %SUBSTRING used in

CL. A colon (:) is used to separate the variable, start position and length arguments instead of the blank used in CL. In contrast, the ILE RPG sample in Figure 1 uses the substring built-in function and is a close comparison to the CL sample. %SUBST is used in ILE RPG instead of the %SST or %SUBSTRING used in CL. A colon (:) is used to separate the variable, start position and length arguments instead of the blank used in CL. Even though the operation extender P is not specified (and cannot be specified with the EVAL operation code), the variable end still has the value 'BCDE'. When used with character fields, the EVAL operation functions similar to a MOVEL(P). When using the substring built-in function, the pad with blanks is implied with the EVAL operation in ILE RPG as it is with the CHGVAR command in CL. %SUBST Used to Modify a String While the SUBST op code has proved valuable in RPG/400, it is limited because it only permits you to retrieve a substring, not modify one. Although the substring operation has the same restriction in ILE RPG, the EVAL op code allows you to overcome the limitation. The previous examples of %SUBST were used to retrieve a substring. Let's take a look at how to change a substring. A substring can be modified in CL by using the substring built-in function in the VAR parameter of the CHGVAR command. In the CL sample in 2, part of the variable &MOD (starting in position 3 and extending for a length of two characters) is replaced with the value of the variable &CON. Even though the length of the variable &CON is longer than 2, only the first two characters are used. Upon execution of the CHGVAR, the value of the variable &MOD changes to 'VWabZ'. A substring can be modified in CL by using the substring built-in function in the VAR parameter of the CHGVAR command. In the CL sample in Figure 2, part of the variable &MOD (starting in position 3 and extending for a length of two characters) is replaced with the value of the variable &CON. Even though the length of the variable &CON is longer than 2, only the first two characters are used. Upon execution of the CHGVAR, the value of the variable &MOD changes to 'VWabZ'. 2 illustrates a similar capability for ILE RPG. A substring can be changed in ILE RPG using the EVAL operation code with the %SUBST built-in function specified on the left side of the equal sign (=). Identical to the CL sample, the value of the variable mod changes to 'VWabZ'. Figure 2 illustrates a similar capability for ILE RPG. A substring can be changed in ILE RPG using the EVAL operation code with the %SUBST built-in function specified on the left side of the equal sign (=). Identical to the CL sample, the value of the variable mod changes to 'VWabZ'. The second ILE RPG sample in 2 shows the use of the EVAL operation code with the %SUBST built-in function specified on both sides of the equal sign. This permits the value of a substring to be set equal to the value of another substring. The third and fourth characters in the variable mod are replaced with the fourth and fifth characters of the variable con. Upon completion of the execution of the EVAL operation, the variable mod contains a value of 'VWdeZ'. The second ILE RPG sample in Figure 2 shows the use of the EVAL operation code with the %SUBST built-in function specified on both sides of the equal sign. This permits the value of a substring to be set equal to the value of another substring. The third and fourth characters in the

variable mod are replaced with the fourth and fifth characters of the variable con. Upon completion of the execution of the EVAL operation, the variable mod contains a value of 'VWdeZ'. If desired, blanks can be used be-tween the arguments in a built-in function to make the code more readable. Coding %subst(mod:3:2) is the same as coding %subst(mod: 3: 2). Variables can be used for the start position and length as shown in the third ILE sample in 2. The results will be identical to the previous example; i.e., the variable mod will have a value of 'VWdeZ'. Variables can be used for the start position and length as shown in the third ILE sample in Figure 2. The results will be identical to the previous example; i.e., the variable mod will have a value of 'VWdeZ'. Any valid expression is permitted for the start position and length when the %SUBST built-in function is used as a target as shown in the fourth ILE RPG sample. Part of the variable mod (starting in position 2 and extending for a length of three characters) is replaced with the second, third and fourth characters from the variable con. Upon completion of the execution of the EVAL operation, the variable mod has a value of 'VbcdZ'. As we showed last month, an expression can be continued over multiple lines. Continued lines must be blank in positions 7 to 35. No special continuation character is required unless a literal is being continued. Run-time errors can occur when using the %SUBST built-in function if the start position is less than or equal to zero, the length is less than zero, or a combination of the start position and length would cause the substring to exceed the length of the field in the first argument. When used as a target, the first argument of the %SUBST built-in function must refer to a storage location. In other words, it must be a field, data structure subfield, array name, array element or table element. The ability to use the %SUBST built-in function as a target to change a portion of the value of a field is a substantial improvement to ILE RPG. Think of how much code this would take in RPG/400 if the start position and length were variables vs. one line of code in ILE RPG. Once again, nice job IBM! %TRIM Several built-in functions are available in ILE RPG to trim blanks from character variables. %TRIMR trims trailing blanks from the right side of a character variable. %TRIML trims leading blanks from the left side of a character variable. %TRIM trims leading and trailing blanks from a character variable. As illustrated in 3, the argument of the %TRIMR, %TRIML and %TRIM built- in functions can specify a character variable or a valid character expression. The plus sign (+) used in conjunction with character variables means concatenation (combining), not addition. As illustrated in Figure 3, the argument of the %TRIMR, %TRIML and %TRIM built- in functions can specify a character variable or a valid character expression. The plus sign (+) used in conjunction with character variables means concatenation (combining), not addition.

Since the availability of the CAT operation code, concatenating a first name with a last name has been simple. In the RPG/400 sample in 4, the field FIRST is concatenated with the field LAST, with one blank in between. The combined name is placed in the field XNAME and padded with blanks. If the field FIRST contains the value "Charles" and the field LAST contains the value "Massoglia", the field XNAME would contain the value "Charles Massoglia". ILE RPG supports the CAT operation code which is identical in function to the RPG/400 version; it also can accomplish the concatenation with the built-in trim function as shown. Since the availability of the CAT operation code, concatenating a first name with a last name has been simple. In the RPG/400 sample in Figure 4, the field FIRST is concatenated with the field LAST, with one blank in between. The combined name is placed in the field XNAME and padded with blanks. If the field FIRST contains the value "Charles" and the field LAST contains the value "Massoglia", the field XNAME would contain the value "Charles Massoglia". ILE RPG supports the CAT operation code which is identical in function to the RPG/400 version; it also can accomplish the concatenation with the built-in trim function as shown. The first ILE RPG sample in 4 uses the EVAL operation in conjunction with an expression containing a built-in function. The %TRIMR trims the trailing blanks from the right side of the character variable-in this case, the field FIRST. Because the field XNAME is a character variable, the plus sign (+) means concatenation. So the field FIRST with the blanks trimmed from the right is concatenated with a single blank. The result is concatenated with the field LAST. This first ILE RPG EVAL sample yields the same results as the RPG/400 sample. The first ILE RPG sample in Figure 4 uses the EVAL operation in conjunction with an expression containing a built-in function. The %TRIMR trims the trailing blanks from the right side of the character variable-in this case, the field FIRST. Because the field XNAME is a character variable, the plus sign (+) means concatenation. So the field FIRST with the blanks trimmed from the right is concatenated with a single blank. The result is concatenated with the field LAST. This first ILE RPG EVAL sample yields the same results as the RPG/400 sample. Both the CAT operation and the EVAL operation with %TRIMR work well unless there are any leading blanks in the first or last name. If the field FIRST contains the value "Charles" and the field LAST contains the value " Massoglia" with two leading blanks, the field XNAME would contain the value "Charles Massoglia" with three blanks between "Charles" and "Massoglia". The second ILE RPG sample in 4 solves this problem using the %TRIM built-in function which causes the blanks to be trimmed from both sides of the specified variable. It now makes no difference whether or not the fields FIRST and LAST have leading or trailing blanks. The second ILE RPG sample in Figure 4 solves this problem using the %TRIM built-in function which causes the blanks to be trimmed from both sides of the specified variable. It now makes no difference whether or not the fields FIRST and LAST have leading or trailing blanks. The %TRIM built-in function in ILE RPG reduces the amount of code required to combine two or more fields while eliminating leading and trailing blanks. ILE RPG requires a single statement to perform the same function which might have been coded as a complex subroutine or called program in RPG/400. Way to go, IBM! %ELEM with Arrays

When arrays are used in RPG/400, the number of elements and the element length and decimal positions must be individually coded in E-specs. This means if you need to change the number of elements for these arrays, you have to modify multiple E-specs. In addition, if the number of elements is specified as a literal in factor 2 of DO loops in C-specs, these also have to be modified. Even if you use a variable in factor 2, you still have to modify at least one statement. In the RPG/400 sample in 5, the arrays TOT1, TOT2 and TOT3 are all defined with nine elements of seven digits with two decimal positions. If you need to increase the number of elements to 11, you must modify all three E- specs. In addition, you need to modify factor 2 of all three of the DO operations in the C-specs. In the RPG/400 sample in Figure 5, the arrays TOT1, TOT2 and TOT3 are all defined with nine elements of seven digits with two decimal positions. If you need to increase the number of elements to 11, you must modify all three E- specs. In addition, you need to modify factor 2 of all three of the DO operations in the C-specs. The ILE RPG sample in 5 requires changing only a single line of code. The %ELEM built-in function returns the number of elements in an array. Attributes are coded only for the array total1 in the D-specs. The LIKE keyword is used to cause the data type, length and number of decimal positions for the elements in the arrays total2 and total3 to be the same as in the array total1. The %ELEM built-in function is used on the DIM keyword to cause the arrays total2 and total3 to have the same number of dimensions (elements) as the array total1. The ILE RPG sample in Figure 5 requires changing only a single line of code. The %ELEM built-in function returns the number of elements in an array. Attributes are coded only for the array total1 in the D-specs. The LIKE keyword is used to cause the data type, length and number of decimal positions for the elements in the arrays total2 and total3 to be the same as in the array total1. The %ELEM built-in function is used on the DIM keyword to cause the arrays total2 and total3 to have the same number of dimensions (elements) as the array total1. This means if you need to modify the number of elements for these arrays, you only need to change the D-spec defining the array total1. When you recompile your program, the arrays total2 and total3 are automatically defined the same as the array total1. The numeric constant numelem is defined as the value of the number of elements in the array total1 using the %ELEM built-in function in D-specs. Instead of coding a 9 in factor 2 of the DO loops in C-specs, numelem is coded instead. Now if the number of elements in the arrays changes, no changes are required to C-specs. When the program is recompiled, the numeric constant numelem automatically reflects the new value. The way the %ELEM built-in function works with tables is similar to the way it is used with arrays. Whenever identically defined arrays or tables are defined in ILE RPG, they should be defined based upon the main array or table using the %ELEM built-in function. Any time an array is used in a DO loop in C-specs, the number of elements should also be coded in factor 2 using the %ELEM built-in function. Using these techniques can improve program maintainability and reduce debugging time. %ELEM with Multiple Occurrence Data Structures The number of occurrences of a multiple occurrence data structure is coded in I-specs in RPG/400. When the multiple occurrence data structure is used in a DO loop in C-specs, the number of

occurrences is generally coded in factor 2. This means if the number of occurrences changes, you must change multiple lines of code. In the RPG/400 sample in 6, the multiple occurrence data structure GLDS is defined in I-specs with 500 occurrences. The number 500 is also hard-coded in factor 2 of the DO loop in C-specs. Both specifications have to be modified if the number of occurrences is changed. In the RPG/400 sample in Figure 6, the multiple occurrence data structure GLDS is defined in Ispecs with 500 occurrences. The number 500 is also hard-coded in factor 2 of the DO loop in Cspecs. Both specifications have to be modified if the number of occurrences is changed. The ILE RPG sample in 6 requires changing only a single line of code. The %ELEM built-in function returns the number of occurrences in a multiple occurrence data structure. The OCCURS keyword makes the data structure glds a multiple occurrence data structure with 500 occurrences. The ILE RPG sample in Figure 6 requires changing only a single line of code. The %ELEM built-in function returns the number of occurrences in a multiple occurrence data structure. The OCCURS keyword makes the data structure glds a multiple occurrence data structure with 500 occurrences. The numeric constant numocc is defined as the value of the number of occurrences in the multiple occurrence data structure glds using the %ELEM built-in function in D-specs. Instead of coding a 500 in factor 2 of the DO loop in C-specs, numocc is coded instead. Now if the number of occurrences in the multiple occurrence data structure changes, the C-specs require no alteration. When the program is recompiled, the numeric constant numocc automatically reflects the new value. The %ELEM built-in function can be used anywhere a numeric constant is valid within the functions column of the D-specs or the extended factor 2 of the C- specs. %SIZE Built-in Function The %SIZE built-in function returns the number of bytes of storage occupied by a literal, named constant, data structure, data structure subfield, field, array or table name specified as the first argument. When used with a character or hexadecimal literal, %SIZE returns the number of bytes occupied by that literal. For numeric literals, the number of digits including leading and trailing zeroes is returned. If %SIZE is used with a numeric variable stored in packed format, the packed length is returned (e.g., a seven-digit, packed field would return a size of 4 since it take four bytes to store the number in packed format). For binary numbers, the binary length (4 or 2) is returned. When the first argument of the %SIZE built-in function is an array name or table name, the size of a single element is returned. If a multiple occurrence data structure is used, the size of a single occurrence is returned. If *ALL is specified as the second argument, the size of all elements or occurrences is returned. 7 illustrates some examples of values returned when the %SIZE built-in function is used. %SIZE can be used anywhere a numeric constant is valid within the functions column of the D-specs or the extended factor 2 of the C-specs.

Figure 7 illustrates some examples of values returned when the %SIZE built-in function is used. %SIZE can be used anywhere a numeric constant is valid within the functions column of the Dspecs or the extended factor 2 of the C-specs. Pointer Support You may have heard about pointers, particularly if you are a C programmer. While RPG/400 does not support pointers, ILE RPG now provides pointer support. Two other built-in functions work with this data type. %ADDR returns a basing pointer containing the address of the variable specified as the argument. %PADDR returns a procedure pointer containing the return address of the entry point specified as the argument. Pointer support permits ILE RPG to easily use application program interfaces (APIs) but is an advanced topic beyond the scope of this article. For further information on pointers and APIs, please consult the System Programmer's Interface Reference. What's Next? We've seen how built-in functions can substantially reduce program development and maintenance time, in some cases reducing complex routines or called programs in RPG/400 to a single line of code in ILE RPG. In our next article, we will tackle date and time data types including the new date/time arithmetic operation codes. Charlie Massoglia, president of Massoglia Technical Consulting, Inc. in Okemos, Michigan, has authored a number of midrange books. His cowboy hat is his trademark for his frequent speaking tours throughout the United States, Canada, Europe, and Australia. Charlie can be reached at 517676-9700. Reference System Programmer's Interface Reference (SC21-8223, CD-ROM QBKA8402). An Introduction to ILE RPG: Part 4

Figure 1 %SUBST Used to Retrieve a String

*/

DCL DCL CHGVAR

VAR(&BEG) TYPE(*CHAR) LEN(6) VALUE('ABCDEF') VAR(&END) TYPE(*CHAR) LEN(8) VALUE('XXXXXXXX') VAR(&END) VALUE(%SST(&BEG 2 4)) /* &END = 'BCDE

*. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 CL0N01N02N03Factor1+++OpcdeFactor2+++ResultLenDHHiLoEqComments+++++++...... C MOVE 'ABCDEF' BEG 6 C MOVE 'XXXXXXXX'END 8 C 4 SUBSTBEG:2 END P END = 'BCDE ' *. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 0 CL0N01Factor1+++++++Opcode(E)+Factor2+++++++Result++++++++Len+ +D+HiLoEq....Comm

'

ents++++++++++++ C C prev defined C w/blank implied

eval eval

beg = 'ABCDEF' end = 'XXXXXXXX'

end

eval

end = %subst(beg:2:4)

Pad

An Introduction to ILE RPG: Part 4

Figure

2

%SUBST Used to Modify a String

DCL DCL CHGVAR

VAR(&MOD) TYPE(*CHAR) LEN(5) VALUE('VWXYZ') VAR(&CON) TYPE(*CHAR) LEN(5) VALUE('abcde') VAR(%SST(&MOD 3 2)) VALUE(&CON) /* &MOD = 'VWabZ' */

*. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 0 DName+++++++++++ETDsFrom+++To/L++ +IDc.Functions............................Comm ents++++++++++++ D mod S 5 INZ('VWXYZ') D con S 5 INZ('abcde') D start1 S 5 0 INZ(3) D length S 5 0 INZ(2) D start2 S 5 0 INZ(4) CL0N01Factor1+++++++Opcode(E)+Extendedfactor2+++++++++++++++++++++++++++++Comments++++++++++++ C eval %subst(mod:3:2) = con = 'VWabZ' C = 'VWdeZ'

eval

%subst(mod: 3: 2) = %subst(con: 4: 2)

C same as previous C = 'VWdeZ'

eval

%subst(mod: start1: length) = %subst(con: start2: length)

C mod:2:3 con:2:3 C = 'VbcdZ'

eval

3

mod

mod

%subst(mod: start1-1: length+1) = %subst(con: start2/2: length+1)

An Introduction to ILE RPG: Part 4

Figure

mod

%Trim Function Examples

mod

Function

Value

Result

%triml %trimr %trim

' ' '

Charlie Massoglia Charlie Massoglia Charlie Massoglia

%triml %trimr %trim

'same' 'same' 'same'

%triml %trimr %trim

' ab ' + ' cd ' 'ab cd ' ' ab ' + ' cd ' ' ab cd' ' ab ' + ' cd ' 'abcd'

%triml %trimr %trim

' ' '

' ' '

' 'Charlie Massoglia ' ' ' Charlie Massoglia' ' 'Charlie Massoglia'

'same' 'same' 'same'

'' '' ''

An Introduction to ILE RPG: Part 4

Figure

4

%TRIM Function

*. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 CL0N01N02N03Factor1+++OpcdeFactor2+++ResultLenDHHiLoEqComments+++++++...... C FIRST CAT LAST:1 XNAME P Combine first & last *. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 0 CL0N01Factor1+++++++Opcode(E)+Factor2+++++++Result++++++++Len+ +D+HiLoEq....Comm ents++++++++++++ C eval XNAME = %TRIMR(FIRST) + ' ' + LAST Combine first/last C Trim blanks

eval

XNAME = %TRIM(FIRST) + ' ' + %TRIM(LAST)

An Introduction to ILE RPG: Part 4

Figure

5

%ELEM Function with Arrays

*. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 E....FromfileTofile++Name++N/rN/tbLenPDSArrnamLenPDSComments............... E TOT1 9 7 2 E TOT2 9 7 2 E TOT3 9 7 2

CL0N01N02N03Factor1+++OpcdeFactor2+++ResultLenDHHiLoEqComments+++++++...... C *LIKE DEFN TOT1 OUT C DO 9 X 50 C MOVE TOT1,X OUT C EXCPTPRINT1 C ENDDO C DO 9 X 50 C MOVE TOT2,X OUT C EXCPTPRINT1 C ENDDO C DO 9 X 50 C MOVE TOT3,X OUT C EXCPTPRINT1 C ENDDO *. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 0 DName+++++++++++ETDsFrom+++To/L+++IDc.Functions+++++++++++++++++++++++++++ +Comm ents++++++++++++ D total1 S 7 2 dim(9) D total2 S like(total1) dim(%elem(total1)) D total3 S like(total1) dim(%elem(total1)) D out S like(total1) D numelem C const(%elem(total1)) = 9 D x S 5 0 CL0N01Factor1+++++++Opcode(E)+Factor2+++++++Result++++++++Len+ +D+HiLoEq....Comm ents++++++++++++ C do numelem x C move tot1(x) out C except print1 C enddo C do numelem x C move tot2(x) out C except print1 C enddo C do numelem x C move tot3(x) out C except print1 C enddo

An Introduction to ILE RPG: Part 4

Figure 6 Struc

%ELEM Function with Multiple Occurrence Data

*. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 IDsname....NODsExt-file++..............OccrLen+............................ IGLDS DS 500 I............Ext-field+..............PFromTo++DField+...................... I 1 9 GLNUM I 10 182GLAMT

CL0N01N02N03Factor1+++OpcdeFactor2+++ResultLenDHHiLoEqComments+++++++...... C DO 500 X 50 C X OCUR GLDS C EXCPTPRINT C ENDDO *. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 0 DName+++++++++++ETDsFrom+++To/L+++IDc.Functions+++++++++++++++++++++++++++ +Comm ents++++++++++++ D glds DS occurs(500) D glnum 9 D glamt 9 2 D numocc C const(%elem(glds)) = 500 D x S 5 0 CL0N01Factor1+++++++Opcode(E)+Factor2+++++++Result++++++++Len+ +D+HiLoEq....Comm ents++++++++++++ C do numocc x C x occur glds C except print C enddo

An Introduction to ILE RPG: Part 4

Figure

7

%SIZE Function

*. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 0 DName+++++++++++ETDsFrom+++To/L+++IDc.Functions+++++++++++++++++++++++++++ +Comm ents++++++++++++ D packnum S 13P 4 D binnum S 9B 0 D signnum S 15S 0 D charvar S 40A D packarr S 5P 0 DIM(10) D signarr S 5S 0 DIM(10) D chararr S 11 DIM(5) D multoccds DS 8 OCCURS(20) D charcon C 'abcdefgh' D numcon C 500 D size_of_ds C const(%size(multoccds:*all)) = 160

17

CL0N01Factor1+++++++Opcode(E)+Extendedfactor2+++++++++++++++++++++++++++++Comments++++++++++++ C eval num = %size(-005.00) C eval num = %size(005.00) C eval num = %size('Charlie Massoglia')

= 5 = 5 =

C 21

C (packed length) C (binary length) C

15

C

40

C (single element) C

eval

num = %size('

Charlie Massoglia

')

=

eval

num = %size(packnum)

= 7

eval

num = %size(binnum)

= 4

eval

num = %size(signnum)

=

eval

num = %size(charvar)

=

eval

num = %size(packarr)

= 3

eval

num = %size(packarr: *all)

=

eval

num = %size(signarr)

= 5

eval

num = %size(signarr: *all)

=

eval

num = %size(chararr)

=

eval

num = %size(chararr: *all)

=

eval

num = %size(multoccds)

= 8

eval

num = %size(multoccds: *all)

=

eval eval

num = %size(charcon) num = %size(numcon)

= 8 = 3

30

(whole array) C (single element) C

50

(whole array) C 11

(single element) C

55

(whole array) C (single occur) C 160 (all occur) C C

An Introduction to ILE RPG: Part 5 Brief: In our final installment of this introductory ILE RPG series, we examine the support for date data types. ILE RPG can define date, time and timestamp fields corresponding with the DDS support for these data types. It also provides support for date arithmetic, conversion from one date type to another, and conversion to and from numeric and character fields. Last month we saw the introduction of built-in functions, which can substantially reduce program development and maintenance time, in some cases reducing complex routines or called programs in RPG/400 to a single line of code in ILE RPG. In this article, we look at one of the most exciting features of ILE RPG- support for date data types. Date data types have been available on the AS/400 since V2R2; but because they cannot be directly processed in RPG/400, their usefulness has been limited. ILE RPG provides full support for date data types and date arithmetic. This support makes it easy to calculate the difference between two dates or to increment a date by a number of days, taking into account the varying number of days in each month. For example, 1992 is a leap year. If you add 30 days to January 31, 1992, ILE RPG correctly calculates the result as March 1, 1992; if you add 30 days to January 31, 1993, the result is March 2, 1993.

The "Date, Time and Timestamp Data Types" sidebar (page 100) covers the possible formats for date fields in OS/400. Within ILE RPG, you can define fields or constants as date (D), time (T) or timestamp (Z) data types. For the rest of this article, we'll refer to such fields generically as date fields unless an example specifically applies to time or timestamp fields. The length of a date field is determined by the data type and the date format-it should not be coded as part of the definition. The default format for date fields in an ILE RPG program can be specified in the Header specification (H-spec) using the DATFMT and TIMFMT keywords. (For more information on Hspec keywords, see "An Introduction to ILE: Part 1," MC, March 1994.) If these keywords are not used, the default format is International Standards Organization (*ISO) format. Date Field Definitions 1 shows samples of defining date and time fields with initialized values. Since no H-spec exists in the program, date fields that do not include a DATFMT or TIMFMT keyword default to *ISO format; and the *ISO format must be used to initialize all date fields regardless of their format. Figure 1 shows samples of defining date and time fields with initialized values. Since no H-spec exists in the program, date fields that do not include a DATFMT or TIMFMT keyword default to *ISO format; and the *ISO format must be used to initialize all date fields regardless of their format. In the first example in 1, the D in position 40 defines the field eur_date as a date field. Since *EUR is specified for the DATFMT keyword, the date is internally represented in IBM European Standard format (i.e., dd.mm.yyyy) and is automatically defined as 10 characters in length. The INZ parameter initializes the field to 16.12.1994 (December 16, 1994). Even though the field eur_date is defined as a *EUR format date field, the value on the INZ parameter must be in *ISO format (i.e., 1994-12-16). Several other examples of date field definitions are included in 1. In the first example in Figure 1, the D in position 40 defines the field eur_date as a date field. Since *EUR is specified for the DATFMT keyword, the date is internally represented in IBM European Standard format (i.e., dd.mm.yyyy) and is automatically defined as 10 characters in length. The INZ parameter initializes the field to 16.12.1994 (December 16, 1994). Even though the field eur_date is defined as a *EUR format date field, the value on the INZ parameter must be in *ISO format (i.e., 1994-12-16). Several other examples of date field definitions are included in Figure 1. The T in position 40 defines the field hms_time as a time field. Since *HMS is specified for the TIMFMT keyword, the time is internally represented in Hours:Minutes:Seconds format (i.e., hh.mm.ss). The INZ parameter initializes the field to 30 seconds after 6:06 p.m. In a similar manner, the field usa_time is defined as a *USA format time field with an implied length of eight. While the internal format of this field is hh:mm AM or hh:mm PM, the value on the INZ parameter must be in *ISO format (i.e., hh.mm.ss). Literals cannot be specified in a date format different from the default for the program. Therefore, the value for all date and time literals must be represented in the format specified in the H-spec or *ISO format if no format is specified. Date literals should be prefixed by D, T and Z for date, time and timestamp values. Using the *ISO format, D'1994-12-16' defines a date literal with a length of 10 and a value of December 16, 1994. T'18.06.30' defines a time literal with a length of eight and a value of 30 seconds after 6:06 p.m. Z'1994-12-16-18.06.30' defines a timestamp literal with a length of 26 and a value of 30 seconds after 6:06 p.m. on December 16, 1994. (If the microseconds portion of a timestamp literal is not specified, it defaults to '000000' and its length remains 26).

2 shows another sample of defining date and time fields with initialized values. In this sample, a DATFMT of *USA and TIMFMT of *HMS are specified on the H-spec. Figure 2 shows another sample of defining date and time fields with initialized values. In this sample, a DATFMT of *USA and TIMFMT of *HMS are specified on the H-spec. As in the prior sample, the field eur_date is defined as a 10-character, *EUR- format (dd.mm.yyyy) date field. But this time the initialization value must be provided in *USA format (mm/dd/yyyy) because of the DATFMT keyword specified in the H-spec. When the LIKE keyword is used, the DATFMT and TIMFMT keywords are not allowed. The field eur_date2 is defined as a 10-character, *EUR-format (dd.mm.yyyy) date field that takes its format (but not its value) from the field eur_date. The field usa_date is defined as an eight-character, *USA-format date field with a format of *USA&. The ampersand (&) changes the default separator character from a slash (/) to a blank. The value of the field usa_date will be 12 16 1994, while the value of the field usa_date2 will be 12/16/1994. Default Values We've already shown how date fields can be initialized to a specific value using the INZ keyword in the D-specs. You can also initialize a date field using the CLEAR operation code in the C-specs. The default initialization and CLEAR value is not all zeros, as might be expected. For date fields, the default value is January 1, 0001; for time fields, the default value is midnight; and for timestamp fields, the default value is midnight on January 1, 0001. In all cases, the format includes separator characters and is based on the DATFMT and TIMFMT parameters or the default *ISO format. If the DATFMT and TIMFMT keywords are not specified in either the H-spec or the D-spec, the cleared value of a date field is 0001-01-01; the cleared value of a time field is 00.00.00; and the cleared value of a timestamp field is 0001-01-01- 00.00.00.000000. The value set by *LOVAL is the same as the CLEAR value. The value set by *HIVAL is December 31, 9999 for a date field, one second before midnight (23.59.59) for a time field, and one microsecond before midnight on December 31, 9999 for a timestamp field (9999-12-31- 23.59.59.999999). Comparing Date Fields Date data types can be used in factor 1 and factor 2 for many ILE RPG operation codes. As with other types of fields, you can compare date fields only if they have the same data type-date, time or timestamp. ILE RPG will automatically handle different formats-an *ISO-format time field with a value of 15.30.00 will compare equal to a *USA-format time field with a value of 03:30 PM. In the same respect, a *MDY-format date field with a value of 12/16/94 will compare equal to a *YMDformat date field with a value of 94/12/16. Date Arithmetic Arithmetic operations are where the new date data types really shine. Many RPG/400 programs use a complex subroutine that accounts for leap years and the varying number of days in each month to calculate the difference between two dates or to increment a date by a specific number of days. You can get the same results with much less effort using date fields and several new operation codes.

The Add Duration (ADDDUR) operation code can be used to add a duration to a date, time or timestamp field, resulting in a field of the same type. Factor 1 is optional and, if not specified, defaults to the result field. Factor 1 and the result field must be the same data type. Factor 2 is required and contains two parts separated by a colon (:). The first part must be a numeric field, array element or constant with zero decimal positions. The second part is a code indicating the type of duration. The duration code must be valid for the data type of the field specified in the result field. For example, you cannot add a minute duration to a date type field. The valid duration codes are *YEARS or *Y; *MONTHS or *M; *DAYS or *D; *HOURS or *H; *MINUTES or *MN; *SECONDS or *S; and *MSECONDS or *MS. An error indicator can be specified in the less-than columns (73-74). The value of the result field remains unchanged and this indicator is set on if: o The date, time or timestamp field in factor 1 contains invalid data. o Factor 1 is not specified and the date, time or timestamp field in the result field contains invalid data. o The result of the operation is invalid. 3 shows some samples of using the ADDDUR operation code. Since no H-spec is present, all date and time values are specified in *ISO format. Figure 3 shows some samples of using the ADDDUR operation code. Since no H-spec is present, all date and time values are specified in *ISO format. The first C-spec adds 30 days to the field start_date and stores the result in the field end_date. Both start_date and end_date are defined as date fields with an *ISO format and an implied length of 10. Since the field start_date is initialized to 1994-12-16, the field end_date will have a value of 199501-15 after execution of the ADDDUR operation code. If an error occurs, indicator 50 will be turned on. Indicator 50 will be turned off if no error occurs. In the second sample in 3, one month is being added to the *USA format date field month_end. The field month_end is initialized to a value of 10/31/1994 in D-specs. Adding one month to the month portion of this date would result in an invalid date of 11/31/1994; but the result of the ADDDUR operation is automatically adjusted to the last valid day of the month. The field month_end will have the value 11/30/1994 after execution of the ADDDUR operation code. In the second sample in Figure 3, one month is being added to the *USA format date field month_end. The field month_end is initialized to a value of 10/31/1994 in D-specs. Adding one month to the month portion of this date would result in an invalid date of 11/31/1994; but the result of the ADDDUR operation is automatically adjusted to the last valid day of the month. The field month_end will have the value 11/30/1994 after execution of the ADDDUR operation code. In the next example, one year is added to the field employ_dat and the result is stored in the field anniv_dat. The field employ_dat is initialized to a value of 02/29/1992 in D-specs. Adding one year to this date without any adjustment would result in an invalid date of 02/29/1993 since 1993 is not a leap year; but the result of the ADDDUR operation is again automatically adjusted to the last valid day of the month. The field anniv_dat will have the value 02/28/1993 after execution of the ADDDUR operation code.

The next sample demonstrates the use of the ADDDUR operation code with time fields. The first calculation adds three hours to the literal in factor 1, which is set to midnight. The time constant is expressed in *ISO format using a period (.) as a separator character even though the result field end_time is defined in *HMS format using a colon (:) as a separator character. The next two lines of code add 22 minutes and 50 seconds to end_time, giving a result of 03:22:50. The Subtract Duration (SUBDUR) operation code follows the same rules as ADDDUR to subtract durations from date fields. The result field is required and must be the same data type as factor 1 if factor 1 is specified. Several examples are shown in 4. The Subtract Duration (SUBDUR) operation code follows the same rules as ADDDUR to subtract durations from date fields. The result field is required and must be the same data type as factor 1 if factor 1 is specified. Several examples are shown in Figure 4. The SUBDUR operation can also be used to calculate the duration (or difference) between: o Two dates. o A date and a timestamp. o Two times. o A time and a timestamp. o Two timestamps. When calculating a duration, both factor 1 and factor 2 must be specified and must contain the same or compatible data types. A date and a timestamp are compatible as are a time and a timestamp. However, ILE RPG will handle any conversion between date or time formats (i.e., a *USA date subtracted from a *ISO date). The result field is also required and contains two parts. The first must be a numeric field, array element or constant with zero decimal positions in which the result will be placed. The second is separated from the first by a colon (:) and must be a valid duration code indicating the type of duration. The result will be negative if the date or time in factor 1 is earlier than the date or time in factor 2. 4 shows some samples of using the SUBDUR operation code. Since DATFMT(*USA) is specified on the H-spec, all date literals must be provided in *USA format. Because TIMFMT(*HMS) is also specified, all time literals must be provided in *HMS format. Figure 4 shows some samples of using the SUBDUR operation code. Since DATFMT(*USA) is specified on the H-spec, all date literals must be provided in *USA format. Because TIMFMT(*HMS) is also specified, all time literals must be provided in *HMS format. The first three examples are very similar to the examples for ADDDUR in the previous section. A duration is subtracted from a date, resulting in a new date; if necessary, ILE RPG automatically adjusts the result to a valid date, taking into account leap year and the number of days in each month. The fourth sample demonstrates the use of the SUBDUR operation code with timestamp fields to determine the difference between two timestamp values. The field start_time is defined as a timestamp field with a value of 1994-05-12- 02.59.40, and the field end_time is defined as a timestamp field with a value of 1994-05-12-03.22.50. Micro-seconds default to all zeros. Since the duration code *SECS is specified on the result field, the field num_sec will have a value of 1,390 seconds after execution of the SUBDUR operation code. In the last sample, the date field loan_date, which has a value of 12/16/1993, is subtracted from the date field due_date, which has a value of 12/16/2008. Since the duration code *M (months) is specified on the result field, the field num_mon will have a value of 180 months.

EXTRCT Operation Code The Extract (EXTRCT) operation code can be used to extract a portion of a date field. Factor 1 must be blank. Factor 2 is required and contains two parts separated by a colon (:). The first part must be a date, time or timestamp field. The second part must be a duration code that is valid for the data type of the field specified in the first part of factor 2. For example, you can extract hours from a time or timestamp field but not from a date field. The result field may be a numeric or character field. Before the EXTRCT operation is executed, the result field is cleared. Numeric result fields are right-justified while character result fields are leftjustified. The first three samples in 5 extract information from the field due_date which is defined as an *ISO format date field and initialized to 2008-12-16. The month is extracted into the character field char_month with a result of '12'. The day is extracted into the character field char_day with a result of '16'. The year is extracted into the numeric field num_year with a result of 1994. The first three samples in Figure 5 extract information from the field due_date which is defined as an *ISO format date field and initialized to 2008-12-16. The month is extracted into the character field char_month with a result of '12'. The day is extracted into the character field char_day with a result of '16'. The year is extracted into the numeric field num_year with a result of 1994. The second group of examples uses the field start_time, which is defined as a timestamp field and initialized to a value of 1994-10-22-02.59.40. The month is extracted into the character field char_month with a result of '10', and the hour is extracted into the numeric field num_hour with a result of 2. Converting Date Formats The MOVE and MOVEL operation codes can be used to convert date, time and timestamp fields from one data type or format to another. The valid conversions are: o Date to date, timestamp, character or numeric. o Time to time, timestamp, character or numeric. o Timestamp to date, time, character or numeric. o Character or numeric to date, time or timestamp. You can use the Move Array (MOVEA) operation code only to move date data type fields to a charactertype field, array or array element. As with any move operation, when you use one of the MOVE operation codes to convert from one data type to another, the value in factor 2 will be moved to the result field. Factor 1 is optional and is used to specify the format of factor 2, when factor 2 is not a date data type. Alternatively, factor 1 can be used to specify the format of the result field when the result field is not a date data type. All of the date formats are valid and, in addition, *JOBRUN can be used to indicate that the date format values from the job should be used. If factor 1 is not specified, then the DATFMT and TIMFMT values in the H-spec are used if specified; otherwise, *ISO format is assumed. Factor 1 must be blank if both factor 2 and the result field are date data types. In this case, ILE RPG will automatically convert from one date format to another. When a MOVE operation code is used to convert a character field to a date type field, the character field must include the separators required by the format specified in factor 1. Conversely, when a

date field is moved to a character field, the character field will contain separators based upon the format specified in factor 1. Separators are not permitted when moving a numeric field to a date field, nor are they inserted when moving a date field to a numeric field. 6 shows some samples of converting dates using the MOVE operation code. In the first sample, the field start_num is defined as a zoned decimal field in which we are storing a date in YYMMDD format (941216). We want to add 30 days to the value in start_num. In RPG/400, this requires a subroutine that accounts for leap years and the number of days in each month; but, as 6 illustrates, it is a simple process in ILE RPG. Figure 6 shows some samples of converting dates using the MOVE operation code. In the first sample, the field start_num is defined as a zoned decimal field in which we are storing a date in YYMMDD format (941216). We want to add 30 days to the value in start_num. In RPG/400, this requires a subroutine that accounts for leap years and the number of days in each month; but, as Figure 6 illustrates, it is a simple process in ILE RPG. First, we use the MOVE operation code to convert the zoned decimal field start_num to the *ISO date start_date. Factor 1 indicates the field start_num is in *YMD format (e.g., YYMMDD). Then all we have to do is use the ADDDUR operation code to add 30 days to start_date and MOVE the *ISO date field start_date back to the zoned decimal field start_num. Again, factor 1 indicates the field start_num is to be formatted in *YMD format. The field start_num will have the value 950115. In the next sample, the move operation code is used to convert a date from *USA to *EUR format. The field usa_date is defined as a *USA-format field with a value of 04/16/1916. The field eur_date is defined as a *EUR-format field. Moving the field usa_date to the field eur_date will result in eur_date having the value 16.04.1916. The final sample demonstrates a potentially serious problem for those who store their dates in MMDDYY, DDMMYY or YYMMDD format. Dates in these formats must be in the range of 1940 to 2039. Attempting to move a value outside of this range to this format date will result in a runtime error. Since the *USA-format date usa_date has a value of 04/16/1916, which is before 1940, attempting to move this date to the *YMD-format date ymd_date will cause a run-time error. Many people store their dates in packed decimal fields in CYYMMDD format where C represents the century (e.g., 0941216 represents 12/16/1994 and 1941216 represents 12/16/2094). *CYMD is not currently supported as a convert-from or convert-to date format. This is one of the most serious deficiencies in the ILE RPG language definition. Hopefully, IBM Toronto will recognize the major problems this will cause. Hopefully, this support will be added to ILE RPG before general availability of V3R1M0 or, worst case, be made available in the next release (or version?). Summary In this series of articles, we've only had time to take a look at some of the enhancements IBM has made to RPG in V3R1M0. For example, we haven't covered bound program calls; CLEAR and RESET operation code enhancements; date, time and timestamp built-in functions; and much more. Yet, we have seen that ILE RPG has introduced many radical changes to the RPG language definition:

o Numerous modifications were required to handle the change from 6- to 10- character symbolic names. o Keyword notation has not only freed up space to accommodate longer fields in F-specs, it has also made the coding of H-specs and F-specs much easier for us and much easier for IBM to enhance in the future. o E-specs have been eliminated with array and table definition moved to D- specs. Named constant and data structure definition has been moved from I-specs to D-specs. o The new D-specs permit us to consolidate our data definitions in a single place in our programs. Substantial productivity gains should result from the introduction of the OVERLAY and PREFIX keywords and the ability to use length notation in data structures. o Major changes to C-specs include six-character operation codes and free-form arithmetic and logical expressions. Our programs should be easier to code and maintain with the ability to code complex logic in a single EVAL, IF, WHEN, DOW or DOU calculation continued over multiple lines as necessary. o Built-in functions can substantially reduce program development and maintenance time, in some cases reducing complex routines or called programs in RPG/400 to a single line of code in ILE RPG. o The introduction of date, time and timestamp data types will finally let us easily address the year 2000. The ADDDUR and SUBDUR operation codes will enable us to replace entire subroutines or subprograms with a single line of code. ILE RPG is not the same old RPG. It offers the hope of making RPG a viable language into the twenty-first century. Charlie Massoglia, president of Massoglia Technical Consulting, Inc. in Okemos, Michigan, has authored a number of midrange books. His cowboy hat is his trademark for his frequent speaking tours throughout the United States, Canada, Europe and Australia. Charlie can be reached at 517676-9700. Date, Time and Timestamp Data Types DDS has supported date, time and timestamp data types for some time. Because these data types are not directly supported in RPG/400, they have been of little practical value for RPG programmers. ILE RPG is about to change that. A1 shows the eight date formats currently supported for date fields. The date format controls the order and length of the month, day and year. In addition, the date format specifies the default separator character of slash (/), hyphen (-) or period (.). The year can be represented in two-byte (yy) and four-byte (yyyy) character format. The day of month (dd) is represented in two- byte format, while Julian day (ddd) is represented in three-byte format. The month (mm) is always represented in two-byte format. Figure A1 shows the eight date formats currently supported for date fields. The date format controls the order and length of the month, day and year. In addition, the date format specifies the default separator character of slash (/), hyphen (-) or period (.). The year can be represented in two-byte (yy) and four-byte (yyyy) character format. The day of month (dd) is represented in two- byte

format, while Julian day (ddd) is represented in three-byte format. The month (mm) is always represented in two-byte format. The external length is the number of bytes of storage required to store the date field on disk without the separator characters. All date fields, regardless of date format, require four bytes of storage. The internal length is the number of bytes of storage required to represent the date in a program, on a screen or in a report including the separator characters. Date fields require between six and ten characters of storage for internal representation, depending upon the date format specified. Leading zeros are required for all date formats except *USA. ILE RPG supports five time formats, as shown in A2. The time format designates whether 12- or 24-hour format is used and whether seconds are shown. In addition, the time format specifies the default separator character of colon (:) or period (.). Hours (hh) and minutes (mm) are represented in two-byte format. Either the seconds (ss) are represented in two-byte format for 24-hour time, or AM or PM is represented in two-byte format for 12-hour time. ILE RPG supports five time formats, as shown in Figure A2. The time format designates whether 12- or 24-hour format is used and whether seconds are shown. In addition, the time format specifies the default separator character of colon (:) or period (.). Hours (hh) and minutes (mm) are represented in two-byte format. Either the seconds (ss) are represented in two-byte format for 24hour time, or AM or PM is represented in two-byte format for 12-hour time. The external length of a time field is always three bytes. Time fields always require eight bytes for internal representation regardless of the time format specified. Leading zeros are required for all time formats except *USA. Fields with a timestamp data type always have the same format as shown in A3. Year (yyyy) is always four bytes, followed by month (mm), day (dd), hours (hh), minutes (mm) and seconds (ss) which are always two bytes. Microseconds (uuuuuu) is last with six bytes. The separator characters are always a combination of hyphens (-) for the date and periods (.) for the time. Fields with a timestamp data type always have the same format as shown in Figure A3. Year (yyyy) is always four bytes, followed by month (mm), day (dd), hours (hh), minutes (mm) and seconds (ss) which are always two bytes. Microseconds (uuuuuu) is last with six bytes. The separator characters are always a combination of hyphens (-) for the date and periods (.) for the time. The external length of a time-stamp field is always 10 bytes. Timestamp fields always require 26 bytes for internal representation. If microseconds is not specified when a timestamp value is used in ILE RPG, the compiler pads the value with zeros. An Introduction to ILE RPG: Part 5

Figure 1 Defining Date and Time Fields with Initialized Val Format *.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 10

HFunctions++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Comm ents++++++++++++ H DName+++++++++++ETDsFrom+++To/L++ +IDc.Functions............................Comm ents++++++++++++ D eur_date S D DATFMT(*EUR) INZ(D'1994-12-16') 16.12.1994 D usa_date S D DATFMT(*USA) INZ(D'1994-12-16') 12/16/1994 D iso_date S D INZ(D'1994-12-16') 1994-12-16 D hms_time 18:06:30 D usa_time 6:06 PM D iso_time 18.06.30

S

T

TIMFMT(*HMS) INZ(T'18.06.30')

S

T

TIMFMT(*USA) INZ(T'18.06.30')

S

T

INZ(T'18.06.30')

An Introduction to ILE RPG: Part 5

Figure Val

2

Defining Date and Time Fields with Initialized

*HMS Format *.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 10 HFunctions++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Comm ents++++++++++++ H DATFMT(*USA) TIMFMT(*HMS) DName+++++++++++ETDsFrom+++To/L++ +IDc.Functions............................Comm ents++++++++++++ D eur_date S D DATFMT(*EUR) INZ(D'12/16/1994') 16.12.1994 D eur_date2 S LIKE(eur_date) INZ(D'05/18/1995') 18.05.1995 D usa_date S D DATFMT(*USA&) INZ(D'12/16/1994') 16 1994 D usa_date2 S D INZ(D'12/16/1994') 12/16/1994 D iso_date S D DATFMT(*ISO) INZ(D'12/16/1994') 1994-12-16 D usa_time 6:06 PM D hms_time 18:06:30 D iso_time

S

T

TIMFMT(*USA) INZ(T'18:06:30')

S

T

INZ(T'18:06:30')

S

T

TIMFMT(*ISO) INZ(T'18:06:30')

12

18.06.30

An Introduction to ILE RPG: Part 5

Figure

3

ADDDUR-Add Duration Operation Code

*.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 10 DName+++++++++++ETDsFrom+++To/L++ +IDc.Functions............................Comm ents++++++++++++ D start_date S D DATFMT(*ISO) INZ(D'1994-12-16') D end_date S D DATFMT(*ISO) D month_end S D DATFMT(*USA) INZ(D'1994-10-31') D employ_dat S D DATFMT(*USA) INZ(D'1992-02-29') D anniv_dat S D DATFMT(*USA) D end_time S T TIMFMT(*HMS) D total_time S Z CL0N01Factor1+++++++Opcode(E)+Factor2+++++++Result++++++++Len+ +D+HiLoEq....Comm ents+++++++++++++ * * Add 30 days to date * C start_date adddur 30:*days end_date * * Add 1 month to date * C adddur 1:*months month_end * * Add 1 year to date * C employ_dat adddur 1:*years anniv_dat * * Add 3 hours, 22 minutes and 50 seconds to midnight * C T'00.00.00' adddur 3:*hours end_time C adddur 22:*min end_time C adddur 50:*seconds end_time * * Add 1000 microseconds to a timestamp * C adddur 1000:*ms total_time

50

An Introduction to ILE RPG: Part 5

Figure

4

SUBDUR-Subtract Duration Operation Code

*.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8

...+... 9 ...+... 10 HFunctions++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Comm ents++++++++++++ H DATFMT(*USA) TIMFMT(*HMS) DName+++++++++++ETDsFrom+++To/L++ +IDc.Functions............................Comm ents++++++++++++ D start_date S D DATFMT(*ISO) D end_date S D DATFMT(*ISO) INZ(D'01/04/1995') D month_end S D DATFMT(*USA) INZ(D'10/31/1994') D employ_dat S D DATFMT(*USA) D anniv_dat S D DATFMT(*USA) INZ(D'02/29/1992') D start_time S Z INZ(Z'1994-05-12-02.59.40') D end_time S Z INZ(Z'1994-05-12-03.22.50') D loan_date S D INZ(D'12/16/1993') D due_date S D INZ(D'12/16/2008') CL0N01Factor1+++++++Opcode(E)+Factor2+++++++Result++++++++Len+ +D+HiLoEq....Comm ents+++++++++++++ * * Subtract 30 days from date * C end_date subdur 30:*days start_date * * Subtract 1 month from date * C subdur 1:*months month_end * * Subtract 1 year from date * C anniv_date subdur 1:*years employ_dat * * Calculate number of seconds between start and stop timestamps * C end_time subdur start_time num_sec:*secs 7 0 * * Calculate number of days between dates * CL0N01Factor1+++++++Opcode(E)+Factor2+++++++Result++++++++Len+ +D+HiLoEq....Comm ents+++++++++++++ C due_date subdur loan_date num_mon:*m 3 0

50

An Introduction to ILE RPG: Part 5

Figure

5

EXTRCT-Extract Operation Code

*.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 10 DName+++++++++++ETDsFrom+++To/L++ +IDc.Functions............................Comm ents++++++++++++ D due_date S D INZ(D'2008-12-16')

D start_time

S

Z

INZ(Z'1994-10-22-02.59.40')

CL0N01Factor1+++++++Opcode(E)+Factor2+++++++Result++++++++Len+ +D+HiLoEq....Comm ents+++++++++++++ * * Extract month, day and year * C extrct due_date:*m char_month 2 C extrct due_date:*d char_day 2 C extrct due_date:*y num_year 4 0 * * Extract month and hours * C extrct start_time:*m char_month C extrct start_time:*h num_hour 2 0

An Introduction to ILE RPG: Part 5

Figure

6

MOVE with Dates, Times and Timestamps

*.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 10 * No H-spec so dates and times default to *ISO format. DName+++++++++++ETDsFrom+++To/L++ +IDc.Functions............................Comm ents++++++++++++ D start_num S 6S 0 INZ(941216) D start_date S D DATFMT(*ISO) D usa_date S D DATFMT(*USA) INZ(D'1916-04-16') 04/16/1916 D eur_date S D DATFMT(*EUR) D ymd_date S D DATFMT(*YMD) CL0N01Factor1+++++++Opcode(E)+Factor2+++++++Result++++++++Len+ +D+HiLoEq....Comm ents+++++++++++++ * * Add 30 days to date stored as a number in YYMMDD format * C *YMD move start_num start_date start_date=1994-12-16 C adddur 30:*days start_date start_date=1995-01-15 C *YMD move start_date start_num start_num=950115 * * Convert a date from *USA to *EUR format * C move usa_date eur_date eur_date=16.04.1916 * * Cannot convert a date before 1940 or after 2039 to *YMD format * C move usa_date ymd_date

run

time error

An Introduction to ILE RPG: Part 5

Figure

A1

Date Format Parameter *MDY *DMY *YMD *JUL *ISO *USA *EUR *JIS

Date Formats and Default Separators

Date Format Description

Internal and Separator

Month/Day/Year mm/dd/yy 8 Day/Month/Year dd/mm/yy 8 Year/Month/Day yy/mm/dd 8 Julian yy/ddd 6 4 94/350 International Standards yyyy-mm-dd Organization IBM USA Standard mm/dd/yyyy IBM European Standard dd.mm.yyyy Japanese Industrial yyyy-mm-dd Standard Christian Era

External Length Length

Example

4 4 4

12/16/94 16/12/94 94/12/16

10

4

1994-12-16

10 10 10

4 4 4

12/16/1994 16.12.1994 1994-12-16

An Introduction to ILE RPG: Part 5

Figure

A2

Time Format Parameter *HMS *ISO *USA *EUR *JIS

Time Formats and Default Separators

Time Format Description

Internal and Separator

Hours:Minutes:Seconds hh:mm:ss International Standards hh.mm.ss Organization IBM USA Standard hh:mm AM or hh:mm PM IBM European Standard hh.mm.ss Japanese Industrial hh:mm:ss Standard Christian Era

External Length Length

Example

8 8

3 3

18:06:30 18.06.30

8

3

6:06 PM

8 8

3 3

18.06.30 18:06:30

An Introduction to ILE RPG: Part 5

Figure

Format

A3

Timestamp Format and Separator Characters

Internal Length Length

External Example

yyyy-mm-dd-hh.mm.ss.uuuuuu

26

10

1994-12-16.18.06.30.000001

View more...

Comments

Copyright ©2017 KUPDF Inc.
SUPPORT KUPDF