Day 10

Common Control Statements


Chapter Objectives

After you complete this chapter, you should be able to:

Using the if Statement

The if statement in ABAP/4 has relational operators for equality and inequality and special relational operators for string comparisons and for bit masks.

NOTE
Bit comparisons are not often used in ABAP/4 and so they are not presented here. They are, however, detailed in the ABAP/4 keyword documentation under the heading "Relational Operators for Bit Masks."

Syntax for the if Statement

The following is the syntax for the if statement.

if [not] exp [ and [not] exp ] [ or [not] exp ].
    ---
[elseif exp.
    ---]
[else.
    ---]
    endif.

where:

The following points apply:

The logical operators for operands of any type are listed in Table 10.1.

Table 10.1  Common Comparisons and Their Alternate Forms

Comparison
Alternate
Forms
True When
v1 = v2 EQv1 equals v2
v1 <> v2 NE, ><v1 does not equal v2
v1 > v2 GTv1 is greater than v2
v1 < v2 LTv1 is less than v2
v1 >= v2 GE, =>v1 is greater than or equal to v2
v1 <= v2 LE, =<v1 is less than or equal to v2
v1 between v2 and v3  v1 lies between v2 and v3 (inclusive)
not v1 between v2 and v3  v1 lies outside of the range v2 to v3 (inclusive)

In Table 10.1, v1 and v2 can be variables, literals, or field strings. In the case of variables or literals, automatic conversion is performed if the data type or length does not match. Field strings are treated as type c variables.

Comparing two values that do not have the same data type will result in an internal automatic type adjustment of one or both of the values. One type will take precedence and will dictate what type of conversion is performed. The order of precedence is:

Conversions follow the same rules as those performed by the move statement. Type conversions are fully detailed in the ABAP/4 keyword documentation under the heading "Relational Operators for All Data Types."

Data Conversion of Literals During Comparisons

Literals are stored internally with data types, as shown in Table 10.2.

Table 10.2  Data Types of Literals
Description
Data Type
Numbers one to nine digits long
i
Numbers 10 or more digits long
p
All others
c

Type conversions for literals follow the same order of precedence and the same conversion rules apply.

Listing 10.1 shows a sample program using the common comparison operators. A surprising conversion is also demonstrated.


Listing 10.1  An Example of Using IF in the Program

1  report ztx1001.
2  data: begin of s1,
3            x value 'X',
4            y value 'Y',
5            z value 'Z',
6            end of s1,
7        begin of s2,
8            x value 'X',
9            z value 'Z',
10           end of s2.
11
12 if s1-x = s2-x.
13     write: / s1-x, '=', s2-x.
14 else.
15     write: / s1-x, '<>', s2-x.
16     endif.
17
18 if s1-x between s2-x and s2-z.
19     write: / s1-X, 'is between', s2-x, 'and', s2-z.
20 else.
21     write: / s1-X, 'is not between', s2-x, 'and', s2-z.
22     endif.
23
24 if s1 = s2.        "comparing field strings byte by byte
25     write: / 's1 = s2'.
26 else.
27     write: / 's1 <> s2'.
28     endif.
29
30 if 0 = ' '.        "Watch out for this one
31     write: / '0 = '' '''.
32 else.
33     write: / '0 <> '' '''.
34     endif.

The code in Listing 10.1 produces this output:

X = X
X is between X and Z
s1 <> s2
0 = ' '

Displaying Conversions

By performing a program analysis, you can determine where conversions occur within a program. To perform a program analysis, use the following procedure.

Start the ScreenCam "How to Perform a Program Analysis" now.

  1. Start at the ABAP/4 Editor: Initial Screen.
  2. Type the program name to be analyzed in the Program field.
  3. Choose the menu path Utilities->Program Analysis. The Conversions: xxxxx screen is displayed.
  4. Press the Conversions pushbutton. The Conversions: xxxxx screen is displayed. All conversions are summarized on this screen. The first column contains field types compared.
  5. Double-click on any line to view it within the program.

NOTE
The first column on the Conversions: xxxxx screen does not show which conversion is performed. It merely shows the data types involved in the conversion.

Using elseif

You use elseif to avoid nesting ifs. Nesting ifs can be difficult to read and maintain. (see Listing 10.2).


Listing 10.2  Using ELSEIF Is Clearer than Using Nested IFs

