Day 20

Modularization: Function Modules, Part 2


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

Defining Global Data for Function Modules

Two types of global data can be defined for a function module:

The global data defined within the top include is accessible from all function modules within the group. It is analogous to the global data definitions at the top of an ABAP/4 program.

The parameters defined within a global interface are accessible from all subroutines called from the function module. It is analogous to variables defined within a subroutine using the locals statement.

The parameters defined within a local interface are inaccessible from subroutines called from the function module. It is analogous to variables defined within a subroutine using the data statement. By default, interfaces are local.

To make an interface global, from the Function Module Change: Import/Export Parameters screen, choose the menu path Edit->Globalize Parameters. To make it local again, choose the menu path Edit->Localize Parameters.

CAUTION
If a parameter with the same name exists in two function modules within a group and both interfaces are global, the data definitions of both of these parameters must be identical.

Global data defined within the top include is allocated when a program makes its first call to any function module of a group. It remains allocated as long as the calling program remains active. Each subsequent call to a function module within the same group sees the previous values within the global data area. The values in the global data area persist until the calling program ends.

Global data defined by making the interface global is reinitialized each time the function module is called.

Listings 20.1 through 20.4 illustrate the persistence of global data defined within the top include.


Listing 20.1  This Program Illustrates the Persistence of Global Data

 1 report ztx2001.
 2 parameters parm_in(10) default 'XYZ' obligatory.
 3 data f1(10) value 'INIT'.
 4
 5 perform: call_fm12,
 6          call_fm13.
 7 write: / 'f1 =', f1.
 8
 9 *_____________________________________________________________________
10 form call_fm12.
11   call function 'Z_TX_2002'
12        exporting
13             p_in    = parm_in
14        exceptions
15             others  = 1.
16   endform.
17
18 *_____________________________________________________________________
19 form call_fm13.
20   call function 'Z_TX_2003'
21        importing
22             p_out   = f1
23        exceptions
24             others  = 1.
25   endform.


Listing 20.2  This Is the Source Code of the First Function Module Called from Listing 20.1

1  function z_tx_2002.
2  *"------------------------------------------------------------
3  *"*"Local interface:
4  *"       IMPORTING
5  *"             VALUE(P_IN)
6  *"------------------------------------------------------------
7  g1 = p_in.
8  endfunction.


Listing 20.3  This Is the Source Code of the Second Function Module Called from Listing 20.1

1  function z_tx_2003.
2  *"------------------------------------------------------------
3  *"*"Local interface:
4  *"       EXPORTING
5  *"             VALUE(P_OUT)
6  *"------------------------------------------------------------
7  p_out = g1.
8  endfunction.


Listing 20.4  This Is the Top INCLUDE for the Function Group ZTXB-ZTXB Contains the Function Modules Shown in Listings 20.2 and 20.3

1  function-pool ztxb.
2  data g1(10).

The code in Listings 20.1 through 20.4 produce this output:

f1 = XYZ

Passing an Internal Table to a Function Module

Passing an internal table to a function module follows the same rules as that of passing an internal table to a subroutine. There are two methods:

To return an internal table that originates from within a function module, use one of the following:

Passing an Internal Table Via tables

If you use the tables portion of the interface, you can pass the internal table together with the header line. If it doesn't have a header line, it will automatically acquire one within the function module. tables parameters are always passed by reference.

To use this method, from the Function Library Initial Screen, choose the Table Parameters/Exceptions Interface radio button and then press the Change pushbutton. You will see the Table Parameters/Exceptions screen. In the upper-half of the screen under the Table Parameters column, type the names of internal table parameters.

If the internal table is a structured type, in the Ref. Structure column, you can optionally type the name of a DDIC structure. Only DDIC structure names can be entered here. If you don't specify a DDIC structure here, you will not be able to access any of the components of the internal table within the function module. To do so will cause a syntax error.

If the internal table is not a structured type, you can enter an ABAP/4 data type in the Reference Type column instead.

