📄 ch20.htm
字号:
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.
<P>
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.
<P>
<A HREF="javascript:popUp('f20-18.gif')"><B>Figure 20.18: </B><I>A syntax error detected at runtime within
a function module</I>.</A>
<P>
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 <TT>lztxau02</TT>. 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
<TT>"." expected after "P2"</TT>.
<P>
To fix the error, use the following procedure.
<P>
<img src="../button/screencam.gif" tppabs="http://pbs.mcp.com/ebooks/0672312174/button/screencam.gif">
<P>
Start the ScreenCam "How to Fix an Error in a Function Module"
now.
<OL>
<LI>Begin at the ABAP/4 Editor: Initial Screen (transaction <TT>SE38</TT>).
<LI>In the Program field, type the program name from the first
field of the dialog box, in this case <B>lztxau02</B>.
<LI>Press the Change pushbutton. This will show you the function
module source code that contains the error.
<LI>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.
<LI>Correct the error. Often, you can simply press the Correct
button and the system will automatically correct the error for
you.
</OL>
<H2><A NAME="SettingtheValueofsysubrconReturn"><FONT SIZE=5 COLOR=#FF0000>
Setting the Value of sy-subrc on Return</FONT></A></H2>
<P>
Normally, after returning from a function module, the system automatically
sets the value of <TT>sy-subrc</TT> to zero. Use one of the following
two statements to set <TT>sy-subrc</TT> to a non-zero value:
<UL>
<LI><TT>raise</TT>
<LI><TT>message ... raising</TT>
</UL>
<H3><A NAME="UsingtheraiseStatement">
Using the raise Statement</A></H3>
<P>
Use the <TT>raise</TT> statement to exit the function module and
set the value of <TT>sy-subrc</TT> on return.
<H4>Syntax for the raise Statement</H4>
<P>
The following is the syntax for the <TT>raise</TT> statement.
<BLOCKQUOTE>
<PRE>
raise xname.
</PRE>
</BLOCKQUOTE>
<P>
where:
<UL>
<LI><TT><I>xname</I></TT> is the
name of the exception to be raised.
</UL>
<P>
The following points apply:
<UL>
<LI><TT><I>xname</I></TT> 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 <TT><B>"</B></TT>
<TT><B>'</B></TT> <TT><B>.</B></TT>
<TT><B>,</B></TT> and <TT><B>:</B></TT>.
<LI>Do not enclose <TT><I>xname</I></TT>
within quotes.
<LI><TT><I>xname</I></TT> cannot
be a variable.
</UL>
<P>
When the <TT>raise</TT> statement is executed, control returns
immediately to the <TT>call function</TT> statement and a value
is assigned to <TT>sy-subrc</TT> 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.
<P>
<A HREF="javascript:popUp('f20-19.gif')"><B>Figure 20.19: </B><I>This illustrates raise statement processing</I>.</A>
<P>
<CENTER>
<TABLE BORDERCOLOR=#000000 BORDER=1>
<TR VALIGN=TOP><TD WIDTH=600><B>NOTE</B></TD></TR>
<TR VALIGN=TOP><TD WIDTH=600>
<BLOCKQUOTE>
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.</BLOCKQUOTE>
</TD></TR>
</TABLE>
</CENTER>
<P>
<P>
<IMG SRC="../button/input.gif" tppabs="http://pbs.mcp.com/ebooks/0672312174/button/input.gif">
<HR>
<P>
<B>Listing 20.7 How to Set the Value of SY-SUBRC from
Within a Function Module<BR>
</B>
<BLOCKQUOTE>
<PRE>
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.
</PRE>
</BLOCKQUOTE>
<HR>
<P>
<IMG SRC="../button/input.gif" tppabs="http://pbs.mcp.com/ebooks/0672312174/button/input.gif">
<HR>
<P>
<B>Listing 20.8 This Is the Function Module Called
from Listing 20.7<BR>
</B>
<BLOCKQUOTE>
<PRE>
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.
</PRE>
</BLOCKQUOTE>
<HR>
<P>
<IMG SRC="../button/output.gif" tppabs="http://pbs.mcp.com/ebooks/0672312174/button/output.gif">
<P>
The code in Listings 20.7 and 20.8 produce this output, if you
specify a value of <TT>A</TT> for <TT>parm_in</TT>:
<BLOCKQUOTE>
<PRE>
sy-subrc = 1
vout = INIT
</PRE>
</BLOCKQUOTE>
<P>
<IMG SRC="../button/analysis.gif" tppabs="http://pbs.mcp.com/ebooks/0672312174/button/analysis.gif">
<UL>
<LI>In Listing 20.7, line 4 takes the value from <TT>parm_in</TT>
and passes it to the function module <TT>z_tx_2007</TT>. Control
transfers to line 1 of Listing 20.8.
<LI>In Listing 20.8, line 14 assigns a value to the <TT>pout</TT>
parameter. This parameter is passed by value, so the change is
only to the local definition of <TT>pout</TT>. The original has
not yet been modified.
<LI>In Listing 20.8, line 15 examines the value passed via parameter
<TT>exname</TT>. The value is <TT>B</TT>, so line 17-<TT>raise
error_b</TT>-is executed. Control transfers to line 9 of Listing
20.7. Because the <TT>raise</TT> statement has been executed,
the value of <TT>pout</TT> is not copied back to the calling program,
thus the value of <TT>vout</TT> will be unchanged.
<LI>In Listing 20.7, the system scans lines 10 through 13 until
it finds a match for the exception named by the just-executed
<TT>raise</TT> statement. In this case, it's looking for <TT>error_b</TT>.
Line 11 matches.
<LI>On line 11, the value on the right-hand side of the equals
operator is assigned to <TT>sy-subrc</TT>. Control then transfers
to line 20.
</UL>
<P>
The special name <TT>others</TT> on line 13 of Listing 20.7 will
match all exceptions not explicitly named on the <TT>exceptions</TT>
addition. For example, if line 7 of Listing 20.8 were executed,
exception <TT>error_x</TT> would be raised. This exception is
not named in Listing 20.7, so <TT>others</TT> will match and the
value of <TT>sy-subrc</TT> will be set to <TT>99</TT>. You can
code any numbers you want for exception return codes.<P>
<CENTER>
<TABLE BORDERCOLOR=#000000 BORDER=1>
<TR VALIGN=TOP><TD WIDTH=600><B>CAUTION</B></TD></TR>
<TR VALIGN=TOP><TD WIDTH=600>
<BLOCKQUOTE>
If you do not code <TT>others </TT>and an exception is raised within the function module that is not named on the <TT>exceptions </TT>addition, the program will be aborted and a short dump will result that has the runtime error <TT>RAISE_EXCEPTION</TT>.
</BLOCKQUOTE>
</TD></TR>
</TABLE>
</CENTER>
<P>
<P>
If an export parameter is passed by value, after a <TT>raise</TT>
its value remains unchanged in the calling program even if a value
was assigned within the function module before the <TT>raise</TT>
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 <TT>pout</TT> is changed in the
function module and, if a <TT>raise</TT> statement is executed,
the changed value is not copied back into the calling program.
<P>
<CENTER>
<TABLE BORDERCOLOR=#000000 BORDER=1>
<TR VALIGN=TOP><TD WIDTH=600><B>NOTE</B></TD></TR>
<TR VALIGN=TOP><TD WIDTH=600>
<BLOCKQUOTE>
<TT>check</TT>, <TT>exit</TT>, and <TT>stop </TT>have the same effect with function modules as they do in external subroutines. However, they should not be used within function modules. Instead, the <TT>raise </TT>statement should be used because it enables the caller to set the value of <TT>sy</TT>-<TT>subrc </TT>on return.
</BLOCKQUOTE>
</TD></TR>
</TABLE>
</CENTER>
<P>
<H3><A NAME="UsingthemessageraisingStatement">
Using the message ... raising Statement</A></H3>
<P>
The <TT>message ... raising</TT> statement has two modes of operation:
<UL>
<LI>If the exception named after <TT>raising</TT> is not handled
by the <TT>call function</TT> statement and <TT>others</TT> is
not coded, a message is issued to the user.
<LI>If the exception named after <TT>raising</TT> is handled by
the <TT>call function</TT> statement, a message is not issued
to the user. Instead, control returns to the <TT>call function</TT>
statement and the exception is handled the same way as for the
<TT>raise</TT> statement.
</UL>
<H4>Syntax for the message ... raising Statement</H4>
<P>
The following is the syntax for the <TT>message ... raising</TT>
statement
<BLOCKQUOTE>
<PRE>
message tnnn(cc) [with v1 v2 ...] raising xname
</PRE>
</BLOCKQUOTE>
<P>
where:
<UL>
<LI><TT><I>t</I></TT> is the message
type (<TT>e</TT>, <TT>w</TT>, <TT>i</TT>, <TT>s</TT>, <TT>a</TT>,
or <TT>x</TT>).
<LI><TT><I>nnn</I></TT> is the
message number.
<LI><TT><I>(cc)</I></TT> is the
message class.
<LI><TT><I>v1</I></TT> and <TT><I>v2</I></TT>
are values to be inserted into the message text.
<LI><TT><I>xname</I></TT> is the
name of the exception to be raised.
</UL>
<P>
The following points apply:
<UL>
<LI><TT><I>xname</I></TT> is an
exception name as described for the <TT>raise</TT> statement.
<LI>If the message class is not specified here, it must be specified
on the <TT>function-pool</TT> statement in the top <TT>include</TT>
for the function group via the <TT>message-id</TT> addition.
<LI>The following <TT>sy</TT> variables are set: <TT>sy-msgid</TT>,
<TT>sy-msgty</TT>, <TT>sy-msgno</TT>, and <TT>sy-msgv1</TT> through
<TT>sy-msgv4</TT>. These can be examined within the calling program
(after return).
</UL>
<P>
When the <TT>message ... raising</TT> 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).
<UL>
<LI>If the condition is handled by the caller, control returns
to the caller. The values of the <TT>sy-msg</TT> variables are
set. The values of exports passed by value are not returned.
<LI>If the condition is not handled by the caller, and for message
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -