02
Sat, Nov
2 New Articles

Good News for RPG/400

RPG
Typography
  • Smaller Small Medium Big Bigger
  • Default Helvetica Segoe Georgia Times

Learn about the new ammunition available in Release 3.0

by Ernie Malaga

Upgrading your AS/400 to a new release is a time-consuming chore that you may be tempted to put off for a rainy day when you have nothing better to do. After all, spending six to eight hours waiting for messages on your AS/400 console on Sunday (or whenever) is not quite anyone's idea of fun.

But perhaps you will change your mind when you read about the new features available in RPG/400 in Release 3.0. They were long overdue, and they finally made it to your compiler.

The Initialization Subroutine

RPG/400 programs can now use a subroutine named *INZSR. This subroutine is executed automatically upon initialization of the program, right after all fields, arrays, tables, indicators, and structures are set to their initial values, but before 1P output is sent to a printer file.

What's more, the *INZSR subroutine can be called again with an EXSR operation, anytime; the *INZSR can be coded just like any other subroutine, so it can contain any operations normally available to "regular" subroutines, with the exception of the new RESET operation.

Let me give you a couple of nice applications for this subroutine. First, the system time is obtained by way of the TIME operation and, as such, cannot be calculated except after the program performs 1P output to the printer file. Since the *INZSR is executed automatically before 1P time, you can code an initialization subroutine as shown in 1. Now your O-specs can include the SYSTIM and SYSDAT fields, which will already have the system time and date, even during 1P output.

Let me give you a couple of nice applications for this subroutine. First, the system time is obtained by way of the TIME operation and, as such, cannot be calculated except after the program performs 1P output to the printer file. Since the *INZSR is executed automatically before 1P time, you can code an initialization subroutine as shown in Figure 1. Now your O-specs can include the SYSTIM and SYSDAT fields, which will already have the system time and date, even during 1P output.

Second, this is the perfect place to code all of those operations that you have to do for the first cycle only; just remember not to run an EXSR *INZSR or it will be executed all over again. For example, perhaps you store your report headings and titles in message descriptions. You could then use the *INZSR to retrieve the text from the message descriptions as shown in 2.

Second, this is the perfect place to code all of those operations that you have to do for the first cycle only; just remember not to run an EXSR *INZSR or it will be executed all over again. For example, perhaps you store your report headings and titles in message descriptions. You could then use the *INZSR to retrieve the text from the message descriptions as shown in Figure 2.

Initializing Data Structures

A data structure is a useful tool to represent a data aggregate, and a multiple-occurrence data structure is an array in which each element is a data structure. RPG/400 support for data structures, until now, lacked an easy way to initialize a data structure. When a program containing a data structure is started, the alphanumeric subfields of the data structure are initialized to blanks automatically, and so are the numeric fields. This causes decimal data errors if the numeric subfields are used before being manually initialized to zero or to some other valid numeric value.

With Release 3.0, you can code a data structure (whether internally or externally described) to instruct the system to initialize the structure subfields properly, according to their type: alphanumeric fields will be initialized to blanks, but numeric fields will be initialized to zeros.

There are two methods for initializing a data structure: globally (the entire data structure), and by individual subfields. Examples are provided in Figures 3a and 3b.

Data structure SMPLDS is initialized globally; notice the "I" coded in column 18 of the I-spec. When the program starts, fields ALPHA1 and ALPHA2 will be set to blanks, but fields NUM1 and NUM2 will be set to zero, since they are numeric. You can then use these fields with confidence, knowing that they have been properly initialized and will not cause decimal data errors.

In this case, data structure SMPLDS is not initialized globally, but on a subfield basis. When the program starts, ALPHA1 is initialized to blanks because it is alphanumeric; NUM1 is initialized to -70 (notice the "I" coded in column 8 and the numeric literal, -70, coded in column 21). Field NUM2 is initialized to blanks, even though it is numeric, so it could cause decimal data errors; field ALPHA2 is initialized to the value 'AZ'.