Passing an Internal Table Via exporting/importing and changing

If you use the exporting/importing or changing part of the interface, you can pass the body of an internal table only. However, these parts of the interface enable you to choose whether to pass the internal table body by value (the default) or by reference. When using this method, you must specify table in the Reference Type column.

Figures 20.1 and 20.2 and Listings 20.5 and 20.6 illustrate the ways of passing internal tables to a function module.

Figure 20.1 : The Import/Export Parameters screen showing how to pass the body of the internal table.

Figure 20.2 : The Table Parameters/ Exceptions screen showing how to pass an internal table together with its header line.


Listing 20.5  This Program Passes Internal Tables to a Function Module

 1 report ztx2005.
 2 tables ztxlfa1.
 3 data: it_a like ztxlfa1 occurs 3,   "doesn't have a header line
 4       it_b like ztxlfa1 occurs 3.   "doesn't have a header line
 5 select * up to 3 rows from ztxlfa1 into table it_a.
 6
 7 call function 'Z_TX_2006'
 8      exporting
 9           it1     = it_a[]
10      importing
11           it2     = it_b[]
12      tables
13           it4     = it_a
14      changing
15           it3     = it_a[]
16      exceptions
17           others  = 1.
18
19 write: / 'AFTER CALL',
20        / 'IT_A:'.
21 loop at it_a into ztxlfa1.
22     write / ztxlfa1-lifnr.
23     endloop.
24 uline.
25 write / 'IT_B:'.
26 loop at it_b into ztxlfa1.
27     write / ztxlfa1-lifnr.
28     endloop.


Listing 20.6  This Is the Source Code for the Function Module Called from Listing 20.5

1  function z_tx_2006.
2  *"------------------------------------------------------------
3  *"*"Local interface:
4  *"       IMPORTING
5  *"             VALUE(IT1) TYPE  TABLE
6  *"       EXPORTING
7  *"             VALUE(IT2) TYPE  TABLE
8  *"       TABLES
9  *"             IT4 STRUCTURE  LFA1
10 *"       CHANGING
11 *"             VALUE(IT3) TYPE  TABLE
12 *"------------------------------------------------------------
13 data wa like lfa1.
14 write / 'IT1:'.
15 loop at it1 into wa.
16     write / wa-lifnr.
17     endloop.
18 loop at it3 into wa.
19     wa-lifnr = sy-tabix.
20     modify it3 from wa.
21     endloop.
22 uline.
23 write: / 'IT4:'.
24 loop at it4.
25     write / it4-lifnr.
26     endloop.
27 uline.
28 it2[] = it1[].
29 endfunction.

The code in Listings 20.5 and 20.5 produce this output:

------------
IT1:             
1000             
1010             
1020             
------------
IT4:             
1000             
1010             
1020             
------------
AFTER CALL       
IT_A:            
1                
2                
3                
------------
IT_B:            
1000             
1010             
1020         

Defining Subroutines in a Function Group

You can call internal and external subroutines from within function modules. Calls to external subroutines are the same for function modules as they are for reports. Internal subroutines should be defined within a special include: the F01.

The F01 is included into the function group by editing the main program and inserting the statement include LfgidF01. Then, double-clicking on the name of the include will create it automatically. Within it, you can put subroutines accessible by all function modules within the group. There is, however, an easier way.

The easiest way to define the F01 is to code your call to the subroutine and then double-click on the subroutine name on the perform statement. The following procedure illustrates this process.

