How To Replace MOVE And MOVEL With Subprocedures
September 27, 2016 Ted Holt
Note: The code accompanying this article is available for download here.
Google “what shall we do about” and you’ll find a lot of issues that people are concerned about. Now that RPG has gone fully free-form, the question of concern for RPG programmers is “what shall we do about MOVE and MOVEL?” Faithful reader Mark sent me a solution he used in his shop and gave me permission to pass it along in case it may be of help to you.
I can think of two ways to replace MOVE and MOVEL with free-form code. The first is to string together math expressions and/or built-in functions within EVAL statements. Bryan Meyers has thoughtfully provided a thorough and concise guide to this approach at http://enskill.com/faqs/free-format-alternatives-to-move/.
I can illustrate this approach with a common task from my experience. Suppose a customer number is an eight-digit value, which consists of a two-digit company number followed by a six-digit account number within that company. Users perceive the customer number as a single eight-digit value, but in the database, company and account are separate fields. A common task is to split an eight-digit number into company and account. (An equally common task is to combine company and account into one eight-digit number.)
With fixed-form RPG, this process is efficiently handled using MOVE and MOVEL.
C MOVEL CUSNO COMPNY C MOVE CUSNO ACCT
The following code shows two ways to extract company and account from the customer number.
COMPNY = CUSNO * 0.000001; ACCT = CUSNO - (COMPNY * 1000000); COMPNY = %uns(%subst(%editc(CUSNO:'X'):1:2)); ACCT = %uns(%subst(%editc(CUSNO:'X'):3));
I won’t say that is ideal, but it does seem to me to be the best available method. It’s a labor-intensive method, requiring a programmer to examine each operation, decide how it works, write a free-form equivalent, and test the new code.
The other approach is to replace each MOVE and MOVEL with a call to a subprocedure that accomplishes the same task. The effort required for this approach is less than the first method, requiring nothing more than determining the proper parameter values to pass to the subprocedures.
Mark chose the second approach. He wrote a service program with five exported subprocedures.
Let’s see the same task using Mark’s routines.
COMPNY = mv_n2n ('L': CUSNO : COMPNY: 8.0: 2.0); ACCT = mv_n2n ('R': CUSNO : ACCT: 8.0: 6.0);
The following table explains the parameters:
Field definitions are expressed as real numbers, where the whole number portion is the total field length and the decimal portion is the number of decimal positions. This is an easy way to pass two pieces of information through one value.
It’s not necessary to hardcode field definitions. The compiler can calculate the lengths for variables.
COMPNY = mv_n2n ('L': CUSNO : COMPNY: %len(CUSNO) + 0.1 * %decpos(CUSNO): %len(COMPNY) + 0.1 * %decpos(COMPNY)); ACCT = mv_n2n ('R': CUSNO : ACCT: %len(CUSNO) + 0.1 * %decpos(CUSNO): %len(ACCT) + 0.1 * %decpos(ACCT));
Notice that the result field is expressed twice–as the third parameter and as the target of the assignment.
Let me end with a few more comments.
There you have two ways to convert MOVE and MOVEL to free-form RPG. Which is better? That’s easy. The better one is the one that more easily enables you to raise prices and/or decrease costs.
Ted Holt welcomes your comments and questions. Email him through the IT Jungle Contacts page.