The CLEAR Operation

The new operation code CLEAR is used to initialize any type of variable to its proper initial value. The variable can be a field, array, array element, table, indicator, or data structure. If it is alphanumeric it will be initialized to blanks; if it is numeric, to zeros. The table in 4 summarizes the uses of the CLEAR operation.

The new operation code CLEAR is used to initialize any type of variable to its proper initial value. The variable can be a field, array, array element, table, indicator, or data structure. If it is alphanumeric it will be initialized to blanks; if it is numeric, to zeros. The table in Figure 4 summarizes the uses of the CLEAR operation.

But there is more. CLEAR can also be used on record names, thus providing an easy and convenient way to make sure that the record you are about to write is properly initialized. Before Release 3.0, you had to MOVE *BLANK or Z-ADD *ZERO on each field of the record format before you issued a WRITE operation; now you can simply CLEAR the record by name and then WRITE it. Simple? You bet.

When CLEAR is used on record names, only those fields defined as output or both are cleared; input-only fields are not affected. If you code *NOKEY in Factor 1 of the CLEAR operation, the key fields of an indexed disk file will not be cleared.

The RESET Operation

RESET is another new operation. It sets a variable back to the value it had when the initialization of the program was complete. Since this program initialization includes the *INZSR subroutine (described earlier), you can use the RESET operation to return certain variables to their "initial" values. For instance, you may have coded your *INZSR as in 5.

RESET is another new operation. It sets a variable back to the value it had when the initialization of the program was complete. Since this program initialization includes the *INZSR subroutine (described earlier), you can use the RESET operation to return certain variables to their "initial" values. For instance, you may have coded your *INZSR as in Figure 5.

This *INZSR will set field RCDTYP (record type) to the value 'CM' at program initialization. Because this is taken as the initial value of this field, issuing a RESET RCDTYP will move 'CM' to that field, automatically. You can use this operation to refresh the values of certain fields. If you use RESET on a data structure subfield that has been initialized to a specific value, that specific value will be moved to the data structure subfield automatically.

Just like CLEAR, RESET can be used on all types of variables: fields, data structures, arrays, and indicators. It can also be used on record format names and shares with CLEAR the limitations and syntax, including the *NOKEY reserved word in Factor 1.

String Operations

At long last, RPG programmers have access to string operations. Before Release 3.0, RPG programmers typically spent a great deal of time coding arrays whenever character strings had to be manipulated. With Release 3.0, these tedious coding techniques are no longer needed. RPG/400 now provides three string operations: CAT, SCAN, and SUBST.

CAT is used to concatenate two strings together. It works like the *CAT, *BCAT, and *TCAT operations in CL. You code the first string in Factor 1, the second string in Factor 2, and the resulting string in the Result Field. Optionally, Factor 2 can indicate the number of intervening blanks between the two strings to be joined.

For example, imagine that field FIRST contains your first name and field LAST contains your last name. You need to print your entire name in a "natural" way (with only one blank between names). RPG/400 can now handle this problem easily, as shown in 6.

For example, imagine that field FIRST contains your first name and field LAST contains your last name. You need to print your entire name in a "natural" way (with only one blank between names). RPG/400 can now handle this problem easily, as shown in Figure 6.

Field NAME will have both names with one blank between them, as indicated by the ":1" notation in Factor 2. This number of blanks defaults to zero if not indicated, and can be indicated by a variable too, as in LAST:N.

SCAN is a very powerful operation. Before Release 3.0 you had to CALL program QCLSCAN whenever you needed to scan a character string. This external program call is no longer necessary, resulting in a much improved performance.

For example, suppose you have a series of records (like a customer master file) and you want to find the record that has "SMITH" in the CUNAME field, as in 7. In this program segment, all records in CUSTMAST are read. The SCAN operation tries to find string 'SMITH' (which could have been stored in a field, of course) in field CUNAME. POSITN is the position in which 'SMITH' is found in CUNAME; if not found, a zero is returned. So, if POSITN is greater than zero, it is because 'SMITH' was found.