Start the ScreenCam "How to Create Subroutines within a Function Group" now.

  1. Start from the Function Library: Initial Screen.
  2. Select the Source Code radio button.
  3. Press the Change pushbutton. The Function Module: Edit screen is shown.
  4. Type a perform statement in the source code of the function module. For example, perform sub1.
  5. Double-click on the subroutine name. In this example, you would double-click on sub1. The Create Object dialog box appears, asking you if you want to create the subroutine.
  6. Press the Yes button. The Create Subroutine dialog box appears. The subroutine name appears in the Subroutine field. The include name lfgidf01 appears in the Include Choice box, and the radio button to its left is automatically selected.
  7. Press the Continue button (the green checkmark). A Warning dialog box appears, indicating the main program will be modified and an include lfgidf01 statement will be inserted into it.
  8. Press the Continue button (the green checkmark). You see the Exit Editor dialog box indicating that your source code has changed and asking you if you want to save the changes.
  9. Press the Yes button. The Function Module Editor screen is shown. You are now editing the F01. Code the subroutine here.
  10. When you have finished coding your subroutine, press Save and then Back. You are returned to the function module's source code where you began.

To see the include you just created, return to the Function Library Initial screen. Choose the Main Program radio button and press the Change button. You will see the Function Module: Edit screen. At the bottom will be the include lfgidf01 statement. This statement was inserted by step 7 of the above procedure. If you double-click on this line, you will see your subroutine.

Releasing a Function Module

The release function adds a level of protection to the interface of a function module by protecting it from modification. If you have completed testing of your function module, you might want to release it to indicate that it is safe for other developers to use in their code. By doing so, you are essentially promising not to change the existing interface parameters in any way that would cause problems to any programs that will call your function module. You are promising interface stability.

For example, after releasing a function module, you shouldn't add a required parameter, change the proposals, or remove a parameter. If you did, any existing calls to your function module might fail or work differently.

After releasing, you can still change the interface, but you need to take an extra step to do it.

To release a function module, use the following procedure.

Start the ScreenCam "How to Release a Function Module" now.

  1. Begin at the Function Library Initial Screen.
  2. Choose the Administration radio button.
  3. Press the Change pushbutton. The Function Module Change: Administration screen is shown. In the bottom right corner of the screen, at the bottom of the General Data box, you will see Not Released.
  4. Choose the menu path Function Module->Release->Release. The message Released appears at the bottom of the window in the status bar. In the bottom right corner of the window, Not Released changes to Customer Release On and is followed by the current date.

If you try to change the interface after the function module has been released, the input fields on the interface screen will be grayed out. The message Function module has been released will also appear at the bottom of the window. However, if you want to change the interface, you only need to press the Display <-> Change button and you will be allowed to change it in any way you want. Remember, however, that you should not make changes that can cause existing programs to abnormally terminate or return different results.

TIP
If you accidentally release a function module and want to cancel the release, go to the Function Module Display: Administation screen, press the Display <->Change button, and choose the menu path Function Module->Release ->Cancel Release. After choosing this menu path, press the Enter key to com-plete the cancellation process.

Testing a Function Module

If you want to test a function module without writing an ABAP/4 program, you can do it using the test environment within the Function Library. Use the following procedure to access the test environment.

Start the ScreenCam "How to Use the Test Environment for Function Modules" now.

  1. Begin at the Function Library: Initial Screen. Type the name of the function module you want to test in the Function Module field.
  2. Press the Test pushbutton. You will see the Test Environment For Function Modules screen (shown in Figure 20.3).
    Figure 20.3 : The Test Environment for Function Modules screen.
  3. Type the parameters you want to supply for the test. To fill an internal table, double-click on the internal table name. A screen will be shown that enables you to enter data into the internal table. (If you specified a Ref. Structure for the internal table, the columns of the structure will be shown.) Type your data and press the Enter key. You will be returned to the Test Environment For Function Modules screen.
  4. Press the Execute button on the Application toolbar to execute the function module. You will see the Test Function Module: Result Screen (see Figure 20.4). The output from write statements within the function module appear first. In Figure 20.4, You passed A is the result of a write statement within the function module. Then, the length of time taken to execute the function module (in microseconds) is shown. Following that, the values of the parameters are shown, and the changing and tables parameters have two values: the before and after. For changing parameters, the "before" value is shown first and the "after" value appears below it. For tables parameters, the "after" contents appear above the "before" (original) contents. In Figure 20.4, internal table it contained two lines after processing and three lines before. To see the before or after contents of the internal table, double-click on either line.
    Figure 20.4 : The Test Function Module: Result screen showing the before and after values for the changing and tables parameters.

