Sams Teach Yourself ABAP/4® in 21 Days
Day 20
Modularization: Function Modules, Part 2
After you complete this chapter, you will be able to:
- Understand the components and structure of a function group
- Define global data and subroutines within a function group
Two types of global data can be defined for a function
module:
- Data definitions placed in the top include are accessible
from all function modules and subroutines within the group. This
type of global data is persistent across function module calls.
- Data definitions within the interface are known only within
the function module. If the interface is defined as a global
interface, the parameter definitions are also known within
all subroutines that the function module calls. This type of global
data is not persistent across function module calls.
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
- In Listing 20.1, line 5 transfers control to line 10, and
line 11 calls function module z_tx_2002, which exists
in function group ztxb. The value of parm_in
is passed to p_in. Control transfers to line 1 of Listing
20.2.
- In Listing 20.2, line 7 moves the value from p_in
to the global variable g1. g1 is defined in
the top include on line 2 of in Listing 20.14. That makes
it visible to all function modules, and the value is persistent
between calls to function modules of that group. Control returns
to line 11 of Listing 20.1.
- In Listing 20.1, line 16 transfers control to line 5, then
line 6, and then line 19. Line 20 calls function module z_tx_2003,
which also exists in function group ztxb. Control transfers
to line 1 of Listing 20.3.
- In Listing 20.3, line 7 moves the value from the global variable
g1 to p_out. g1 still contains the
value placed in it by the previous function module. Control returns
to the calling program and the value is written out.
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:
- Via the tables portion of the interface. This is
equivalent to passing it via the tables addition to the
perform statement.
- Via the importing or changing portion of
the interface. The first is equivalent to using on the
perform statement and the last is equivalent to changing
on perform.
To return an internal table that originates from within a function
module, use one of the following:
- The tables portion of the interface
- The exporting portion of the interface
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.
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
- In Listing 20.5, it_a and it_b are internal
tables without header lines.
- Line 5 puts three rows into it_a.
- Line 8 passes the body of it_a to it1 by
value, to it3 by value and result, and to it4
by reference with header line (it4 will acquire a header
line within the function module).
- In Listing 20.6 and within the function module, it1
and it3 are independent copies of it_a. Line
13 defines a work area wa for use with it1 and
it3 because they don't have header lines.
- Lines 15 through 17 write out the contents of it1
using the work area wa.
- Lines 18 through 21 modify the contents of it3. This
table was passed by value and result, so the contents of the original
will be changed when the endfunction statement executes.
- Lines 24 through 26 write out the contents of it4.
Notice that line 25 accesses a component of it. This
is only possible because the Ref. Structure column on the Table
Parameters/Exceptions screen contains the name of the DDIC structure
lfa1. This defines the structure of it within
the function module. If the Ref. Structure column was blank, a
syntax error would have occurred on line 25.
- Line 28 copies the contents of it1 to it2.
- Line 29 copies the contents of it3 back into it_a
in the calling program and control returns to the caller.
- In Listing 20.5, lines 21 through 23 show that the contents
of it_a have been changed by the function module.
- Lines 26 through 28 show that the contents of it_a
have been copied to it_b by the function module.
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.
- Start from the Function Library: Initial Screen.
- Select the Source Code radio button.
- Press the Change pushbutton. The Function Module: Edit screen
is shown.
- Type a perform statement in the source code of the
function module. For example, perform sub1.
- 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.
- 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.
- 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.
- 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.
- Press the Yes button. The Function Module Editor screen is
shown. You are now editing the F01. Code the subroutine here.
- 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.
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.
- Begin at the Function Library Initial Screen.
- Choose the Administration radio button.
- 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.
- 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.
|
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.
- Begin at the Function Library: Initial Screen. Type the name
of the function module you want to test in the Function Module
field.
- 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.
- 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.
- 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.
|
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.
- 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.
- Expand the Programming line by clicking on the plus sign (+)
to the left of it. A subtree is shown below it.
- 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.
- 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.
- 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).
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
|
- 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.
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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
|
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.
- Begin at the ABAP/4 Editor: Initial Screen (transaction SE38).
- In the Program field, type the program name from the first
field of the dialog box, in this case lztxau02.
- Press the Change pushbutton. This will show you the function
module source code that contains the error.
- 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.
- Correct the error. Often, you can simply press the Correct
button and the system will automatically correct the error for
you.
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:
- raise
- message ... raising
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:
- xname is the
name of the exception to be raised.
The following points apply:
- xname can
be any name that you make up. It does not have to be previously
defined anywhere. It can be up to 30 characters in length. All
characters are allowed except "
' .
, and :.
- Do not enclose xname
within quotes.
- xname cannot
be a variable.
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
- In Listing 20.7, line 4 takes the value from parm_in
and passes it to the function module z_tx_2007. Control
transfers to line 1 of Listing 20.8.
- In Listing 20.8, line 14 assigns a value to the pout
parameter. This parameter is passed by value, so the change is
only to the local definition of pout. The original has
not yet been modified.
- In Listing 20.8, line 15 examines the value passed via parameter
exname. The value is B, so line 17-raise
error_b-is executed. Control transfers to line 9 of Listing
20.7. Because the raise statement has been executed,
the value of pout is not copied back to the calling program,
thus the value of vout will be unchanged.
- In Listing 20.7, the system scans lines 10 through 13 until
it finds a match for the exception named by the just-executed
raise statement. In this case, it's looking for error_b.
Line 11 matches.
- On line 11, the value on the right-hand side of the equals
operator is assigned to sy-subrc. Control then transfers
to line 20.
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.
|
The message ... raising statement has two modes of operation:
- If the exception named after raising is not handled
by the call function statement and others is
not coded, a message is issued to the user.
- If the exception named after raising is handled by
the call function statement, a message is not issued
to the user. Instead, control returns to the call function
statement and the exception is handled the same way as for the
raise statement.
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:
- t is the message
type (e, w, i, s, a,
or x).
- nnn is the
message number.
- (cc) is the
message class.
- v1 and v2
are values to be inserted into the message text.
- xname is the
name of the exception to be raised.
The following points apply:
- xname is an
exception name as described for the raise statement.
- If the message class is not specified here, it must be specified
on the function-pool statement in the top include
for the function group via the message-id addition.
- The following sy variables are set: sy-msgid,
sy-msgty, sy-msgno, and sy-msgv1 through
sy-msgv4. These can be examined within the calling program
(after return).
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).
- If the condition is handled by the caller, control returns
to the caller. The values of the sy-msg variables are
set. The values of exports passed by value are not returned.
- If the condition is not handled by the caller, and for message
types e, w, and a, the function module
is exited and the calling program is terminated immediately. The
message is displayed and the output list appears blank. When the
user presses the Enter key, the blank list is removed and the
user is returned to the screen from which the program was invoked.
- If the condition is not handled by the caller, and for message
type i, the message is displayed to the user in a dialog
box. When the user presses the Enter key, control returns to the
function module at the statement following the message
statement. The function module continues processing and, at the
endfunction statement, control returns to the calling
program. The values of the sy-msg variables are set and
the values of exports passed by value are returned.
- If the condition is not handled by the caller, and for message
type s, the message is stored in a system area. Control
continues within the function module at the statement following
the message statement. The function module continues
processing and, at the endfunction statement, control
returns to the calling program. The values of the sy-msg
variables are set and the values of exports passed by value are
returned. When the list is displayed, the message appears in the
status bar at the bottom of the list.
- If the condition is not handled by the caller, and for message
type x, the function module is exited and the calling
program is terminated immediately. A short dump is generated and
displayed to the user.
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
- In Listing 20.9, when using the default values for the parameters
line 6 is true, so control transfers to the subroutine call_and_handle_exception.
- Line 20 transfers control to line 1 of Listing 20.10.
- In Listing 20.10, line 16 assigns a value to the local parameter
pout. This value is defined as pass-by-value, so the
value of vout in the caller is not yet changed.
- Line 18 of the case statement is true and the message
... raising statement is executed. This triggers the exception
error_e.
- The exception error_e is handled by the calling program,
so the message is not displayed to the user. Control returns to
line 25 of Listing 20.9. The value of vout is not changed;
the sy-msg variables are assigned values.
- In Listing 20.9, line 26 assigns 1 to sy-subrc.
- Line 33 returns control to line 11 and the values are written
out.
Try running program ztx2009. By specifying a p_handle
value of N, you will see error messages produced.
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.
- Begin at the Function Library: Initial Screen.
- Type your function module name in the Function Module field
if it is not already there.
- Choose the Table Parameters/Exceptions Interface radio button.
- Press the Change pushbutton. The Function Module Change: Table
Parameters/Exceptions screen is displayed.
- 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.
- Press the Save button and the Back button. You are returned
to the Function Library: Initial Screen.
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:
- Begin at the ABAP/4 Editor: Edit Program screen.
- Position your cursor within the source code on the line after
the one where you want the call function statement to
appear.
- Press the Pattern button on the Application toolbar. The Insert
Statement dialog box appears.
- The Call Function radio button should already be chosen. If
it isn't, select it.
- Type the name of your function module in the input field to
the right of Call Function.
- 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.
- 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.
|
- Global variables can be defined at two levels. When defined
in the top include, they are global to all function modules
within the group and remember their values between calls to function
modules within the group as long as the calling program continues
to execute. By globalizing the interface, parameters are visible
within subroutines called from the function module.
- Subroutines defined within a function group are coded in the
F01 include.
- Function modules can be released to denote that the interface
is stable and no significant changes will be made to it. It is
therefore released for general availability and is "safe"
to use in production code.
- The test environment provides a convenient way of running
function modules without writing any ABAP/4 code.
- Existing function modules can be found with the aid of the
Repository Information System.
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.
|
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."
- 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?
- If you accidentally release a function module and want to
cancel the release, what menu path can you use?
- 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?
- Check, exit, and stop have the
same effect with function modules as they do in external subroutines.
Should they be used within function modules?
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.)
© Copyright, Macmillan Computer Publishing. All rights reserved.