For example, suppose you have a series of records (like a customer master file) and you want to find the record that has "SMITH" in the CUNAME field, as in Figure 7. In this program segment, all records in CUSTMAST are read. The SCAN operation tries to find string 'SMITH' (which could have been stored in a field, of course) in field CUNAME. POSITN is the position in which 'SMITH' is found in CUNAME; if not found, a zero is returned. So, if POSITN is greater than zero, it is because 'SMITH' was found.

The Result Field is optional. If it is omitted, you must code an indicator in columns 58-59, which would turn on if the SCAN could not find the string.

Both Factor 1 and Factor 2 can have ":n" options. In Factor 1, ":n" indicates the length of the portion of Factor 1 to be used for scanning. In Factor 2, ":n" indicates the starting position of the scan. An example is shown in 8. This code will scan the first four characters of FIRST (the first name) in field NAME, beginning with the second character of NAME. Again, variable names could have been used instead of 4 and 2, such as FIRST:M and NAME:N.

Both Factor 1 and Factor 2 can have ":n" options. In Factor 1, ":n" indicates the length of the portion of Factor 1 to be used for scanning. In Factor 2, ":n" indicates the starting position of the scan. An example is shown in Figure 8. This code will scan the first four characters of FIRST (the first name) in field NAME, beginning with the second character of NAME. Again, variable names could have been used instead of 4 and 2, such as FIRST:M and NAME:N.

Because you can code a SCAN operation in such a way that the scanning process would go beyond the end of the character string in Factor 2, coding an indicator in columns 56-57 is advisable. This indicator will turn on if there is an error during the execution of SCAN.

SCAN has another feature. If you code a numeric array name in the result field, SCAN will assign the position of each occurrence in each element of the array. Examine the example in 9. If field NAME were to contain 'TALBOTT ATTORNEYS', the SCAN operation would change the array as seen in the same figure.

SCAN has another feature. If you code a numeric array name in the result field, SCAN will assign the position of each occurrence in each element of the array. Examine the example in Figure 9. If field NAME were to contain 'TALBOTT ATTORNEYS', the SCAN operation would change the array as seen in the same figure.

If the array has more elements than occurrences found, the first few elements are loaded with the position numbers, while the rest are cleared to zero. If the array has fewer elements than occurrences found, the array will contain the first few occurrences, ignoring those that exceed the size of the array - and there will be no warning. For example, if array ARR had only three elements, the fourth and fifth occurrence of 'T' would not be recorded and you would not even know they exist.

The SUBST operation extracts a substring from a longer string; it works like the %SST function in CL. You code the length of the desired substring in Factor 1, the base string in Factor 2, and the name of the resulting substring as the Result Field. Optionally, Factor 2 can include a ":n" notation to indicate the position where it should begin extracting the substring.

For example, to extract four characters from field LONG, beginning on the third character, and placing the result in field SHORT, as in 10.

For example, to extract four characters from field LONG, beginning on the third character, and placing the result in field SHORT, as in Figure 10.

If the ":n" notation is removed from Factor 2, the starting position is assumed to be 1 by default. As with the SCAN operation, an indicator in columns 56-57 will turn on if the SUBST operation results in an error such as attempting to go past the end of the base string. For instance, if string LONG in 10 were only five characters long, SUBST would generate an error, since it would not be able to extract four characters beginning with the third character.

If the ":n" notation is removed from Factor 2, the starting position is assumed to be 1 by default. As with the SCAN operation, an indicator in columns 56-57 will turn on if the SUBST operation results in an error such as attempting to go past the end of the base string. For instance, if string LONG in Figure 10 were only five characters long, SUBST would generate an error, since it would not be able to extract four characters beginning with the third character.