TIP
To save your test data and/or results, press the Save button either on the Test Environment screen or on the Result screen. To retrieve your saved information, press the Test Data Directory button on either screen. Test sequences can also be built using the Test Sequence button.

Finding Existing Function Modules

As stated before, SAP supplies more than 5,000 pre-existing function groups containing more than 30,000 function modules. Often the functionality you require is already covered by these SAP-supplied function modules-you only need to find the right one. To find an existing function module, use the Repository Information system. The following procedure shows you how.

Start the ScreenCam "How to Search for Function Modules" now.

  1. From the ABAP/4 Development Workbench screen, choose the menu path Overview -> Repository Infosys. You see the ABAP/4 Repository Information System screen shown in Figure 20.5.
    Figure 20.5 : The ABAP/4 Repository Information System screen as it appears initially.
  2. Expand the Programming line by clicking on the plus sign (+) to the left of it. A subtree is shown below it.
  3. Expand the Function Library line by clicking on the plus sign (+) to the left of it. A subtree is shown below it. Your screen should now look like Figure 20.6.
    Figure 20.6 : The ABAP/4 Repository Information System screen with the Function Modules left exposed.
  4. Double-click on the Function Modules line. The ABAP/4 Repository Information System: Function Module screen is shown. Press the All Selections button on the Application toolbar to display all possible selection fields. Your screen should now appear as shown in Figure 20.7. This is a selection screen in which you can enter search criteria for finding function modules. All fields are case-insensitive with the exception of the Short Description field, which is case sensitive!
    Figure 20.7 : The ABAP/4 Repository Information System: Function Module screen with all selections shown.
  5. To search for a function module, either words or character strings might be entered in the search fields. Use + and * as wildcard characters. + will match any single character, and * will match any sequence of characters. For example, enter *DATE* in the Function Module field. This will find all function modules that contain the characters DATE anywhere in their name. Or, you might either enter *Date* or *date* in the short description field (only one string is allowed in this field).
  6. To enter more than one value to search for, press the arrow at the end of the field. The Multiple Selection screen is shown (see Figure 20.8). The values you enter on this screen are ORed together. Type multiple selection criteria here. These values are known as the included values, or simply the "includes." (This is a different usage of the term than when it refers to include programs.)
    Figure 20.8 : The Multiple Selection screen.
  7. Press the Options button to specify selection operators such as equal, not equal, greater than, less than, and so on. You will see the Maintain Selection Options screen, as shown in Figure 20.9. To be able to specify Pattern or Exclude Pattern, your value must contain a pattern-matching character: either + or *. Press the Copy button to return to the Multiple Selection screen.
    Figure 20.9 : The Maintain Selection Options screen.
  8. On the Multiple Selection screen, press the Complex Selection button. The Multiple Selection screen is reshown, but this time there is a scroll bar on the right side and Ranges fields appear (see Figure 20.10). To specify values that should be excluded from the search, scroll down and enter them within the box titled ...But Not (see Figure 20.11). These values are known as the excluded values, or more simply, the excludes.
    Figure 20.10: The Multiple Selection screen with a scroll bar on the right side and Ranges fields.
    Figure 20.11: The ...But Not box.
  9. Press the Copy button to copy your selection criteria back to the selection screen. You are returned to the ABAP/4 Repository Information System screen, and if you entered multiple selection criteria, the arrow at the end of the line is green to show that more than one selection criterion exists (see Figure 20.12).
    Figure 20.12: The ABAP/4 Repository Information System screen. The green arrow at the end of the line shows that more than one selection criterion exists.
  10. To begin the search, press the Execute button. The search results are determined as if separate searches had been done for all of the include criteria, and then the results ORed together. Then, if excludes have been specified, they are applied one entry after the other. For example, in the Short Description field, suppose you specified the includes *Date* and *date* and excludes of *Update* and *update*. All of the descriptions containing *Date* will be found, and then all of the descriptions contains *date* will be ORed with the first result set. Then all of the descriptions containing *Update* will be removed, and then all of those containing *update* will be removed. The result will contain the strings "Date" or "date" without "Update" and "update." You see the results on the Function Modules screen (see Figure 20.13). The number of function modules found is indicated in the title bar within parentheses.
    Figure 20.13: The Function Modules screen.
  11. To display a function module, double-click on it. The Function Module Display: Documentation screen is shown (see Figure 20.14). This screen shows you all the interface parameters and their documentation. To see more documentation, double-click on a parameter name (see Figure 20.15). To return to the interface documentation, press the Back button. To return to the function module list, press the Back button again.
    Figure 20.14: The Function Module Display: Documentation screen.
    Figure 20.15: The additional documentation for a parameter.