1  report ztx1002.
2  parameters: f1 default 'A',
3              f2 default 'B',
4              f3 default 'C'.
5
6  if      f1 = f2.   write: / f1, '=', f2.
7  elseif  f1 = f3.   write: / f1, '=', f3.
8  elseif  f2 = f3.   write: / f2, '=', f3.
9  else.              write: / 'all fields are different'.
10     endif.
11
12 *lines 5-9 do the same as lines 14-26
13
14 if f1 = f2.
15     write: / f1, '=', f2.
16 else.
17     if  f1 = f3.
18         write: / f1, '=', f3.
19     else.
20         if  f2 = f3.
21             write: / f2, '=', f3.
22         else.
23             write: / 'all fields are different'.
24             endif.
25         endif.
26     endif.

The code in Listing 10.2 produces this output:

all fields are different
all fields are different

Using Character String Operators

Special operators for character strings are shown in Table 10.3.

Table 10.3  Special Operators for Character Strings


Operator


Means


True When

Case
Sensitive?
Trailing
Blanks
Ignored?
v1 CO v2 Contains Onlyv1 is composed solely of characters in v2
Yes
No
v1 CN v2 not v1 CO v2 v1 contains characters that are not in v2
Yes
No
v1 CA v2 Contains Anyv1 contains at least one character in v2
Yes
No
v1 NA v2 not v1 CA v2 v1 does not contain any character in v2
Yes
No
v1 CS v2 Contains Stringv1 contains the character string v2
No
Yes
v1 NS v2 not v1 CS v2 v1 does not contain the character string v2
No
Yes
v1 CP v2 Contains Patternv1 contains the pattern in v2
No
Yes
v1 NP v2 not v1 CP v2 v1 does not contain the pattern in v2
No
Yes

These operators can be used in any comparison expression. The CS, NS, CP, and NP operators ignore trailing blanks and are not case sensitive.

Although you can use variables, constants, or literals with relational operators for character strings, for clarity Listing 10.3 only uses literals. Also for clarity, the if statements here occupy a single line each.


Listing 10.3  A Sample Program Exercising CO, CN, CA, and NA

1  report ztx1003.
2  * operator: co
3  write / '''AABB'' co ''AB'''.
4  if 'AABB' co 'AB'.           write 'True'. else. write 'False'. endif.
5  write / '''ABCD'' co ''ABC'''.
6  if 'ABCD' co 'ABC'.          write 'True'. else. write 'False'. endif.
7
8  * operator: cn
9  write / '''AABB'' cn ''AB'''.
10 if 'AABB' cn 'AB'.           write 'True'. else. write 'False'. endif.
11 write / '''ABCD'' cn ''ABC'''.
12 if 'ABCD' cn 'ABC'.          write 'True'. else. write 'False'. endif.
13
14 * operator: ca
15 write / '''AXCZ'' ca ''AB'''.
16 if 'AXCZ' ca 'AB'.           write 'True'. else. write 'False'. endif.
17 write / '''ABCD'' ca ''XYZ'''.
18 if 'ABCD' ca 'XYZ'.          write 'True'. else. write 'False'. endif.
19
20 * operator: na
21 write / '''AXCZ'' na ''ABC'''.
22 if 'AXCZ' na 'ABC'.          write 'True'. else. write 'False'. endif.
23 write / '''ABCD'' na ''XYZ'''.
24 if 'ABCD' na 'XYZ'.          write 'True'. else. write 'False'. endif.

The code in Listing 10.3 produces this output:

'AABB' co 'AB' True
'ABCD' co 'ABC' False
'AABB' cn 'AB' False
'ABCD' cn 'ABC' True
'AXCZ' ca 'AB' True
'ABCD' ca 'XYZ' False
'AXCZ' na 'ABC' False
'ABCD' na 'XYZ' True

Referring back to Table 10.3, the CP (contains pattern) and NP (no pattern) operators perform a string search that allows pattern-matching characters. The expression v1 CP v2 is true when v1 contains a string that matches the pattern in v2. The expression v1 NP v2 is true when v1 does not contain a string that matches the pattern in v2. It is equivalent to not v1 cp v2. The pattern matching characters allowed in v2 are given in Table 10.4.

Table 10.4  CP and NP Operators
Character
Used to
*
Match any sequence of characters.
+
Match any single character.
#
Interpret the next character literally.

