Control Structures
This section will look at program flow control and logical expressions. It could be argued that this is really the main aspect of ABAP programming, where the real work is done. How one structures a program using logical expressions will determine the complete flow of the program and in what sequence actions are taken.
First, a look will be taken at control structures. When a program is created it is broken up into many tasks and subtasks. One controls how and when the sections of a program are executed using logical expressions and conditional loops, often referred to as control structures.
If Statement
Copy your program previous article in which to test some of the logic which is to be built. Here I copy the program Z_OPENSQL_1 to Z_LOGIC_1:
Remove all of the code from the program, leaving only the first example INSERT statement and its validation test.
When one talks of control structures, this refers to large amounts of code which allows one to make decisions, resulting in a number of different outcomes based on the decisions taken. Take a look at the IF statement to explain the basic logic at work here.
The IF statement is probably the most common control structure, found in just about every programming language. The syntax may vary between languages, but its use is just about universal:
This IF statement tells the program that IF (a logical expression), do something. The ELSE addition means that should this logical expression not occur, do something else. Then the statement is ended with the ENDIF statement.
The IF and ENDIF statements belong together, and every control structure created will take a similar form, with a start and an end. Control structures can be very large, and may contain other, smaller control structures within them, having the system perform tasks within the framework of a larger task. The code between the start and end of a control structure defines the subtasks within it. Tasks can be repeated, in what are called loops.
From here on, control structures will be used to control the flow, create tasks, subtasks and branches within a program, and to perform loops.
Comment out all of the preceding code, and click the ‘Pattern’ button, in the toolbar by Pretty Printer. A window will appear, and just select the ‘Other pattern’ field, and type “IF”. The structure of an IF statement will then appear in the code, which can be followed as a guide:
Create a DATA statement, 15 characters of type ‘c’, and name this “surname”. Then on a new line give this the value ‘SMITH’. Then edit the auto-generated IF statement so that it looks like this.
The IF statement here takes the form that if the value of ”surname” is ‘SMITH’, text will be displayed stating “Youve won a car!” (note that an apostrophe cannot be placed correctly in You’ve without making the code invalid). Then execute the code. The result should be:
Next, this will be extended to include the ELSEIF statement which has been commented out above. Change the value of “surname” to ‘BROWN’. Then, add to the ELSEIF statement so that if the value of “surname” is ‘BROWN’, the output text will read “Youve won a boat!”:
In this example, the first IF statement was not true, as the surname was not Smith. Hence this branch was not executed. The ELSEIF statement was true, so the text output assigned here appeared. The ELSEIF statement can be added to an IF statement any number of times, to designate the action taken in a number of situations:
Depending on what the value of ‘surname’ is at any given time, a different branch will be executed.
There is also the ELSE statement. This is used for the last piece of the IF block, and is used if none of the values in the IF and ELSEIF statement are matched. The full block of code is shown below:
With this block as it is now, there will always be an output, regardless of the value of ‘surname’, every possibility is now taken care of. The value will either match one of the first four, or the ELSE statement’s text will be displayed. The IF statement is very important for determining the flow of a program and will be used on a regular basis.
Linking Logical Expressions Together
There are a whole set of ABAP operators which can be used with logic statements. With the IF statement so far the equals (=) operator has been used. The following can also be used here:
(from left to right: equal to, NOT equal to, less than, greater than, less than OR equal to, greater than OR equal to. These can also be written with their text equivalents, in order: EQ, NE, LT, GT, LE, GE. The text versions are not commonly used.)
Logical expressions can be linked with the operators OR, AND and NOT. For example, one could add to the previous IF statement:
OR and NOT operate can also be used in exactly the same way
Nested If Statements
Nested IF statements allow one to include IF statements inside other IF statements, for example:
Here, the first IF statement will discount records where the Surname field value does not equal ‘SMITH’. For all records with a Surname = ‘SMITH’, the second IF statement checks to see if the record being processed has a Forename = ‘JOHN’. If it does the message “Youve won a car!” will be output to the screen. If not, a consolatory message will be output instead.
You are not limited to just one nested IF statement. Nesting can continue down as many levels / branches as is required by the program being written, for example:
Also, you do not simply have to nest statements one after another, but can put any other statements you need between, as long as the control structures are terminated correctly with, in this case, the ENDIF statement.
Case Statement
When logical expressions are created, and linked together, it is always important to make the code as readable as possible. Generating many logical expressions on one line can often be confusing. While the code will still work without problems, it is preferable to structure your code across multiple lines and make use of other control structures if possible.
This is where the CASE statement can help. This does similar work to the IF statement but with the flexibility to make the code much more readable, but is at the same time limited to one logical expression. Here is an example code block for the CASE statement:
Like the IF statement, here the contents of the surname field are searched by the CASE statement, checking its contents and performing an action. The WHEN addition is used to check the field for different values, and WHEN OTHERS accounts for all values which are not specified elsewhere. The ENDCASE statement closes this control structure. This is in many ways much easier to read than a large amount of nested IFs and ELSEIFs.
You also have the facility to nest multiple CASE statements.
Select Loops
This next section will discuss iteration statements, otherwise known as looping statements. These are used to execute a block of ABAP code multiple times.
Create another new program and call it Z_ITERATIONS_1.
There are various ways to loop through blocks of code in an ABAP program, and these can be separated into those which have conditions attached and those which do not. The SELECT statement is a form of loop which has already been used. This statement allows you to iterate through a record set.
The asterisk (*) tells the program to select everything from the zemployees table, and this is followed by a WRITE statement to write the table to the output screen. The SELECT loop closed with ENDSELECT, at which point the loop returns to the start, writing each record in turn until there are no more records to process in the table.
This last example had no conditions attached. To add a condition is quite simple:
Here, only records where the surname is Mills will be selected and written to the output screen:
Do Loops
The DO loop is a simple statement, here declare DO. Add a WRITE statement, and then ENDDO:
You will notice there is nothing to tell the loop to end. If one tries to execute the code, the program will get stuck in a continuous loop endlessly writing out ‘Hello’ to the output screen. The transaction must be stopped and the code amended. A mechanism must be added to the DO loop to tell it when to stop processing the code inside it. Here, the TIMES addition is used. Amend the code as follows so that the system knows the loop is to be processed 15 times. Also here a ‘new line’ has been added before ‘Hello’:
The DO statement is useful for repeating a particular task a specific number of times. Just remember to always include the TIMES addition.
Now try some processing with the DO loop. Create a DATA variable named ‘a’, of type integer, and set the value of this to 0. Then, inside the DO loop, include the simple calculation “a = a + 1”.
The system also contains its own internal counter for how many times a DO loop is executed, which can be seen when this is executed in debug mode. Set a breakpoint on the DO line, then execute the code, keeping an eye on the ‘a’ field in the Field names section, and also includes ‘sy-index’ in one of these fields. You will see that ‘a’ keeps a running count of how many times the DO loop executes as well as the system variable sy-index. The values will be the same for both, going up by 1 each time the loop completes. The sy-index variable will in fact update a line of code before the ‘a’ variable, as it counts the DO loops, and the ‘a’ refers to the calculation on the next line of code:
Note that here the blue arrow cursor has moved down a line in the second image, executing the next line of code. If one adds a new line to the WRITE statement in the initial code, the output window will appear like this:
Nested Do Loops
DO loops can also be nested. If this is done, each nested loop will have its own sy-index created and monitored by the system. Be aware that when nesting many loops, it is important to consider how much work the system is being asked to do.
Add to the WRITE statement from the previous section a small amount of text reading ‘Outer Loop cycle:’ before outputting the value of ‘a’. This will allow ‘a’ to be monitored.
Then, under the WRITE statement, add a new DO statement to create the inner loop cycle, as below, as well as adding the extra data variables. The main loop will execute 15 times, but within each of these loops, the nested loop will execute 10 times. The variable named ‘c’ will count how many times the loop has occurred. Around 150 loops will execute here.
While the SAP system will certainly be able to handle this instantly, you should bear in mind that if this number was significantly larger and included more intensive processing than simple counting, this could take much longer:
Set a breakpoint and execute this code in debug mode, keeping an eye on the values of a, b, c and sy-index in the Fields mode. As the DO loop is entered, the sy-index field will begin counting. Here, the inner loop has just occurred for the 10th time, noted by the 10 in sy-index (and indeed the value of ‘b’).
Then the full loop has completed once, the sy-index field displays 1 and the ‘c’ field has been filled in:
After the second full loop, sy-index and ‘a’ will display 2, ‘b’ will be 10 again (as its value is reset to 0 at the beginning of each loop) and ‘c’ will display 20 representing the number of calculations completed all together:
After the full 15 outer loops are completed, it will look like this:
The value of ‘a’ is then added to ‘c’ to give the total number of both outer and inner loops completed:
When the results are viewed in the output window, the last full loop will look like this:
While Loops
The next looping statement to be examined is the WHILE loop. This differs from the DO loop in that it checks for a predefined condition within the loop before executing any code. All the code between the WHILE and ENDWHILE statements will be repeated as long as the conditions are met. As soon as the condition is false the loop terminates. Here, again the sy-index field can be monitored to see how many times the loop has executed.
So here, the loop will again cause the value of ‘a’ to take the form of incremental counting, and each time the loop is executed the value of ‘a’ will be written. The loop will continue as long as the value of ‘a’ is not equal to 15, and once it is, it will stop:
If one runs this in the debugger mode one will see that on the 15th loop, when the value of ‘a’ is 15, the code inside the statement is skipped over and the cursor jumps straight from WHILE to ENDWHILE.
Nested While Loops
Just as with DO loops, WHILE loops can be nested. The process is exactly the same for both. Below is an example of nested WHILE loop statements.
The output for this code would appear exactly the same as our nested DO loop example. The values of ‘b’ have also been indented slightly here for ease of reading:
Loop Termination – CONTINUE
Up until now, the loop statements set up have been allowed to use the conditions inside them to determine when they are terminated. ABAP also includes termination statements which allow loops to be ended prematurely. There are two categories of these, those which apply to the loop and those which apply to the entire processing block in which the loop occurs.
First, we will looks at how to terminate the processing of a loop. The first statement of importance here is the CONTINUE statement. This allows a loop pass to be terminated unconditionally. As the syntax shows, there are no conditions attached to the statement itself. It tells the program to end processing of the statements in the loop at the point where it appears and go back to the beginning of the loop again. If it is included within a loop, any statements after it will not be executed.
For the simple DO loop ,include an IF statement which includes CONTINUE inside it, like this:
With this code, the second iteration of the loop (when the sy-index field, like the value of a, will read 2) will hit the CONTINUE statement and go back to the top, missing the WRITE statement. When this is output, the incremental counting will go from 1 to 3. As with many of these statements, in debug mode, the operation can be observed more closely by executing the code line by line.
Loop Termination – CHECK
The CHECK statement works similarly to the CONTINUE statement, but this time allows you to check specific conditions. When the logic of a CHECK statement is defined, if the condition is not met, any remaining statements in the block will not be executed and processing will return to the top of the loop. It can be thought of as a combination of the IF and CONTINUE statements. To use the CHECK statement to achieve the same ends as in the example above, the syntax would look like this:
The program will check that the sy-index field does not contain a value equal to 2, and where it does not, will continue executing the code. When it does contain 2, the condition attached will not be true and the CHECK statement will cause the loop to start again, missing the WRITE statement. This can be executed in debug mode to closely observe how it works. The output window, once this is complete, will again appear like this:
When you are looking at programs created by other people, do not be surprised to see the CHECK statement used outside loops. It is not only used to terminate a loop pass, but can check, and terminate other processing blocks at any point if its particular conditions are not met. You must be aware of where the CHECK statement is being used, as putting it in the wrong place can even cause the entire program to terminate. For example here, the statement will only allow processing to continue if the value of ‘a’ is equal to 1. Since the value of ‘a’ equals 0, it will always terminate the program before the DO loop is reached:
Loop Termination – EXITe EXIT statement can also be used to terminate loops. This again allows the loop to be terminated immediately without conditions. Unlike the CONTINUE statement though, it does not then return to the beginning of a loop but, terminates the loop entirely once it is reached. The program will then continue process the code immediately following the end statement of the loop.
If the exit statement is used within a nested loop, it will only be that nested loop which is terminated and the statement following the end of the nested loop will execute next in the higher level loop. Additionally it can, like the CHECK statement, be used outside loops, though again one must be careful doing this.
In the next example, regardless of the number of times the DO statement is told to be executed, on the third loop when the sy-index field contains the number 3, the loop will be terminated and the statement after ENDDO will be executed, writing “Filler” to the output screen.