NOTE
Not all parameters have additional documentation. If the parameter you double-clicked on doesn't have any more documentation, nothing happens when you double-click on it.

TIP
If, when you look at the title bar on the Function Modules screen, the number of function modules found is exactly 500, then you have probably hit the maximum list size. Return to the selection screen and look in the Maximum No. of Hits field. If it is also 500, you hit the maximum. You might be tempted to increase the maximum number of hits, but this will rarely be productive because you probably won't read an entire list of 500 function modules. Refine your search criteria to reduce the number of hits.

  1. To test a function module, put your cursor on it and press the Test/Execute button (it looks like a little monkey wrench). You will be shown the Test Environment Screen for that function module.

Exploring the Components of your Function Group

After creating your first function module, use the following procedure and take a few minutes to explore the components of the function group. You should become familiar with the structure that you have just created.

Start the ScreenCam "Exploring the Components of Your Function Group" now.

  1. Begin on the Function Library Initial Screen. If it is not already there, type the name of your function module in the Function Module field.
  2. Choose the Administration radio button and then press the Change pushbutton. The Function Module Change: Administration screen is displayed (see Figure 20.16). At the top of the screen in the Function Group field you can see the ID of the function group to which this function module belongs. In the bottom right corner in the Program field, you can see the name of the main program for the function group. In the Include field is the name of the include that contains the source code for the function module. The last field shows the status of the function module: Active or Inactive. Press the Back button to return to the Function Library Initial Screen.
    Figure 20.16: This is the way the Function Module Create: Administration screen appears after the function module has been created.
  3. Choose the Import/Export Parameter Interface radio button and then press the Change pushbutton. The Import/Export Parameters screen is shown. Press the Back button to return to the Function Library Initial Screen.
  4. Choose the Table Parameters/Exceptions Interface radio button and then press the Change pushbutton. The Function Module Change: Table Parameters/Exceptions screen is shown. Here you can enter or change internal table parameters and exception names. Press the Back button to return.
  5. Choose the Documentation radio button and then press the Change pushbutton. The Function Module Change: Documentation screen is shown. Here you can enter a short description for each parameter and exception in the interface. Press the Back button to return.
  6. Choose the Source Code radio button and then press the Change pushbutton. The Function Module: Edit screen is shown. Press the Back button to return.
  7. Choose the Global Data radio button and then press the Change pushbutton.
    The Function Module: Edit screen is shown. This time, however, you are editing the top include. Notice the name of the top include in the title bar. It conforms to the naming convention lfgidtop, where fgid is the name of your function group. Here you can define global variables and tables work areas that are common to all function modules within the function group. If your function modules use the message statement, you can also define the default message class (on the function-pool statement). Press the Back button to return.
  8. Choose the Main Program radio button and press the Change pushbutton. The Function Module: Edit screen is shown. This time, you are editing the main program (refer to Figure 20.17). Notice the name within the title bar begins with sapl followed by your function group ID. The two include statements incorporate the top include and the UXX into the main program. Double-clicking on the top include name will enable you to edit it. Press the Back button to return to the main program. Double-clicking on the UXX will display the include program source code-it contains the statements that include the function modules into the group. Their names are indicated within comments at the end of each include statement. You are not allowed to modify the UXX. Double-clicking on any of the include statements will display the source code for a function module within the group. Press the Back button to return.