# is the escape character. A single character following it is interpreted exactly. Special meaning, if it exists, is lost. You can also use # to make a search case sensitive or to search for the *, +, or # characters. Table 10.5 shows examples of how you might use these characters. The escape character is needed when you want to perform a case-sensitive search using CS, NS, CP, or NP. You also need it if you want to perform a pattern search (CP or NP) for a string containing *, +, or #.

Table 10.5  Using Characters
Statement
True When
v1 CP 'A+C'
v1 contains "a" in the first position and "c" in the third. Either character can be in upper- or lowercase. Any character can appear in the second position.
v1 CP '*Ab*'
The string "ab" occurs anywhere within v1. Either character can be in upper- or in lowercase.
v1 CP '*#A#b*'
v1 contains a capital A followed by lowercase b.
v1 CP '*##*'
v1 contains a #.

Use of these operators always sets the system variable sy-fdpos. If the result of the comparison is true, sy-fdpos contains the zero-based offset of the first matching or non-matching character. Otherwise, sy-fdpos contains the length of v1. The value assigned to sy-fdpos by each operator is described in Table 10.6.

After a comparison, sy-fdpos will contain either a 1st character offset or the length of v1. In this table, "1st char(v1)" means "the offset of the first character of (the string or pattern) v1 that is." So, for example, where you see "1st char(v1) in v2," read that as "the zero-based offset of the first character of v1 that is also in v2." Length(v1) means "the length of v1." Note that only the first column contains ABAP/4 statements.

Table 10.6  Value Assigned to SY-FDPOS by Each Operator
Comparison
if TRUE sy-fdpos = if FALSE sy-fdpos =
v1 CO v2
length (v1) 1stchar (v1) not in v2
v1 CN v2
1stchar (v1) in v2 length (v1)
v1 CA v2
1stchar (v1) in v2 length (v1)
v1 NA v2
length (v1) 1stchar (v1) in v2
v1 CS v2
1stchar (v2) in v1 length (v1)
v1 NS v2
length (v1) 1stchar (v1) in v2
v1 CP v2
1stchar (v2) in v1 length (v1)

Listing 10.4 is similar to Listing 10.3, but lines have been added to display the value of sy-fdpos after each comparison.


Listing 10.4  Using SY-FDPOS to See the Offset of the First Matching or Non-matching Character

1  report ztx1004.
2  * operator: co
3  write / '''AABB'' co ''AB'''.
4  if 'AABB' co 'AB'.           write 'True'. else. write 'False'. endif.
5                               write: 'sy-fdpos=', sy-fdpos.
6  write / '''ABCD'' co ''ABC'''.
7  if 'ABCD' co 'ABC'.          write 'True'. else. write 'False'. endif.
8                               write: 'sy-fdpos=', sy-fdpos.
9
10 * operator: cn
11 write / '''AABB'' cn ''AB'''.
12 if 'AABB' cn 'AB'.           write 'True'. else. write 'False'. endif.
13                              write: 'sy-fdpos=', sy-fdpos.
14 write / '''ABCD'' cn ''ABC'''.
15 if 'ABCD' cn 'ABC'.          write 'True'. else. write 'False'. endif.
16                              write: 'sy-fdpos=', sy-fdpos.
17
18 * operator: ca
19 write / '''AXCZ'' ca ''AB'''.
20 if 'AXCZ' ca 'AB'.           write 'True'. else. write 'False'. endif.
21                              write: 'sy-fdpos=', sy-fdpos.
22
23 write / '''ABCD'' ca ''XYZ'''.
24 if 'ABCD' ca 'XYZ'.          write 'True'. else. write 'False'. endif.
25                              write: 'sy-fdpos=', sy-fdpos.
26
27
28 * operator: na
29 write / '''AXCZ'' na ''ABC'''.
30 if 'AXCZ' na 'ABC'.          write 'True'. else. write 'False'. endif.
31                              write: 'sy-fdpos=', sy-fdpos.
32
33 write / '''ABCD'' na ''XYZ'''.
34 if 'ABCD' na 'XYZ'.          write 'True'. else. write 'False'. endif.
35                              write: 'sy-fdpos=', sy-fdpos.

The code in Listing 10.4 produces this output:

