Day 19

Modularization: Function Modules, Part 1


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

Using the include Statement

An include program is a program in which the contents are designed to be used by another program. It is not usually complete all by itself. Instead, other programs use the code the include program contains by copying the lines of code from the include program into themselves. The copy is performed at runtime via the include statement. An include program is also known as an included program.

A program that includes another is known as an including program.

Syntax for the include Statement

The following is the syntax for the include statement.

include ipgm.

where:

The following points apply:

The include statement copies the contents of the include program into the including program. The code from the include program is copied as-is and replaces the include statement at the time of program generation. Figure 19.1 illustrates the include statement.

Figure 19.1 : An illustration of the include statement.

In Figure 19.1, za is the including program. The include programs are zb and zc. At the time za is generated, the source code for zb and zc is inserted into za, making the program shown at the bottom of the figure.

Listings 19.1 through 19.3 illustrate include programs.


Listing 19.1  An Including Program

1  report ztx1901 no standard page heading.
2  tables: ztxlfa1, ztxlfb1.
3  parameters p_lifnr like ztxlfa1-lifnr obligatory default '1000'.
4 
5  include: ztx1902,
6           ztx1903.
7 
8  top-of-page.
9      write: / 'Company Codes for Vendor', p_lifnr.
10     uline.


Listing 19.2  This Program Is Included into ztx1901

1  ***INCLUDE ZTX1902.
2  select single * from ztxlfa1 where lifnr = p_lifnr.


Listing 19.3  This Program Is also Included into ztx1901

1  ***INCLUDE ZTX1903.
2  select * from ztxlfb1 where lifnr = ztxlfa1-lifnr.
3      write: / ztxlfb1-bukrs.
4      endselect.

The code in Listings 19.1 through 19.3 produces this output:

Company Codes for Vendor 1000     
---------------------------------
1000                              
3000                              

SAP uses includes to reduce code redundancy and to divide very large programs into smaller units.

TIP
While viewing an including program, you can view the contents of an included program simply by double-clicking on its name. For example, while editing ztx1901 from the ABAP/4 Editor: Edit Program screen, double-click on the name ztx1902 or ztx1903. The included program will be displayed immediately.

TIP
If you want to see the resulting code with all includes expanded in-line, run program RSINCL00. On the selection screen for RSINCL00, in the Program field, enter the name of a program that includes other programs. Place an X in the Program Source Code and Expand Include Lines fields and press Execute. A list of the resulting source code will be displayed on the next screen.

Introducing Function Modules

A function module is the last of the four main ABAP/4 modularization units. It is very similar to an external subroutine in these ways:

The major differences between function modules and external subroutines are the following:

A function module name has a practical minimum length of three characters and a maximum length of 30 characters. Customer function modules must begin with Y_ or Z_. The name of each function module is unique within the entire R/3 system.

Understanding Function Groups

As stated before, a function group is a program that contains function modules. With each R/3 system, SAP supplies more than 5,000 pre-existing function groups. In total, they contain more than 30,000 function modules. If the functionality you require is not already covered by these SAP-supplied function modules, you can also create your own function groups and function modules.

Each function group is known by a four-character identifier called a function group ID. If you create your own function group, you must choose a function group ID that begins with Y or Z. The ID must be exactly four characters long and cannot contain blanks or special characters.

CAUTION
On releases prior to 3.0F, the R/3 system enables you to specify a function group ID of fewer than four characters or to use spaces within it. However, you should not do this because the tools that manipulate function modules will behave erratically with such a function group.

To illustrate function groups, I will briefly describe the process of creating a function group and a function module within it. Let's assume that neither the function group nor the function module yet exist.

You begin by creating a function module. When you create a function module, the system will first ask you for a function group ID. This ID tells the system where to store the function module.

When you supply the ID, and if it doesn't yet exist, the system creates:

Collectively, these components are known as the function group. Their relationships are illustrated in Figure 19.2.

Figure 19.2 : This is the hierarchical relationship of the components of a function group.

The name of the main program will be saplfgid, where fgid is your four-character function group ID. The system automatically places two include statements into it:

The first include program-lfgidtop-is known as the top include. Within it you can place global data definitions. These are data definitions that are global to all function modules within the group.

The second include program-lfgiduxx-is known as the UXX. You are not allowed to modify the UXX. The system will automatically place an include statement in the UXX for each function module you create in this function group. For the first function module, the statement include lfgidu01 will be inserted into the UXX. When you create a second function module in this group, the system will add a second statement: include lfgidu02. Each time you add a new function module to the group, the system will add a new include statement to the UXX. The number of the include will be 01 for the first function module created within the group, 02 for the second, 03 for the third, and so on.

Within each include mentioned in the UXX is the source code for a function module.

Accessing the Function Library

Function groups are stored in a group of tables within the database called the function library. By accessing the function library, you can also access the tools by which you manipulate function modules and groups. To access the function library from the Development Workbench, press the Function Library button on the Application toolbar. The transaction code is SE37.

Each of the components of a function group can be accessed from the Function Library Initial Screen shown in Figure 19.3.

Figure 19.3 : The Function Library Initial Screen.

For example, to access the main program of the function group, choose the Main Program radio button and then press the Display pushbutton. The main program of function group ztxa is shown in Figure 19.4.

Figure 19.4 : The main program of function group ztxa.

Figure 19.5 shows the UXX for function group ztxa.

Figure 19.5 : The UXX for function group ztxa.

In Figure 19.5, you can see that function group ztxa contains two function modules: z_tx_1901 and z_tx_1902. The first one is active, the second is not (its name is commented out).

Activating a Function Module

A function module must be activated before it can be called. There is an Activate button on the Function Library Initial Screen. Pressing it activates the function module.

When the function module is first created, the include statement for it within the UXX is commented out. Activating the function module causes the system to remove the comment from the include statement. The function module is then available to be called from other programs. If you change the code within the function module, it doesn't need to be activated again. On the other hand, re-activating won't do any harm, either.

If you want, you can deactivate a function module. From the ABAP/4 Function Library: Initial Screen, choose the menu path Function Module->Deactivate. Choosing this menu path comments out the include statement for that function module within the UXX.

All the function modules that belong to a single group exist within the main program: saplfgid. Because of that, a syntax error in any one of these function modules will cause the rest to become inoperative; executing any one of them will result in a syntax error. The Activate and Deactivate functions enable you to work on any single function module of a group without affecting the rest. You can deactivate a function module before you work on it, change the code, and then perform a syntax check on that single module before reactivating it. In that way, the rest of the function modules can still be called, even while you are working on one of them.

Defining Data within a Function Module

Data definitions within function modules are similar to those of subroutines.

Within a function module, use the data statement to define local variables that are reinitialized each time the function module is called. Use the statics statement to define local variables that are allocated the first time the function module is called. The value of a static variable is remembered between calls.

Define parameters within the function module interface to create local definitions of variables that are passed into the function module and returned from it (see the next section).

You cannot use the local statement within a function module. Instead, globalized interface parameters serve the same purpose. See the following section on defining global data to learn about local and global interface parameters.

Defining the Function Module Interface

To pass parameters to a function module, you must define a function module interface. The function module interface is the description of the parameters that are passed to and received from the function module. It is also simply known as the interface. In the remainder of this chapter, I will refer to the function module interface simply as the interface.

To define parameters, you must go to one of two parameter definition screens:

The Import/Export Parameter Interface screen is shown in Figure 19.6. On this screen you can define the following:

Figure 19.6 : The Import/Export Parameter Interface screen.

The Table Parameters/Exceptions Interface screen is shown in Figure 19.7. On this screen you can:

Figure 19.7 : The Table Parameters/Exceptions Interface screen.

You enter the name of the parameter in the first column and the attributes of the parameter in the remaining columns. Enter one parameter per row.

Import parameters are variables or field strings that contain values passed into the function module from the calling program. These values originate outside of the function module and they are imported into it.