Figure 20.17: This is the main program for the z_tx_div function module.

TIP
To copy, rename, or delete a function module, use the Copy, Rename, or Delete buttons on the Function Library: Initial Screen.

Finding and Fixing Errors in Function Modules

The easiest way to fix errors in a function module is to perform a syntax check when you are within the function module. You can do this on the Function Module Edit screen by pressing the Check button on the Application toolbar. Right now, you have only created one function module, so you know where to look if it doesn't work.

However, after you create many function modules, you might end up in the position where you are calling one or more function modules within a group and the system is telling you there is a syntax error somewhere. The error message you might see appears in a SAP R/3 dialog box such as the one shown in Figure 20.18.

Figure 20.18: A syntax error detected at runtime within a function module.

Within this SAP R/3 dialog box is enough information to pinpoint the exact location and cause of the error. In Figure 20.18, the first field contains the program name lztxau02. This is the include program that contains the error. The second field tells you that the error occurred on line 10. At the bottom of the dialog box is the actual error. In this case the error reads "." expected after "P2".

To fix the error, use the following procedure.

Start the ScreenCam "How to Fix an Error in a Function Module" now.

  1. Begin at the ABAP/4 Editor: Initial Screen (transaction SE38).
  2. In the Program field, type the program name from the first field of the dialog box, in this case lztxau02.
  3. Press the Change pushbutton. This will show you the function module source code that contains the error.
  4. Press the Check button on the Application toolbar. You should see the same error that was shown at the bottom of the SAP R/3 dialog box.
  5. Correct the error. Often, you can simply press the Correct button and the system will automatically correct the error for you.

Setting the Value of sy-subrc on Return

Normally, after returning from a function module, the system automatically sets the value of sy-subrc to zero. Use one of the following two statements to set sy-subrc to a non-zero value:

Using the raise Statement

Use the raise statement to exit the function module and set the value of sy-subrc on return.

Syntax for the raise Statement

The following is the syntax for the raise statement.

raise xname.

where:

The following points apply:

When the raise statement is executed, control returns immediately to the call function statement and a value is assigned to sy-subrc based on the exceptions you have listed there. Values assigned to export parameters are not copied back to the calling program. Listings 20.7 and 20.8 and Figure 20.19 illustrate how this happens.

Figure 20.19: This illustrates raise statement processing.

NOTE
The code in the function module shown in Listing 20.8 is merely for sake of example; normally there would also be some code that does some real processing in there also.


Listing 20.7  How to Set the Value of SY-SUBRC from Within a Function Module

 1 report ztx2007.
 2 parameters parm_in default 'A'.
 3 data vout(4) value 'INIT'.
 4 call function 'Z_TX_2008'
 5     exporting
 6         exname = parm_in
 7     importing
 8         pout   = vout
 9     exceptions
10         error_a = 1
11         error_b = 4
12         error_c = 4
13         others  = 99.
14 write: / 'sy-subrc =', sy-subrc,
15        / 'vout =', vout.


Listing 20.8  This Is the Function Module Called from Listing 20.7

 1 function z_tx_2008.
 2 *"------------------------------------------------------------
 3 *"*"Local interface:
 4 *"       IMPORTING
 5 *"             VALUE(EXNAME)
 6 *"       EXPORTING
 7 *"             VALUE(POUT)
 8 *"       EXCEPTIONS
 9 *"              ERROR_A
10 *"              ERROR_B
11 *"              ERROR_C
12 *"              ERROR_X
13 *"------------------------------------------------------------
14 pout = 'XXX'.
15 case exname.
16   when 'A'. raise error_a.
17   when 'B'. raise error_b.
18   when 'C'. raise error_c.
19   when 'X'. raise error_x.
20   endcase.
21 endfunction.