'AABB' co 'AB' True sy-fdpos   =   4
'ABCD' co 'ABC' False sy-fdpos =   3
'AABB' cn 'AB' False sy-fdpos  =   4
'ABCD' cn 'ABC' True sy-fdpos  =   3
'AXCZ' ca 'AB' True sy-fdpos   =   0
'ABCD' ca 'XYZ' False sy-fdpos =   4
'AXCZ' na 'ABC' False sy-fdpos =   0
'ABCD' na 'XYZ' True sy-fdpos  =   4

Using the case Statement

The case statement performs a series of comparisons.

Syntax for the case Statement

The following is the syntax for the case statement.

case v1.
    when v2 [ or vn ... ].
        ---
    when v3 [ or vn ... ].
        ---
    [ when others.
        --- ]
    endcase.

where:

The following points apply:

Case is very similar to if/elseif. The only difference is that on each if/elseif, you can specify a complex expression. With case, you can specify only a single value to be compared, and values are always compared for equality. An example is given in Listing 10.5.


Listing 10.5  The CASE Statement Performs a Series of Comparisons

1  report ztx1005.
2  parameters f1 type i default 2.
3
4  case f1.
5      when 1.         write / 'f1 = 1'.
6      when 2.         write / 'f1 = 2'.
7      when 3.         write / 'f1 = 3'.
8      when others.    write / 'f1 is not 1, 2, or 3'.
9      endcase.
10
11 * The following code is equivalent to the above case statement
12 if         f1 = 1.  write / 'f1 = 1'.
13     elseif f1 = 2.  write / 'f1 = 2'.
14     elseif f1 = 3.  write / 'f1 = 3'.
15     else.           write / 'f1 is not 1, 2, or 3'.
16     endif.

The code in Listing 10.5 produces this output:

f1 = 2
f1 = 2

Using the exit Statement

The exit statement prevents further processing from occurring.

Syntax for the exit Statement

exit.

Listing 10.6 shows a sample program using exit.


Listing 10.6  Using EXIT to Stop Program Processing Dead in Its Tracks

1  report ztx1006.
2  write: / 'Hi'.
3  exit.
4  write: / 'There'.

The code in Listing 10.6 produces this output:

Hi

Exit prevents further processing, so the exit on line 3 prevents line 4 from being executed.

exit can be used in many situations. It can have varying effects depending on where it appears in the code. However, it always prevents further processing. Within loop structures, it leaves loop processing introduced by statements such as loop, select, do, and while. Within subroutines, it leaves subroutines introduced by FORM. Its effects in other situations will be fully explored as they arise.

Using the do Statement

The do statement is a basic loop mechanism.

Syntax for the do Statement

The following is the syntax for the do statement.

do [ v1 times ] [ varying f1 from s-c1 next s-c2 [ varying f2 from s2-c1 next s2-c2 ... ] ].
    ---
    [exit.]
    ---
    enddo.

where:

The following points apply:

Within the loop, sy-index contains the current iteration number. For example, the first time through the loop, sy-index will be 1. The second time through, sy-index will be 2, and so on. After enddo, sy-index contains the value it had before entering the loop. With nested do loops, sy-index contains the iteration number of the loop in which it is used (see Listing 10.7).


Listing 10.7  SY-INDEX Contains the Current Iteration Number

1  report ztx1007.
2  sy-index = 99.
3  write: / 'before  loop, sy-index =', sy-index, / ''.
4  do 5 times.
5      write sy-index.
6      enddo.
7  write: / 'after   loop, sy-index =', sy-index, / ''.
8
9  do 4 times.
10     write: / 'outer   loop, sy-index =', sy-index.
11     do 3 times.
12         write: / '  inner loop, sy-index =', sy-index.
13         enddo.
14     enddo.
15
16 write: / ''.                  "new line
17 do 10 times.
18     write sy-index.
19     if sy-index = 3.
20         exit.
21         endif.
22     enddo.

The code in Listing 10.7 produces this output:

before  loop, sy-index =         99
           1           2           3           4           5
after   loop, sy-index =         99
outer   loop, sy-index =          1
  inner loop, sy-index =          1
  inner loop, sy-index =          2
  inner loop, sy-index =          3
outer   loop, sy-index =          2
  inner loop, sy-index =          1
  inner loop, sy-index =          2
  inner loop, sy-index =          3
outer   loop, sy-index =          3
  inner loop, sy-index =          1
  inner loop, sy-index =          2
  inner loop, sy-index =          3
outer   loop, sy-index =          4
  inner loop, sy-index =          1
  inner loop, sy-index =          2
  inner loop, sy-index =          3
           1           2           3
