The RPG Select When Other Operations

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

It's one thing to wish for language improvements that will make your programs easier to maintain; it's quite another to overlook the tools that are already available. Some topics just seem to suffer from underexposure. Take for example the SELEC, WHxx, OTHER and ENDSL operations in RPG/400. According to my informal survey, some programmers have never heard of the SELEC group of operations. Even those who are aware of this feature do not always know how it functions or appreciate its usefulness. I often hear programmers say "Select? That's SQL stuff. I don't need it." In fact, SELEC and SQL are not even remotely related. The SELEC and its corresponding operations are supported by the standard RPG/400 compiler.

I have found that proper use of the SELEC group can increase readability and in some cases improve performance. I'm sure you're familiar with RPG programs in which the ENDxx operations seem to cluster together throughout the source code or programs that use the CASxx operation to execute a subroutine containing a single line of code. A few simple guidelines coupled with judicious use of the SELEC operations can solve both of these problems. It's all a matter of using the right comparison operation for the task at hand. This comparative strategy will make your code easier to understand and maintain.

A Tour of Comparative Techniques

In the beginning, there were indicators. It's hard to believe that we once wrote complex programs using only indicators for comparisons. Mastering the blizzard of indicators and actually understanding what was happening became a source of pride and brought us job security.

The next step in RPG's evolution was the IFxx statement. A little bit later, the ANDxx and ORxx operations joined the crowd, giving rise to a resounding exclamation of "Finally!" This represented a tremendous step toward coding what you were thinking.

Then came the nifty CASxx operations-the most compact way to represent massive amounts of code. The nice thing about a CASxx group is the clarity. A programmer can summarize a great deal of code, eliminating repetitive IFxx, EXSR, ELSE structures.

We certainly didn't anticipate those "micro" subroutines with one or two lines of code. Regardless of whether small subroutines are good or bad, they just don't feel right. To me, a subroutine is a group of statements that accomplishes a specific function. We separate the statements into a subroutine for the sake of clarity, or because it is executed repetitively-or both.

Writing code with these tools, we created our fair share of nightmarish IF, ELSE, IF, ELSE, IF, ELSE nesting problems...not to mention the resulting confusion if you threw in a couple of DO loops. There were so many END statements, you probably needed a map. (Go to the END END END END of the block and take a left.) Then came the ability to concatenate IF or DO or CS to our END operations. This helped to clean up the code and make navigating program logic much simpler.

The SELEC group is the latest addition to our comparative arsenal-it doesn't revolutionize RPG, but we now have a way of replacing some of those awful nested conditions and one-line subroutines. It's not the ultimate solution to messy conditional coding, but it does have its place among the other solutions which have evolved.

Illustration of Coding Methods

Every programmer knows that conditions and dependent conditions are part of the job. Consider the code in 1. We all have a program or two (or 20) which contain code like this-without using the SELEC group, this solution is probably the best as far as structure.

Every programmer knows that conditions and dependent conditions are part of the job. Consider the code in Figure 1. We all have a program or two (or 20) which contain code like this-without using the SELEC group, this solution is probably the best as far as structure.

Although the method in 2 may look familiar, I do not recommend its use in structured programming. Think about how the steps would execute. Let's say that the first condition is met. The program unnecessarily continues to check every IFxx statement afterward even though we have already found our match. 3 avoids this scenario at the expense of a GOTO operation at the end of each IFxx group. As you probably know, the GOTO operation does not belong to the "structured programming club."

Although the method in Figure 2 may look familiar, I do not recommend its use in structured programming. Think about how the steps would execute. Let's say that the first condition is met. The program unnecessarily continues to check every IFxx statement afterward even though we have already found our match. Figure 3 avoids this scenario at the expense of a GOTO operation at the end of each IFxx group. As you probably know, the GOTO operation does not belong to the "structured programming club."

4 contains a fine example of a typical CASxx structure. CASxx structures work well for executing lengthy subroutines; but if you use them to call subroutines with just a few lines of code, you should consider replacing them with the SELEC group.

Figure 4 contains a fine example of a typical CASxx structure. CASxx structures work well for executing lengthy subroutines; but if you use them to call subroutines with just a few lines of code, you should consider replacing them with the SELEC group.

5 illustrates how the SELEC group could replace1, 2, 3 or 4. The illustrated method is very simple.

Figure 5 illustrates how the SELEC group could replace Figures 1, 2, 3 or 4. The illustrated method is very simple.