The code in Listings 20.7 and 20.8 produce this output, if you specify a value of A for parm_in:

sy-subrc =     1  
vout = INIT       

The special name others on line 13 of Listing 20.7 will match all exceptions not explicitly named on the exceptions addition. For example, if line 7 of Listing 20.8 were executed, exception error_x would be raised. This exception is not named in Listing 20.7, so others will match and the value of sy-subrc will be set to 99. You can code any numbers you want for exception return codes.

CAUTION
If you do not code others and an exception is raised within the function module that is not named on the exceptions addition, the program will be aborted and a short dump will result that has the runtime error RAISE_EXCEPTION.

If an export parameter is passed by value, after a raise its value remains unchanged in the calling program even if a value was assigned within the function module before the raise statement was executed. If the parameter was passed by reference, it will be changed in the caller (it has the Reference flag turned on in the Export/Import Parameters screen). This effect is shown in Listing 20.7. The value of pout is changed in the function module and, if a raise statement is executed, the changed value is not copied back into the calling program.

NOTE
check, exit, and stop have the same effect with function modules as they do in external subroutines. However, they should not be used within function modules. Instead, the raise statement should be used because it enables the caller to set the value of sy-subrc on return.

Using the message ... raising Statement

The message ... raising statement has two modes of operation:

Syntax for the message ... raising Statement

The following is the syntax for the message ... raising statement

message tnnn(cc) [with v1 v2 ...] raising xname

where:

The following points apply:

When the message ... raising statement is executed, the flow of control depends on the message type and whether the condition is handled by the caller (specified in the exceptions list in the calling program).

Listings 20.9 and 20.10 illustrate the effect of the message ... raising statement.


Listing 20.9  Using the MESSAGE ... RAISING Statement

 1 report ztx2009.
 2 parameters: p_etype default 'E',    "enter message types E W I S A X
 3             p_handle default 'Y'.   "if Y, handle the exception
 4 data vout(4) value 'INIT'.
 5
 6 if p_handle = 'Y'.
 7     perform call_and_handle_exception.
 8 else.
 9     perform call_and_dont_handle_exception.
10     endif.
11 write: / 'sy-subrc =', sy-subrc,
12        / 'vout =', vout,
13        / 'sy-msgty', sy-msgty,
14        / 'sy-msgid', sy-msgid,
15        / 'sy-msgno', sy-msgno,
16        / 'sy-msgv1', sy-msgv1.
17
18 *_____________________________________________________________________
19 form call_and_handle_exception.
20   call function 'Z_TX_2010'
21      exporting
22           msgtype = p_etype
23      importing
24           pout    = vout
25      exceptions
26           error_e = 1
27           error_w = 2
28           error_i = 3
29           error_s = 4
30           error_a = 5
31           error_x = 6
32           others  = 7.
33   endform.
34
35 *_____________________________________________________________________
36 form call_and_dont_handle_exception.
37   call function 'Z_TX_2010'
38      exporting
39           msgtype = p_etype
40      importing
41           pout    = vout.
42   endform.


Listing 20.10  The Source Code for the Function Module Called from Listing 20.9

 1 function z_tx_2010.
 2 *"------------------------------------------------------------
 3 *"*"Local interface:
 4 *"       IMPORTING
 5 *"             VALUE(MSGTYPE)
 6 *"       EXPORTING
 7 *"             VALUE(POUT)
 8 *"       EXCEPTIONS
 9 *"              ERROR_E
10 *"              ERROR_W
11 *"              ERROR_I
12 *"              ERROR_S
13 *"              ERROR_A
14 *"              ERROR_X
15 *"------------------------------------------------------------
16 pout = 'XXX'.
17 case msgtype.
18   when 'E'. message e991(zz) with 'Error E' raising error_e.
19   when 'W'. message e992(zz) with 'Error W' raising error_w.
20   when 'I'. message e993(zz) with 'Error I' raising error_i.
21   when 'S'. message e994(zz) with 'Error S' raising error_s.
22   when 'A'. message e995(zz) with 'Error A' raising error_a.
23   when 'X'. message e996(zz) with 'Error X' raising error_x.
24   endcase.
25 endfunction.