TIP
On rare occasions the need arises to "kill time" in a program. You should not use an empty loop to accomplish this; you will burn up CPU needlessly if you do. Instead, you should call the function module rzl_sleep.

Changes made to the value of sy-index do not affect loop control. For example, if you code do 10 times and during the very first loop pass set the value of sy-index to 11, it will maintain that value until the enddo statement is executed. At that point, the value will be reset to 1, then incremented to 2, and the loop will continue processing as if you had not changed it at all.

Terminating an Endless Loop

There will be occasions when a program you run will loop endlessly. Listing 10.8 shows such a program.


Listing 10.8  An Endless Loop Can Be Frustrating If You Don't Know How to Break Out

1  report ztx1008.
2  do.
3      write sy-index.
4      if sy-index = 0.
5          exit.
6          endif.
7      enddo.

If you run this program, it will loop infinitely and that session will be clocked. Ending the SAPGUI task or even rebooting will not interrupt the program because it runs in a work process on the application server, not on your PC. If you reboot and then log on again, you will find that (if you were in the editor when you rebooted) you will not be able to even edit that program. Your logon session is still "out there" on the application server and it will still have the lock on your source code. After about five or ten minutes, your logon session will time out, and you will be able to edit your source code once again. However, the program could still be running in the work process, which slows the system down. Eventually, your program will consume the maximum amount of CPU allowed in your configuration and the work process will restart itself.

To terminate an endless loop, you must have at least two sessions open created via the menu path System->Create Session. You must start them before running your program. If you are in an infinite loop and do not have another session running, it is too late. Sessions created by logging on again will not work.

Start the ScreenCam "How to Terminate an Endless Loop" now.

To terminate an endless loop:

  1. When you first log on, chose the menu path System->Create Session.
  2. Minimize your new session and leave it in the background until you need it. You can now test programs with impunity.
  3. Now run a program that contains an endless loop, such as ztx1008. You see an hourglass when your pointer is over the window. Notice your session number in the status bar at the bottom of the window.
  4. Hold down the Alt key and press Tab successive times until the focus rests on the R3 icon representing your other session.
  5. Let go of the Alt key.
  6. Type /o in the Command field on the Standard toolbar.
  7. Press the Enter key. The Overview Of Sessions dialog box appears. It contains a list of your sessions. To the left of each is the associated session number.
  8. Find the session numer of the looping session, and click once on that line.
  9. Press the Debugging button.
  10. Switch back to the looping session using Alt+Tab. That session will now be stopped in the debugger. You can debug from here, or press the Exit button on the Application toolbar to end the program.

If the debugger did not show up and the session is still looping, you can end the entire session by repeating the procedure from step 6. Then, in step 9, instead of pressing the Debugging button, press the End Session button. This terminates the program and the session containing it. You will need to open another session to replace the one you terminated.

Using the varying Addition

Use the addition varying to obtain components of a field string in sequence. next establishes a distance (in bytes) between two components per iteration. The receiving component establishes the number of bytes to read from each component. This is best explained by example, as shown in Listing 10.9.


Listing 10.9  The Addition VARYING Returns the Components of a Field String in Sequence

1  report ztx1009.
2  data: f1,
3        begin of s,
4            c1 value 'A',
5            c2 value 'B',
6            c3 value 'C',
7            c4 value 'D',
8            c5 value 'E',
9            c6 value 'F',
10           end of s.
11
12 write / ''.
13 do 6 times varying f1 from s-c1 next s-c2.
14     write f1.
15     enddo.
16
17 write / ''.
18 do 3 times varying f1 from s-c1 next s-c3.
19     write f1.
20     enddo.

The code in Listing 10.9 produces this output:

  A B C D E F
  A C E

On line 13, next establishes a distance per iteration equal to the distance between c1 and c2. The length of f1 determines the number of bytes to read from each component. Do then begins at s-c1, and assigns its value to f1. On successive loop passes, the previously established distance is added to the address of the current component, causing successive values to be assigned from s to f1.

All components of s accessed by the do loop must be separated by exactly the same number of bytes. Data conversion is not performed on assignment to f1.

CAUTION
It is possible to read past the end of the structure, but doing so can result in unpredictable behavior and even in program termination. You must either specify the addition times to limit the number of loop passes or use an exit statement to leave the loop before reading past the end of the field string.