Guidelines for Using the SELEC Group

I have referred to the SELEC, WHxx, OTHER and ENDSL operations as a group because they only work when used with each other. The following excerpt from IBM's RPG/400 Reference manual summarizes how the SELEC group works.

After the SELEC operation, control passes to the statement following the first WHxx condition that is satisfied. All statements are then executed until the next WHxx operation. Control passes to the ENDSL statement (only one WHxx is executed). If no WHxx condition is satisfied and an OTHER operation is specified, control passes to the statement following the OTHER operation. If no WHxx condition is satisfied and no OTHER operation is specified, control transfers to the statement following the ENDSL operation of the select group.

You must always start a SELEC group with a SELEC statement and end with an END or ENDSL statement. These two statements really do nothing more than mark the beginning and end of the group.

In any SELEC group usage, a WHxx (When) statement immediately follows the SELEC statement. (It is a common error to translate WHEQ as "Where Equal"-the correct interpretation is When Equal.) As with IF/ELSE nests, it is advisable to arrange your list of comparisons so that the "most likely to be true" conditions come first and the "least likely to be true" come last. You probably won't realize a massive performance improvement from this arrangement unless you process dozens of SELEC groups with hundreds of thousands of records.

You can use ORxx and ANDxx with WHxx, just as you do with an IFxx statement. You cannot use conditioning indicators on a WHxx statement, but you can use control-level indicators (positions 7-8).

I should point out one important concept about WHxx: it is possible that more than one WHxx condition in your list is true, but only the first one found to be true will be processed. Any additional WHxx or OTHER operations are bypassed.

The optional OTHER statement is similar to using the ELSE or CAS operations. The OTHER operation more closely resembles the CAS operation because it functions as the catch-all if none of the WHxx conditions above it were met. The basic logic of an OTHER statement is: If none of the WHxx conditions between the nearest SELEC operation above and the OTHER statement are true, execute the following statements until you reach the first ENDSL operation.

As with WHxx, you cannot use conditional indicators with the OTHER operation, but you can use control-level indicators. You can use conditioning indicators with the SELEC operation, but you probably won't do it often. (Using conditioning indicators is generally considered antisocial behavior in an RPG/400 shop.)

You can nest SELEC groups- much like nesting IFxx statements as illustrated in 6. For example, I have used nested SELEC groups successfully in an interactive program which tests for cursor position when the user presses F4 to prompt on a field. The first SELEC group in the program determines which function key is pressed. A second SELEC group determines which row and column the cursor is on. And a final SELEC group is used to determine which "mode" the program is in (Inquiry, Add, Change, Delete). I'm sure that you can find other uses for the nested SELEC group in your applications.

You can nest SELEC groups- much like nesting IFxx statements as illustrated in Figure 6. For example, I have used nested SELEC groups successfully in an interactive program which tests for cursor position when the user presses F4 to prompt on a field. The first SELEC group in the program determines which function key is pressed. A second SELEC group determines which row and column the cursor is on. And a final SELEC group is used to determine which "mode" the program is in (Inquiry, Add, Change, Delete). I'm sure that you can find other uses for the nested SELEC group in your applications.

Each Technique Has a Place

The SELEC group isn't a universal comparative strategy but it is a good solution to nasty, never-ending nesting problems. IBM's SELEC group documentation says a WHxx op code is not required, but I'm still trying to figure out a use for that feature. I follow the rule that, if you use a SELEC group, you should have at least three conditions you're checking for. If you only have one condition, use a normal IFxx statement. If you have two conditions, use the faithful IFxx/ELSE structure.

The SELEC group of operations is not a complex concept. It is not meant to replace the IFxx or the CASxx group of operations, but simply adds to your arsenal of alternatives. The biggest advantage is the ease of readability you will add to your programs-which translates into easier maintenance in the future. If you use the SELEC group to replace source code like the example in 2, you may also see some performance improvements.

The SELEC group of operations is not a complex concept. It is not meant to replace the IFxx or the CASxx group of operations, but simply adds to your arsenal of alternatives. The biggest advantage is the ease of readability you will add to your programs-which translates into easier maintenance in the future. If you use the SELEC group to replace source code like the example in Figure 2, you may also see some performance improvements.

So now you have a new technique that you can use. Hopefully, you have gained an understanding of, and an appreciation for, the SELEC group. It allows you to stop juggling some of those ENDIFs, and to make your CASxx statements represent "real" subroutines.