Using the default parameter values, the code in Listings 20.9 and 20.10 produce this output:

sy-subrc =     1   
vout = INIT        
sy-msgty E         
sy-msgid ZZ        
sy-msgno 991       
sy-msgv1 Error E   

Try running program ztx2009. By specifying a p_handle value of N, you will see error messages produced.

Defining Exceptions in the Interface

Whenever you raise an exception in a function module, you should document that name in the function module's interface. The exception names will also automatically appear at the top of the function module source within the system-generated comments. The following procedure describes how to document your exceptions.

Start the ScreenCam "How to Document Exceptions in the Function Module Interface" now.

  1. Begin at the Function Library: Initial Screen.
  2. Type your function module name in the Function Module field if it is not already there.
  3. Choose the Table Parameters/Exceptions Interface radio button.
  4. Press the Change pushbutton. The Function Module Change: Table Parameters/Exceptions screen is displayed.
  5. In the bottom half of the screen, in the Exceptions section, type the names of the exceptions that appear in the source code of the function module.
  6. Press the Save button and the Back button. You are returned to the Function Library: Initial Screen.

Automatically Inserting the call function Statement

Instead of typing the call function statement into your source code, the system can automatically generate it for you. When you do it this way, the exception names that you documented in the interface will automatically be inserted into your code as well.

Start the ScreenCam "How to Insert a call function Statement into Your ABAP/4 Program" now.

To see the effects of your exception documentation, create an ABAP/4 program. Instead of coding the call function statement yourself, use the following procedure to automatically generate the call function statement:

  1. Begin at the ABAP/4 Editor: Edit Program screen.
  2. Position your cursor within the source code on the line after the one where you want the call function statement to appear.
  3. Press the Pattern button on the Application toolbar. The Insert Statement dialog box appears.
  4. The Call Function radio button should already be chosen. If it isn't, select it.
  5. Type the name of your function module in the input field to the right of Call Function.
  6. Press the Continue button (the green checkmark). You are returned to the Edit Program screen. A call function statement will appear in the source code on the line above the one you positioned your cursor on. The statement will begin in the same column as the column that your cursor was in. The parameters and exceptions that you named in the interface will appear. If a parameter is marked as optional in the interface, it will be commented out and the default value will appear to the right of it.
  7. Fill in the values to the right of the equal signs. Feel free to change the code or remove any lines that follow the importing addition if you do not need those return values.

CAUTION
An empty importing clause causes a syntax error. If there are no parameter names following the word importing, or if they are all commented out, you must remove the word importing. The same is also true for exporting.

Summary

Q&A

Q
Why would you pass an import parameter by reference? If you specify both import and export parameters should be passed by reference, aren't they the same? Why does the ability to do this exist?
A
A pass by reference is more efficient than a pass by value. You should use it for efficiency. However, the words Import and Export provide important documentation regarding the role each parameter plays within the function module. You should not change Import parameters, they should always be passed in without being changed by the function module. Nor should you accept values into the function module via Export parameters. The value of an Export should always originate within the function module.

Workshop

The Workshop provides you 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. If a parameter with the same name exists in two function modules within a group and both interfaces are global, must the data definitions of both of these parameters be identical?
  2. If you accidentally release a function module and want to cancel the release, what menu path can you use?
  3. If you do not code others and an exception is raised within the function module that is not named on the exceptions addition, what happens?
  4. Check, exit, and stop have the same effect with function modules as they do in external subroutines. Should they be used within function modules?

Exercise 1

Copy the z_tx_div function module, and modify it to raise the zero_divide exception if the value of p2 is zero. (To copy a function module, use the Copy button on the Function Library: Initial screen.)