Some tables in R/3 are not completely normalized. Instead of having multiple records, a single record might contain a series of fields repeated in succession. You can use varying to retrieve these values in sequence.

For example, table lfc1 contains Vendor Master transaction figures. Fields umNNs, umNNh, and umNNu contain the total debit and credit postings for a month and the sales in the posting period. This group of fields is repeated 16 times for each record in this table (NN is a sequential number from 01 to 16). Table knc1 contains a similar sequence of fields. In another example, table mvke contains, within include envke, 10 fields for product attributes: prat1 through prata. They are side by side, making them an equal distance apart, and thus able to be accessed with varying.

A more complex example of the use of varying is shown in Listing 10.10.


Listing 10.10  The Addition VARYING Can Appear More Than Once on the DO Statement

1  report ztx1010.
2  data: f1    type i,
3        f2    type i,
4        tot1  type i,
5        tot2  type i,
6        begin of s,
7            c1 type i value 1,
8            c2 type i value 2,
9            c3 type i value 3,
10           c4 type i value 4,
11           c5 type i value 5,
12           c6 type i value 6,
13           end of s.
14
15 do 3 times varying f1 from s-c1 next s-c3
16            varying f2 from s-c2 next s-c4.
17     write: / f1, f2.
18     add: f1 TO tot1,
19          f2 to tot2.
20     enddo.
21 write: / '---------- -----------',
22        / tot1, tot2.

The code in Listing 10.10 produces this output:

         1           2
         3           4
         5           6
---------- -----------
         9          12

F1 is assigned every other component from s beginning with s-c1, and f2 is assigned every other component beginning with s-c2.

Modifying Values within do ... varying/enddo

You can modify the value of either f1 or s within the do ... varying/enddo loop. When the enddo statement is executed, the current value of f1 value is copied back to the component it came from, whether it was modified or not. In Listing 10.11, report ztx1011 illustrates this functionality.


Listing 10.11  The Current Value of F1 Is Written Back to the Sending Component When ENDDO Is Executed

1  report ztx1011.
2  data: f1 type i,
3        begin of s,
4            c1 type i value 1,
5            c2 type i value 2,
6            c3 type i value 3,
7            c4 type i value 4,
8            c5 type i value 5,
9            c6 type i value 6,
10           end of s.
11 field-symbols <f>.
12
13 write / ''.
14 do 6 times varying f1 from s-c1 next s-c2.
15     if sy-index = 6.
16         s-c6 = 99.
17     else.
18         f1 = f1 * 2.
19         endif.
20     assign component sy-index of structure s to <f>. "<f> now points to
21     write <f>.                                       "a component of s
22     enddo.
23
24 write / ''.
25 do 6 times varying f1 from s-c1 next s-c2.
26     write f1.
27     enddo.

The code in Listing 10.11 produces this output:

      1           2           3           4           5          99
      2           4           6           8          10           6

An exit statement within the loop will not prevent the modified contents of f1 from being written back to the sending field. The only way to leave the loop without the contents of f1 overwriting the sending field is by executing a stop statement or an error message statement within the loop (both covered in later chapters).

Using the while Statement

The while statement is a looping mechanism similar to do.

Syntax for the while Statement

The following is the syntax for the while statement.