Is That All?

There is one more improvement left to talk about, involving the READE and REDPE operations. As you may already know, these operations have been extremely useful tools to read a database file forwards or backwards, looking for records that have the same key. But they did require you to code the key value (literal or field name) as Factor 1. With Release 3.0, this is no longer necessary; if you omit an entry in Factor 1, READE and REDPE will find the next or previous record having the same key as the last record read. It's that simple.

The Future

Beyond the points we have explored in this article, there are expectations and rumors aplenty. Sometime around 1992 or 1993, IBM is planning to revamp the C-specs in order to expand the Result Field to ten characters and add one more column to Decimal Positions, allowing you to define fields with ten or more decimal positions; the actual limit of nine is not ample enough.

There is also talk of allowing arithmetic expressions and a form of indention. However, it seems -- as far as IBM is concerned -- that RPG will remain basically columnar in nature.


Good News for RPG/400

Figure 1 Initialization subroutine

 Figure 1: Initialization Subroutine ....1.... ....2.... ....3.... ....4.... ....5.... ....6.... ....7 C *INZSR BEGSR C TIME SYS 120 C MOVELSYS SYSTIM 60 C MOVE SYS SYSDAT 60 C ENDSR ....1.... ....2.... ....3.... ....4.... ....5.... ....6.... ....7 
Good News for RPG/400

Figure 10 The Substring operation

 Figure 10: The Substring Operation ....1.... ....2.... ....3.... ....4.... ....5.... ....6.... ....7 C 4 SUBSTLONG:3 SHORT 
Good News for RPG/400

Figure 2 Message description

 Figure 2: Message Description ....1.... ....2.... ....3.... ....4.... ....5.... ....6.... ....7 C *INZSR BEGSR C CALL 'SUBR23R3' C PARM 'HDG0001' MSGID 7 C PARM MSGTXT132 C PARM 3 MSGLVL 10 C PARM RTNCDE 10 C PARM TXTLEN 40 C CALL 'SUBR23R3' C PARM 'HDG0002' MSGID 7 C (etc.) C ENDSR ....1.... ....2.... ....3.... ....4.... ....5.... ....6.... ....7 
Good News for RPG/400

Figure 3A Initializing a data structure globally

 Figure 3a: Initializing a Data Structure Globally ....1.... ....2.... ....3.... ....4.... ....5.... ....6.... ....7 ISMPLDS IDS I 1 10 ALPHA1 I 11 150NUM1 I 16 170NUM2 I 18 20 ALPHA2 ....1.... ....2.... ....3.... ....4.... ....5.... ....6.... ....7 
Good News for RPG/400

Figure 3B Initializing a data structure by subfields

 Figure 3b: Initializing a Data Structure by Subfields ....1.... ....2.... ....3.... ....4.... ....5.... ....6.... ....7 ISMPLDS DS I 1 10 ALPHA1 I I -70 11 150NUM1 I 16 170NUM2 I I 'AZ' 18 20 ALPHA2 ....1.... ....2.... ....3.... ....4.... ....5.... ....6.... ....7 
Good News for RPG/400

Figure 4 Uses of the CLEAR operation

 Figure 4: Uses of the CLEAR Operation Type of Variable Equivalent To ---------------- ----------------- Alphanumeric MOVE *BLANK Numeric Z-ADD *ZERO Alpha array MOVEA *BLANK Numeric array MOVEA *ZERO Data structure MOVE *BLANK or Z-ADD *ZERO Indicator MOVE '0' or SETOF 
Good News for RPG/400

Figure 5 *INZSR subroutine

 Figure 5: *INZSR Subroutine ....1.... ....2.... ....3.... ....4.... ....5.... ....6.... ....7 C *INZSR BEGSR C MOVE 'CM' RCDTYP 2 C ENDSR ....1.... ....2.... ....3.... ....4.... ....5.... ....6.... ....7 
Good News for RPG/400