Export parameters are variables or field strings that contain values returned from the function module. These values originate within the function module and they are exported out of it.

Changing parameters are variables or field strings that contain values that are passed into the function module, changed by the code within the function module, and then returned. These values originate outside the function module. They are passed into it, changed, and passed back.

Table parameters are internal tables that are passed to the function module, changed within it, and returned. The internal tables must be defined in the calling program.

An exception is a name for an error that occurs within a function module. Exceptions are described in detail in the following section.

Passing Parameters

The methods for passing parameters to function modules are very similar to those for passing parameters to external subroutines.

By default:

You can cause import, export, and changing parameters to be passed by reference by placing a tickmark in the Reference check box on the Import/Export Parameters screen (refer to Figure 19.6).

NOTE
The concept of an export parameter being passed by value is a little strange for most programmers. Think of it this way: When passed by value, the memory for an export parameter is defined within the function module. The endfunction statement copies the value of the export parameter from with-in the function module to the variable assigned to it in the calling program.
If the endfunction statement is not executed (for example, if you leave the function module abnormally via the raise statement), the value is not copied and the caller's variable remains unchanged.

Using Typed and Untyped Parameters

Like subroutines, function module parameters can be typed or untyped. Typing works the same way for function modules as it does for subroutines. Untyped parameters adopt all of their technical characteristics from the passing parameter. For example, if the passed parameter is type c length 12 and the function module parameter is untyped, the function module parameter becomes type c length 12.

Typed parameters for function modules follow the same rules as typed parameters for subroutines. There are two ways of specifying typed parameters in the Import/Export Parameters screen:

You cannot use both of these methods at the same time for a single parameter. You must use either one or the other.

Using the first method, simply specify an ABAP/4 data type in the Reference Type column on the Import/Export Parameters screen. For example, in Figure 19.8, p1 and p2 are typed parameters that have an ABAP/4 data type of i (integer). P3 is also typed, having a data type of p. Type i is a fixed length data type and so has a length of 4. Type p is a variable length data type, and takes its length and number of decimal places from the parameter that is passed to it.

Using the second method, enter the name of a Data Dictionary structure in the Reference Field column. The parameters are defined as if you had used the like addition on the form statement in an external subroutine.

Parameters can also be made optional and given default values. To make an import parameter optional, place a tickmark in the Optional column (refer to Figure 19.7). If you make an import parameter optional, you do not have to name it on the call function statement when you call the function module. Export parameters are always optional. By that, I mean that you are not required to code any export parameters on the call function statement. For example, if function module z_xyz returns three export parameters, e1, e2, and e3, and you only want e2, then only code e2 on the call function statement. Simply omit the rest.

To give an import parameter a default value, enter a value in the Proposal column, making sure to enclose character values within single quotes. sy variable names are also allowed. If you specify a proposal, the system will automatically place a tickmark in the Optional column.

All parameters that you define in the interface also appear at the top of the source code within special comments. Each special comment line begins with the characters *". Each time you change the interface the system automatically updates these special comments to reflect your changes.

CAUTION
Don't change or delete these comments; they are generated by the system. If you change them, the function module might not work.

In Figure 19.8, you can see that p1, p2, and p3 are passed by value.

Figure 19.8 : The system-generated comments at the top of the source code.

Calling Function Modules

To call a function module, you code the call function statement. The flow of control is within Listing 19.4.


Listing 19.4  This Program Performs a Simple Call to a Function Module

1  report ztx1904.
2 
3  write: / 'Before Call'.
4  call function 'Z_TX_1901'.
5  write: / 'After Call'.

The code in Listing 19.4 produces this output:

Before Call     
Hi from Z_TX_1901
After Call      

Syntax for the call function Statement

The following is the syntax for the call function statement.

call function 'F'
    [exporting   p1 = v1 ... ]
    [importing   p2 = v2 ... ]
    [changing    p3 = v3 ... ]
    [tables      p4 = it ... ]
    [exceptions  x1 = n [others = n]].