while exp [ vary f1 from s-c1 next s-c2 [ vary f2 from s2-c1 next s2-c2 ... ]
    ---
    [ exit. ]
    ---
    endwhile.

where:

The following points apply:

while is very similar to do. Here, it is used to place an equal number of dashes on either side of a string.


Listing 10.12  An Example of the Use of the WHILE Statement

1  report ztx1012.
2  data: l,                         "leading  characters
3        t,                         "trailing characters
4        done.                      "done flag
5  parameters p(25) default '    Vendor Number'.
6  while done = ' '                 "the expression is evaluated first
7      vary l from p+0  next p+1    "then vary assignments are performed
8      vary t from p+24 next p+23.
9      if l = ' ' and t = ' '.
10         l = t = '-'.
11     else.
12         done = 'X'.
13         endif.
14     endwhile.
15 write: / p.

The code in Listing 10.12 produces this output:

----Vendor Number    ----

Using the continue statement

The continue statement is coded within a loop. It acts like a goto, passing control immediately to the terminating statement of the loop and beginning a new loop pass. In effect, it causes the statements below it within the loop to be ignored and a new loop pass to begin. The effect of the continue statement is shown in Figure 10.1.

Figure 10.1 : The continue statement jumps to the end of the loop, ignoring all statements after it for the current loop pass.

The code in Figure 10.1 produces this output:

1 2 9 10

Syntax for the continue Statement

The following is the syntax for the continue statement. It can be used within a do, while, select, or loop. (The loop statement is covered in the next chapter.)

[do/while/select/loop]
    ---
    continue.
    ---
    [enddo/endwhile/endselect/endloop]

where:

The following points apply:

Listing 10.13 is like a goto statement. It causes a jump to the end of the current loop. This program removes duplicate colon and backslash characters from an input string.


Listing 10.13  An Example of the Use of the CONTINUE Statement

1  report ztx1013.
2  parameters p(20) default 'c::\\\xxx\\yyy'.
3  data: c,                    "current character
4        n.                    "next    character
5
6  do 19 times varying c from p+0 next p+1
7              varying n from p+1 next p+2.
8      if c na ':\'.
9          continue.
10         endif.
11     if c = n.
12         write: / 'duplicate', c, 'found', 'at position', sy-index.
13         endif.
14     enddo.

The code in Listing 10.13 produces this output:

duplicate : found at position          2
duplicate \ found at position          4
duplicate \ found at position          5
duplicate \ found at position         10

Using the check statement

The check statement is coded within a loop. It can act very much like continue, passing control immediately to the terminating statement of the loop and bypassing the statements between. Unlike continue, it accepts a logical expression. If the expression is true, it does nothing. If it is false, it jumps to the end of the loop. The effect of the check statement is shown in Figure 10.2.

Figure 10.2 : The check statement is a conditional continue statement. It jumps to the end of the loop if the logical expression is false.

The code in Figure 10.2 produces the same output as that in Figure 10.1:

1 2 9 10

Syntax for the check Statement

The following is the syntax for the check statement. It can be used within a do, while, select, or loop. (The loop statement is covered in the next chapter.)

[do/while/select/loop]
    ---
    check exp.
    ---
    [enddo/endwhile/endselect/endloop]

where:

In listing 10.14, check behaves like a continue statement when the logical expression is false. When it is true, it does nothing.


Listing 10.14  Listing 10.3 Was Re-coded to Use the CHECK Statement Instead of CONTINUE

1  report ztx1014.
2  parameters p(20) default 'c::\\\xxx\\yyy'.
3  data: c,                    "current character
4        n.                    "next    character
5
6  do 19 times varying c from p+0 next p+1
7              varying n from p+1 next p+2.
8      check c ca ':\'.
9      if c = n.
10         write: / 'duplicate', c, 'found', 'at position', sy-index.
11         endif.
12     enddo.

The code in Listing 10.14 produces this output:

duplicate : found at position          2
duplicate \ found at position          4
duplicate \ found at position          5
duplicate \ found at position         10

Lines 8 through 10 in Listing 10.13 were replaced by line 8 in Listing 10.14. The program works in exactly the same way.

TIP
Using check or continue within a select loop can be very inefficient. You should, whenever possible, modify the where clause to select fewer records instead.

Comparing the exit, continue, and check Statements

In Table 10.7, the exit, continue, and check statements are compared.

Table 10.7  Comparing EXIT, CONTINUE, and CHECK
Statement
Effect
exitLeaves the current loop.
continueUnconditional jump to the end of the loop.
check exp Jumps to the end of the loop if exp is false.

Simple Position and Length Specifications for the write Statement

The write statement permits specification of an output position and length.

Although the write statement permits many complex specifications, elementary position and length specifications are presented here to enable you to create basic reports in this and in the following chapter. A detailed treatment of the write statement appears later in chapter 14.

Syntax for Simple Position and Length Specifications on the write Statement

The following is the syntax for simple position and length specifications on the write statement.

write [/][P][(L)] v1.

where:

The following points apply:

Table 10.8 shows the right and wrong ways to code position and length specifications on the write statement.

Table 10.8  Right and Wrong Ways to Code Position and
Length Specifications on the
WRITE Statement
RightWrong
write /10(2) 'Hi'.write / 10(2) 'Hi'.
 write / 10 (2) 'Hi'.
 write /10 (2) 'Hi'.
 write /10( 2) 'Hi'.
 write /10( 2 ) 'Hi'.
Write (2) 'Hi'.write ( 2 ) 'Hi'.
 write 'Hi'(2).
Write 10 'Hi'.write 10'Hi'.
 write 'Hi' 10.

TIP
If you leave a space between a / and the position or length specification, the syntax checker can automatically correct it for you. Simply press the Correct button at the bottom of the message window when it appears.

Listing 10.15 illustrates the use of simple position and length specifications on the write statement. It also shows some of the pitfalls. Line 3 writes out a ruler so that you can see column numbers on the output.


Listing 10.15  Use of Simple Position and Length Specifications on the WRITE Statement

1  report ztx1015.
2  data: f1 type p value 123,
3        f2 type p value -123.
4  write: / '....+....1....+....2....+....3....+....4',
5         /1    'Hi', 4     'There',
6         /1    'Hi', 3     'There',
7         /1    'Hi', 2     'There',
8         /1    'Hi', 1     'There',
9         /2    'Hi',       'There',
10        /2(1) 'Hi',       'There',
11        /2(3) 'Hi',       'There',
12        /2    'Hi', 10(3) 'There',
13        /     f1,         f2,
14        /     f1,   4     f2,
15        /(3)  f1,
16        /(2)  f1.

The code in Listing 10.15 produces this output:

....+....1....+....2....+....3....+....4
Hi There
HiThere
HThere
There
 Hi There
 H There
 Hi  There
 Hi      The
            123              123-
               123-
123
*3

Summary

DO
DON'T
DO open two sessions whenever you log on so that you can terminate an infinite loop.

DO use varying to read a series of equidistant fields from a field string.

DON'T use check or continue within a select loop to filter out records. Instead, use the where clause to filter them out.

DON'T read past the end of a variable or field string with the varying addition. Protection exceptions and unpredictable behavior can result.

Q&A

Q
Why aren't bit operations used much in ABAP/4? What does it use instead?
A
The use of a bit operation creates an operating system dependency. This reduces portability, so they are not used unless necessary. Instead, a single character variable is used to hold a single on/off value. Most commonly, "X" represents an "on" value and space represents an "off" value.
Q
Why do they use X and space to represent the binary values of on and off? I should think they would use 1/0, T/F, or Y/N, as is common in the industry.
A
This convention is for compatibility with character-based user interfaces. Written out, the X value indicates a present selection, and space indicates not present.
Q
You recommend opening multiple sessions whenever I log on. Isn't this a waste of resources? If everyone did that, wouldn't it slow the application server down?
A
The most precious resource is CPU. It is true that a small amount of additional memory is required on the application server to accommodate each new session. However, no CPU is used by the idle session, so it does not slow the server down. If you write a program that begins looping, it will waste a tremendous amount of resources, primarily CPU, and will without a doubt degrade the server while it is running. If you are unable to stop it, you will be unable to mitigate the waste of resources. Unchecked, the program will run, possibly for five or ten minutes, until it exceeds its allotment of CPU and then it will be terminated. The next time you run it, it might do the same again. In short, opening another session is choosing the lesser of two evils.
Q
How do padding bytes affect the use of varying? Do I have to watch out for anything as I do when moving from and to field strings?
A
The easiest way to ensure that varying will work is to make sure the exact sequence of fields repeats. If the same sequence of fields is repeated, the same number of bytes will always separate them. As long as you follow this rule, there is no need to think about padding bytes.
Q
Can I use a variable to indicate position and/or length on a write statement?
A
Yes. The write statement is presented in detail in chapter 14 and variable specifications are covered there.

Workshop

The Workshop provides two ways for you to affirm what you've learned in this chapter. The Quiz section poses questions to help you solidify your understanding of the material covered and the Exercise section provides you with experience in using what you have learned. You can find answers to the quiz questions and exercises in Appendix B, "Answers to Quiz Questions and Exercises."

Quiz

  1. In the following section of code, change the if statements into a case statement.
if v1 eq 5.
write 'The number is five.'.
endif.
if v1 eq 10.
write 'The number is ten.'.
endif.
if v1 <> 5 and v1 <> 10.
write 'The number is not five or ten.'.
endif.

  1. Which string comparison operators use the three characters *, +, and #?
  2. What are the three program control statements discussed in this chapter? What are the differences between them?

Exercise 1

Write a program that produces the output in the Figure 10.3.

Figure 10.3 : .

Do not hardcode as strings. Instead, compute the numbers and either write them out a single byte at a time or use the syst table.