Figure 6 Concatenating two fields

 Figure 6: Concatenating Two Fields ....1.... ....2.... ....3.... ....4.... ....5.... ....6.... ....7 C FIRST CAT LAST:1 NAME 
Good News for RPG/400

Figure 7 Scanning a name in a file

 Figure 7: Scanning a Name in a File ....1.... ....2.... ....3.... ....4.... ....5.... ....6.... ....7 C READ CUSTMAST 99 C *IN99 DOWEQ'0' C 'SMITH' SCAN CUNAME POSITN 20 C POSITN IFGT *ZERO C (what to do if found) C END C READ CUSTMAST 99 C END ....1.... ....2.... ....3.... ....4.... ....5.... ....6.... ....7 
Good News for RPG/400

Figure 8 Scanning with selection criteria

 Figure 8: Scanning With Selection Criteria ....1.... ....2.... ....3.... ....4.... ....5.... ....6.... ....7 C FIRST:4 SCAN NAME:2 POSITN 
Good News for RPG/400

Figure 9 Scanning multiple occurrences

 Figure 9: Scanning Multiple Occurrences ....1.... ....2.... ....3.... ....4.... ....5.... ....6.... ....7 E ARR 8 2 0 C 'T' SCAN NAME ARR ARR,1 1 (found in first position) ARR,2 6 (found in sixth position) ARR,3 7 (found in seventh position) ARR,4 10 (found in tenth position) ARR,5 11 (found in eleventh position) ARR,6 0 (no more occurrences of 'T') ARR,7 0 (same) ARR,8 0 (same) ....1.... ....2.... ....3.... ....4.... ....5.... ....6.... ....7 
BLOG COMMENTS POWERED BY DISQUS

LATEST COMMENTS

Support MC Press Online

$

Book Reviews