where:

The following points apply:

Use the call function statement to transfer control to a function module and specify parameters. Figure 19.9 illustrates how parameters are passed to and received from the function module.

Figure 19.9 : This figure illustrates how parameters are passed to and received from the function mod-ule.

On the call function statement, exports and imports are from the point of view of the program. Values that are exported by call function are imported by the function module. Values exported from the function module are imported by the call function statement.

On the left of the assignment operator (=) is a list of the parameter names defined in the function module's interface. On the right are variables defined within the calling program. Assignments after exporting proceed from right-to-left. Assignments after importing proceed from left-to-right. Assignments after changing and tables are bi-directional. Before the call, the assignment is from right-to-left. On return, the return value is assigned from left-to-right.

Let's use Figure 19.9 as an example. When you call function module Z_XXX, the value of variable v1 is assigned to parameter p1 and the value of variable v2 is assigned to p2. Control then transfers to the function module. On return, the value of p3 is assigned to v3.

NOTE
In this book, the term "import parameters" by itself (without reference to whether it is from the point of view of the program or function module) refers to parameters imported into the function module. The term "export parameters" without a reference refers to parameters exported from the function module.

Running a Sample Function Module

In this section I will illustrate a call to a sample function module z_tx_div, which simply divides two numbers and returns the result of the division.

Listing 19.5 calls z_tx_div and passes parameters. Figure 19.7 shows the Import/Export Parameters screen for this function module, and Listing 19.6 shows the source code for it.


Listing 19.5  Using the call function Statement with Parameters

1  report ztx1905.
2  parameters: op1 type i default 2,   "operand 1
3              op2 type i default 3.   "operand 2
4  data rslt type p decimals 2.        "result
5 
6  call function 'Z_TX_DIV'
7       exporting
8            p1      = op1
9            p2      = op2
10      importing
11           p3      = rslt.
12
13 write: / op1, '/', op2, '=', rslt.


Listing 19.6  The Source Code for the z_tx_div Function Module

1  function z_tx_div.
2  *"------------------------------------------------------------
3  *"*"Local interface:
4  *"       IMPORTING
5  *"             VALUE(P1) TYPE  I DEFAULT 1
6  *"             VALUE(P2) TYPE  I
7  *"       EXPORTING
8  *"             VALUE(P3) TYPE  P
9  *"------------------------------------------------------------
10 p3 = p1 / p2.
11 endfunction.

The code in Listing 19.6 is called from line 6 of Listing 19.5.

The code in Listing 19.5 produces this output:

         2  /          3  =             0.67

TIP
Press the Pattern button on the ABAP/4 Editor: Edit Program screen to automatically insert the call function statement into your code. You will be asked for the function module name and it automatically codes the left-hand side of all interface parameter assignments for you.

Creating a Function Module

Use the following procedure to create a function module. For an exercise, follow this procedure and create a function module exactly like z_tx_div. Call yours z_div, and put it in function group za (remember to replace the with the two characters that you are using to identify your programs).

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

  1. From the ABAP/4 Development Workbench screen, press the Function Library button on the Application toolbar. The Function Library Initial Screen is shown (refer to Figure 19.3).
  2. Type the name of your function module in the Function Module field. The name must begin with Y_ or Z_.
  3. Press the Create button. The Function Module Create: Administration screen is shown (see Figure 19.10).
    Figure 19.10: This is the Function Module Create: Administration screen.
  4. Type the name of a function group in the Function Group field. The function group name must be four characters long and must begin with Y or Z.
  5. Type an S in the Application field. This field is used to indicate which function area uses the function module. Our functionality is not used by any functional area, it is simply an example, so any choice will do. (S indicates that the function module contains functionality needed by Basis.)
  6. Type a description of the function module in the Short Text field. The contents of this field are seen when displaying a list of function modules.
  7. Press the Save button on the Application toolbar.
  8. If the function group does not already exist, a pop-up informs you of that fact and asks you if you want to create it. Press the Yes button to create the function group. The Create Function Group dialog box appears. Type a description in the Short Text field and press the Save button. The Create Object Catalog Entry screen appears. Press the Local Object button. You are returned to the Function Module Change: Administration screen.
  9. Press the Source Code button on the Application toolbar. The Function Module Edit screen is displayed (refer to Figure 19.8).
  10. Type the source code for your function module. Do not change the system-generated comment lines under any circumstances! Your function module might fail to operate if you do.
  11. Press the Save button on the Application toolbar. The message Program xxxxx saved appears in the status bar at the bottom of the window.
  12. Press the Back button on the Application toolbar. You are returned to the Function Library Initial screen.
  13. If you want to define import or export parameters, select the Import/Export Parameter Interface radio button. Press the Change pushbutton. You are shown the Import/Export Parameters screen (refer to Figure 19.6). Type the names of your parameters in the first column and enter any other desired characteristics for each parameter. When you are finished, press the Save button and then the Back button.
  14. Finally, to activate your function module, press the Activate button on the Application toolbar of the Function Library Initial Screen.

Now would be a good time to create an ABAP/4 program to call your function module and try it out. Create a program like the one shown in Listing 19.5. Within your program, be sure to code the function module name in uppercase. If you don't, you will get a short dump because the system won't be able to find the function module.

TIP
Use the Object Browser to list the function modules you have created. From the Object browser, choose Local Priv. Objects and press the Display push-button.

Summary

DO
DON'T
DO use pass-by-reference for import parameters. It is more efficient. Be careful when using it with export parameters. The values of by-reference parameters are changed immediately in the caller. If you change export parameters before you issue the raise statement, you will return but the values will already be changed in the calling program. DON'T change the system-generated comments at the top of the function module source code.
DO document all exceptions in the function module interface and document all parameters in the Documentation component of the function module. DON'T import values that you don't need from a function module. Simply omit unneeded imports from the call function statement.
DO save your test data so that you can retest your function module after modifications using the same data. DON'T use stop, exit, or check within a function module. (check and exit are okay if they are within a loop inside of the function module.)

Q&A

Q
How do I decide whether to use an include, an internal subroutine, an external subroutine, or a function module to implement my code?
A
If the code will not be used by any other programs, then use an internal subroutine. If the code might be useful to other programs, use a function module. You should not create external subroutines. They were only covered in the previous chapter so that you would know how to use them because there are still many in use in the R/3 system. It's also easier to understand function modules if you know how external subroutines work. Instead of external subroutines, use function modules. includes should be used to simplify your program structure and group similar components together. They should not be used as containers for reusable code that is included into multiple programs. For example, you might put all of your data declarations into one include, your events into another, your subroutines into a third, and your calls to function modules into a fourth.
Q
How do I decide which function group to put a new function module into? When should I create a new one, and when should I reuse an existing one?
A
Put function modules that have similar functionality into the same function group. For example, you might put all of the function modules that calculate depreciation into one function group, all that perform calendar functions into another function group, and those that provide external communication interfaces into a third.

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. True or False: An import parameter that has a proposal is always optional.
  2. True or False: All export parameters are optional.

Exercise 1

Use the Test function within the Function Library to test the function module POPUP_WITH_TABLE_DISPLAY. After testing this function module, look at the following program and predict its behavior.

report ztx1910.
data: begin of it occurs 5,
          data(10),
          end of it,
      result(10).   

perform: fill_table tables it,
         call_fm tables it changing result.
write: / 'Result=', result.

form fill_table tables it like it.
     move 'Select' to it-data. append it.
     move 'One'    to it-data. append it.
     move 'Option' to it-data. append it.
    endform.
form call_fm tables it changing result.
    call function 'POPUP_WITH_TABLE_DISPLAY'
      importing
         endpos_col   = 30
         endpos_row   = 30
         startpos_col = 1
         startpos_row = 1
         titletext    = 'Look Ma, a Window'
      exporting
           choise     = result
      tables
          valuetab    = it.
    endform.