Charley Shanks is a programmer/analyst with M.S. Carriers in Memphis, Tennessee.


The RPG Select When Other Operations

Figure 1 IF, ELSE, IF, ELSE...

 *. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+.. C DAY IFEQ '1' C MOVEL'MON' DESC C ELSE C DAY IFEQ '2' C MOVEL'TUE' DESC C ELSE C DAY IFEQ '3' C MOVEL'WED' DESC C ELSE C DAY IFEQ '4' C MOVEL'THU' DESC C ELSE C DAY IFEQ '5' C MOVEL'FRI' DESC C ELSE C MOVEL'???' DESC C ENDIF C ENDIF C ENDIF C ENDIF C ENDIF *. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+.. 
The RPG Select When Other Operations

Figure 2 IF, ENDIF, IF, ENDIF...

 *. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+.. C DAY IFEQ '1' C MOVEL'MON' DESC C ENDIF C DAY IFEQ '2' C MOVEL'TUE' DESC C ENDIF C DAY IFEQ '3' C MOVEL'WED' DESC C ENDIF C DAY IFEQ '4' C MOVEL'THU' DESC C ENDIF C DAY IFEQ '5' C MOVEL'FRI' DESC C ENDIF C DAY IFLT '1' C DAY ORGT '5' C MOVEL'???' DESC C ENDIF *. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+.. 
The RPG Select When Other Operations

Figure 3 IF, ENDIF, IF, ENDIF... With GOTOs

 *. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+.. C DAY IFEQ '1' C MOVEL'MON' DESC C GOTO ENDTAG C ENDIF C DAY IFEQ '2' C MOVEL'TUE' DESC C GOTO ENDTAG C ENDIF C DAY IFEQ '3' C MOVEL'WED' DESC C GOTO ENDTAG C ENDIF C DAY IFEQ '4' C MOVEL'THU' DESC C GOTO ENDTAG C ENDIF C DAY IFEQ '5' C MOVEL'FRI' DESC C GOTO ENDTAG C ENDIF C MOVEL'???' DESC C ENDTAG TAG *. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+.. 
The RPG Select When Other Operations

Figure 4 CASEQ, ENDCS

 *. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+.. C DAY CASEQ'1' DAY1 C DAY CASEQ'2' DAY2 C DAY CASEQ'3' DAY3 C DAY CASEQ'4' DAY4 C DAY CASEQ'5' DAY5 C CAS ERROR C ENDCS * C DAY1 BEGSR C MOVEL'MON' DESC C ENDSR * C DAY2 BEGSR C MOVEL'TUE' DESC C ENDSR * C DAY3 BEGSR C MOVEL'WED' DESC C ENDSR * C DAY4 BEGSR C MOVEL'THU' DESC C ENDSR * C DAY5 BEGSR C MOVEL'FRI' DESC C ENDSR * C ERROR BEGSR C MOVEL'???' DESC C ENDSR *. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+.. 
The RPG Select When Other Operations

Figure 5 SELEC, WHEQ, OTHER, ENDCS

 *. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+.. C SELEC C DAY WHEQ '1' C MOVEL'MON' DESC C DAY WHEQ '2' C MOVEL'TUE' DESC C DAY WHEQ '3' C MOVEL'WED' DESC C DAY WHEQ '4' C MOVEL'THU' DESC C DAY WHEQ '5' C MOVEL'FRI' DESC C OTHER C MOVEL'???' DESC C ENDSL *. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+.. 
The RPG Select When Other Operations

Figure 6 Nested SELEC Groups

 *. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+.. C SELEC C DAY WHEQ '1' C MOVEL'MON' DESC * C DAY WHEQ '2' C MOVEL'TUE' DESC * C SELEC C TIME WHLT 90000 C MOVEL'A' CODE C TIME WHLT 170000 C MOVEL'B' CODE C OTHER C MOVEL'C' CODE C ENDSL * C DAY WHEQ '3' C MOVEL'WED' DESC * C DAY WHEQ '4' C MOVEL'THU' DESC * C SELEC C TIME WHLT 90000 C MOVEL'D' CODE C TIME WHLT 170000 C MOVEL'E' CODE C OTHER C MOVEL'F' CODE C ENDSL * C DAY WHEQ '5' C MOVEL'FRI' DESC * C OTHER C MOVEL'???' DESC C ENDSL *. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+.. 
BLOG COMMENTS POWERED BY DISQUS