Resource Center

  • SB Profound WC 5536 Have you been wondering about Node.js? Our free Node.js Webinar Series takes you from total beginner to creating a fully-functional IBM i Node.js business application. You can find Part 1 here. In Part 2 of our free Node.js Webinar Series, Brian May teaches you the different tooling options available for writing code, debugging, and using Git for version control. Brian will briefly discuss the different tools available, and demonstrate his preferred setup for Node development on IBM i or any platform. Attend this webinar to learn:

  • SB Profound WP 5539More than ever, there is a demand for IT to deliver innovation. Your IBM i has been an essential part of your business operations for years. However, your organization may struggle to maintain the current system and implement new projects. The thousands of customers we've worked with and surveyed state that expectations regarding the digital footprint and vision of the company are not aligned with the current IT environment.

  • SB HelpSystems ROBOT Generic IBM announced the E1080 servers using the latest Power10 processor in September 2021. The most powerful processor from IBM to date, Power10 is designed to handle the demands of doing business in today’s high-tech atmosphere, including running cloud applications, supporting big data, and managing AI workloads. But what does Power10 mean for your data center? In this recorded webinar, IBMers Dan Sundt and Dylan Boday join IBM Power Champion Tom Huntington for a discussion on why Power10 technology is the right strategic investment if you run IBM i, AIX, or Linux. In this action-packed hour, Tom will share trends from the IBM i and AIX user communities while Dan and Dylan dive into the tech specs for key hardware, including:

  • Magic MarkTRY the one package that solves all your document design and printing challenges on all your platforms. Produce bar code labels, electronic forms, ad hoc reports, and RFID tags – without programming! MarkMagic is the only document design and print solution that combines report writing, WYSIWYG label and forms design, and conditional printing in one integrated product. Make sure your data survives when catastrophe hits. Request your trial now!  Request Now.

  • SB HelpSystems ROBOT GenericForms of ransomware has been around for over 30 years, and with more and more organizations suffering attacks each year, it continues to endure. What has made ransomware such a durable threat and what is the best way to combat it? In order to prevent ransomware, organizations must first understand how it works.

  • SB HelpSystems ROBOT GenericIT security is a top priority for businesses around the world, but most IBM i pros don’t know where to begin—and most cybersecurity experts don’t know IBM i. In this session, Robin Tatam explores the business impact of lax IBM i security, the top vulnerabilities putting IBM i at risk, and the steps you can take to protect your organization. If you’re looking to avoid unexpected downtime or corrupted data, you don’t want to miss this session.

  • SB HelpSystems ROBOT GenericCan you trust all of your users all of the time? A typical end user receives 16 malicious emails each month, but only 17 percent of these phishing campaigns are reported to IT. Once an attack is underway, most organizations won’t discover the breach until six months later. A staggering amount of damage can occur in that time. Despite these risks, 93 percent of organizations are leaving their IBM i systems vulnerable to cybercrime. In this on-demand webinar, IBM i security experts Robin Tatam and Sandi Moore will reveal:

  • FORTRA Disaster protection is vital to every business. Yet, it often consists of patched together procedures that are prone to error. From automatic backups to data encryption to media management, Robot automates the routine (yet often complex) tasks of iSeries backup and recovery, saving you time and money and making the process safer and more reliable. Automate your backups with the Robot Backup and Recovery Solution. Key features include:

  • FORTRAManaging messages on your IBM i can be more than a full-time job if you have to do it manually. Messages need a response and resources must be monitored—often over multiple systems and across platforms. How can you be sure you won’t miss important system events? Automate your message center with the Robot Message Management Solution. Key features include:

  • FORTRAThe thought of printing, distributing, and storing iSeries reports manually may reduce you to tears. Paper and labor costs associated with report generation can spiral out of control. Mountains of paper threaten to swamp your files. Robot automates report bursting, distribution, bundling, and archiving, and offers secure, selective online report viewing. Manage your reports with the Robot Report Management Solution. Key features include:

  • FORTRAFor over 30 years, Robot has been a leader in systems management for IBM i. With batch job creation and scheduling at its core, the Robot Job Scheduling Solution reduces the opportunity for human error and helps you maintain service levels, automating even the biggest, most complex runbooks. Manage your job schedule with the Robot Job Scheduling Solution. Key features include:

  • LANSA Business users want new applications now. Market and regulatory pressures require faster application updates and delivery into production. Your IBM i developers may be approaching retirement, and you see no sure way to fill their positions with experienced developers. In addition, you may be caught between maintaining your existing applications and the uncertainty of moving to something new.

  • LANSAWhen it comes to creating your business applications, there are hundreds of coding platforms and programming languages to choose from. These options range from very complex traditional programming languages to Low-Code platforms where sometimes no traditional coding experience is needed. Download our whitepaper, The Power of Writing Code in a Low-Code Solution, and:

  • LANSASupply Chain is becoming increasingly complex and unpredictable. From raw materials for manufacturing to food supply chains, the journey from source to production to delivery to consumers is marred with inefficiencies, manual processes, shortages, recalls, counterfeits, and scandals. In this webinar, we discuss how:

  • The MC Resource Centers bring you the widest selection of white papers, trial software, and on-demand webcasts for you to choose from. >> Review the list of White Papers, Trial Software or On-Demand Webcast at the MC Press Resource Center. >> Add the items to yru Cart and complet he checkout process and submit

  • Profound Logic Have you been wondering about Node.js? Our free Node.js Webinar Series takes you from total beginner to creating a fully-functional IBM i Node.js business application.

  • SB Profound WC 5536Join us for this hour-long webcast that will explore:

  • Fortra IT managers hoping to find new IBM i talent are discovering that the pool of experienced RPG programmers and operators or administrators with intimate knowledge of the operating system and the applications that run on it is small. This begs the question: How will you manage the platform that supports such a big part of your business? This guide offers strategies and software suggestions to help you plan IT staffing and resources and smooth the transition after your AS/400 talent retires. Read on to learn: