📄 ch18.htm
字号:
<IMG SRC="../button/analysis.gif" tppabs="http://pbs.mcp.com/ebooks/0672312174/button/analysis.gif">
<UL>
<LI>Line 2 allocates memory for variable <TT>f1</TT>.
<LI>Line 4 transfers control to line 9.
<LI>Line 10 causes <TT>f1</TT> to be passed by value and result.
Therefore, <TT>p1</TT> refers to a new memory location that is
independent of <TT>f1</TT>. The value of <TT>f1</TT> is automatically
copied into the memory for <TT>p1</TT>.
<LI>Line 11 modifies the memory for <TT>p1</TT>. <TT>f1</TT> is
unchanged.
<LI>Line 12 copies the value of <TT>p1</TT> back into <TT>f1</TT>,
frees <TT>p1</TT>, and transfers control to line 5.
<LI>Line 5 passes control to line 14.
<LI>Line 14 causes <TT>f1</TT> to be passed by value and result.
A new memory area is allocated for <TT>p1</TT> and the value of
<TT>f1</TT> is copied into it.
<LI>Line 15 changes the value of <TT>p1</TT> to <TT>B</TT>.
<LI>Line 16 issues the <TT>stop</TT> statement. It frees the memory
for <TT>p1</TT>, and the changed value is lost. Control transfers
to line 7.
<LI>Line 8 writes out the value <TT>B</TT>.
</UL>
<H3><A NAME="PassingInternalTablesasParameters">
Passing Internal Tables as Parameters</A></H3>
<P>
It may be a good idea to review internal tables now, especially
the <TT><I>it</I>[]</TT> syntax.
<P>
You can use one of two methods to pass an internal table to a
subroutine:
<OL>
<LI>Pass with header line
<LI>Pass body only
</OL>
<P>
If the internal table has a header line, method 1 passes both
the header line and the body to the subroutine. Method 2 passes
only the body to the subroutine.
<P>
If the internal table doesn't have a header line, you can also
use both methods. However, method 1 will behave a little differently-it
will automatically create a header line for the internal table
within the subroutine.
<P>
At this point, you may be asking yourself, "Why would I want
to pass an internal table without a header line?" Most of
the time, you wouldn't. However, if you have a special case that
requires an internal table without a header line, you will need
to pass it without a header line. You will need to do this if
you use nested internal tables-a nested internal table cannot
have a header line. Nested internal tables are used more often
in release 4, so this technique will be needed more often on newer
systems.
<P>
Table 18.4 summarizes the effect of each of these methods on internal
tables with and without header lines.<BR>
<P>
<CENTER><B>Table 18.4 Methods and Results of Passing
an Internal Table to a Subroutine</B></CENTER><CENTER>
<TABLE BORDER=1>
<TR VALIGN=TOP><TD WIDTH=192><BR>
<CENTER><B>Method</B></CENTER></TD><TD WIDTH=192><CENTER><B>If Internal Table<BR>
Has a Header Line</B></CENTER>
</TD><TD WIDTH=192><CENTER><B>If Internal Table Doesn't<BR>
Have a Header Line</B></CENTER>
</TD></TR>
<TR VALIGN=TOP><TD WIDTH=192>With header line</TD><TD WIDTH=192>Passes both
</TD><TD WIDTH=192>Creates a header line inside subroutine</TD>
</TR>
<TR VALIGN=TOP><TD WIDTH=192>Without header line</TD><TD WIDTH=192>Passes body only
</TD><TD WIDTH=192>Passes body</TD></TR>
</TABLE>
</CENTER>
<P>
<P>
Table 18.5 shows the syntax for each method of passing an internal
table to a subroutine.<BR>
<P>
<CENTER><B>Table 18.5 Syntax for Each Method of Passing
an Internal Table to a Subroutine</B></CENTER><CENTER>
<TABLE BORDER=1>
<TR VALIGN=TOP><TD WIDTH=96><CENTER><B>Method</B></CENTER></TD><TD WIDTH=288><CENTER><B>Syntax</B></CENTER>
</TD><TD WIDTH=192><CENTER><B>How Passed</B></CENTER></TD></TR>
<TR VALIGN=TOP><TD WIDTH=96>With header line</TD><TD WIDTH=288><TT>form <I>s1</I> tables <I>it</I></TT>
</TD><TD WIDTH=192>By reference</TD></TR>
<TR VALIGN=TOP><TD WIDTH=96>Body only</TD><TD WIDTH=288><TT>form <I>s1</I> using <I>it</I>[]</TT>
<br>
<TT>form <I>s1</I> changing <I>it</I>[]</TT>
<br>
<TT>form <I>s1</I> using value(<I>it</I>[])</TT>
<br>
<TT>form <I>s1</I> changing value(<I>it</I>[])</TT>
</TD><TD WIDTH=192>By reference
<br>
By reference<br>
By value<br>
By value and result
</TD></TR>
</TABLE>
</CENTER>
<P>
<P>
If the internal table has a header line, the first method in Table
18.4 passes both the header and body to the subroutine. The rest
of the methods pass the body only.
<P>
If the internal table doesn't have a header line, the first method
in Table 18.4 passes the body and creates a header line within
the subroutine. The rest pass the body only.
<H4>Making the Components of an Internal Table Known Within the
Subroutine</H4>
<P>
Merely passing an internal table is usually not enough-you must
also describe the structure of the internal table to the subroutine.
If you don't describe the structure of the internal table on the
<TT>form</TT> statement, the components of the internal table
will be unknown within the subroutine. Accessing any component
within the subroutine will then result in a syntax error.
<P>
The syntax you need depends on the method you use to pass the
internal table. Table 18.6 shows the appropriate syntax for each
method.<BR>
<P>
<CENTER><B>Table 18.6 Syntax for Describing the Internal
Table to the Subroutine</B></CENTER><CENTER>
<TABLE BORDER=1>
<TR VALIGN=TOP><TD WIDTH=96><CENTER><B>Method</B></CENTER></TD><TD WIDTH=192><CENTER><B>Syntax</B></CENTER>
</TD><TD WIDTH=288><CENTER><B>Valid Values for </B><TT><B>x</B></TT></CENTER>
</TD></TR>
<TR VALIGN=TOP><TD WIDTH=96>With header line</TD><TD WIDTH=192><TT>tables <I>it</I> structure <I>x</I></TT>
</TD><TD WIDTH=288>A field string
<br>
A DDIC structure<Br>
A DDIC table<Br>
An internal table with a header line
</TD></TR>
<TR VALIGN=TOP><TD WIDTH=96> </TD><TD WIDTH=192><TT>tables <I>it</I> like <I>x</I></TT>
</TD><TD WIDTH=288>An internal table without aheader line
<Br>
An internal table body (<TT><I>it</I>[]</TT>)
</TD></TR>
<TR VALIGN=TOP><TD WIDTH=96>Without header line</TD><TD WIDTH=192><TT>using it[] like <I>x</I></TT>
</TD><TD WIDTH=288>An internal table without header line
<br>
An internal table body (<TT>it[]</TT>)
</TD></TR>
</TABLE>
</CENTER>
<P>
<P>
The <TT>structure</TT> addition expects a field string name after
it. Here, code the name of any field string, DDIC structure or
table, or the name of an internal table that has a header line.
<P>
The <TT>like</TT> addition expects a table body after it. Here,
code a reference to the body of an internal table. If the internal
table you wish to name here doesn't have a header line, either
<TT>it</TT> or <TT>it[]</TT> refers to the body of <TT>it</TT>.
If <TT>it</TT> has a header line, only the syntax <TT>it[]</TT>
can be used to refer to the body of <TT>it</TT>.
<P>
If you pass the body only, you will usually need a work area within
the subroutine to add records to and retrieve records from the
internal table. To define it, you can use <TT>local</TT>, <TT>data</TT>,
or <TT>statics</TT>. If a global work area is already available,
you might use that one, although it is less desirable because
accessing global variables from within a subroutine makes program
maintenance more difficult. If you elect to use the <TT>data</TT>
statement to define your work area, the <TT>like line of <I>itabbody</I></TT>
addition is available. It defines a field string using only the
body of an internal table. The resulting field string is exactly
like a line of the internal table body <TT><I>itabbody</I></TT>.
For example, <TT>data fs like line of it[]</TT> defines a field
string named <TT>fs</TT>. It has the same structure as a single
row of <TT>it</TT>.
<H4>Passing an Internal Table with Header Line</H4>
<P>
If an internal table has a header line and you want to pass both
the header line and the body to a subroutine, use the syntax shown
in the first row of Table 18.5. This passes both the header line
and the body, and they are both passed by reference. Therefore,
changes made to either the header line or body of the internal
table within the subroutine are immediately reflected in the original.
<P>
Listing 18.8 illustrates this syntax.
<P>
<IMG SRC="../button/input.gif" tppabs="http://pbs.mcp.com/ebooks/0672312174/button/input.gif">
<HR>
<P>
<B>Listing 18.8 How to Pass an Internal Table That
Has a Header Line with Its Header Line<BR>
</B>
<BLOCKQUOTE>
<PRE>
1 report ztx1808.
2 * Here, IT is an internal table that has a header line
3 * This program shows how to pass both the header line and body.
4 tables ztxlfa1.
5 data it like ztxlfa1 occurs 5 with header line.
6
7 select * up to 5 rows from ztxlfa1 into table it order by lifnr.
8 perform s1 tables it.
9 loop at it.
10 write / it-lifnr.
11 endloop.
12
13 form s1 tables pt structure ztxlfa1. "uses the field string ztxlfa1
14 "here, you can use:
15 "structure fs "a field string
16 "structure ddicst "a ddic structure or table
17 "structure it "any internal table with header line
18 "like it. "ok if itab doesn't have header line
19 "like it[]. "any internal table
20 read table pt index 3.
21 pt-lifnr = 'XXX'.
22 modify pt index 3.
23 endform.
</PRE>
</BLOCKQUOTE>
<HR>
<P>
<IMG SRC="../button/output.gif" tppabs="http://pbs.mcp.com/ebooks/0672312174/button/output.gif">
<P>
The code in Listing 18.8 produces the following output:
<BLOCKQUOTE>
<PRE>
1000
1010
XXX
1030
1040
</PRE>
</BLOCKQUOTE>
<P>
<IMG SRC="../button/analysis.gif" tppabs="http://pbs.mcp.com/ebooks/0672312174/button/analysis.gif">
<UL>
<LI>Line 4 defines a global work area <TT>ztxlfa1</TT>. This work
area is a field string having the same structure as the DDIC table
<TT>ztxlfa1</TT>.
<LI>Line 5 defines internal table <TT>it</TT> with a header line.
<LI>Line 7 populates the internal table with 5 rows from table
<TT>ztxlfa1</TT>.
<LI>Line 8 transfers control to line 13.
<LI>Line 13 causes the internal table to be passed together with
its header line. It is passed by reference, so <TT>pt</TT> is
a pointer to the original. <TT>structure</TT> is needed to make
the structure of the internal table known to the subroutine. Without
it, any access to a component of the internal table would cause
a syntax error.
<LI>Lines 15 through 19 show the choices available for making
the structure <TT>it</TT> known within the subroutine.
<LI>Line 20 reads row 3 from <TT>pt</TT> and places it into the
header line. Without the <TT>structure</TT> addition on line 13,
this line would have caused a syntax error.
<LI>Line 21 changes the value of <TT>lifnr</TT> in the header
line. Since the internal table was passed with header line by
reference, this modifies the contents of the original header line.
<LI>Line 22 overwrites row 3 from the header line. Since the internal
table was passed by reference, this modifies the contents of the
original internal table.
<LI>Line 23 returns control to line 8.
<LI>Lines 9 through 11 write out the contents of the internal
table. The output shows that the contents have changed.
</UL>
<P>
If an internal table doesn't have a header line and you want to
pass the body and create a header line in the subroutine, you
can also use the syntax shown in the first row of Table 18.5.
This passes the body by reference, and creates a header line locally
in the subroutine. Changes made to the body of the internal table
within the subroutine are immediately reflected in the original.
<P>
Listing 18.9 illustrates this syntax.
<P>
<IMG SRC="../button/input.gif" tppabs="http://pbs.mcp.com/ebooks/0672312174/button/input.gif">
<HR>
<P>
<B>Listing 18.9 How to Pass an Internal Table Without
a Header Line to a Subroutine and Automatically Create a Header
Line<BR>
</B>
<BLOCKQUOTE>
<PRE>
1 report ztx1809.
2 * Here, an internal table that doesn't have a header line
3 * is passed with header line
4 tables ztxlfa1.
5 data: it like ztxlfa1 occurs 5. "doesn't have a header line
6
7 select * up to 5 rows from ztxlfa1 into table it order by lifnr.
8 perform s1 tables it.
9 loop at it into ztxlfa1. "need to use a work area because it
10 write / ztxlfa1-lifnr. "doesn't have a header line
11 endloop.
12
13 form s1 tables pt structure ztxlfa1. "or you can use:
14 " like it
15 " like it[]
16 read table pt index 3.
17 pt-lifnr = 'XXX'.
18 modify pt index 3.
19 endform.
</PRE>
</BLOCKQUOTE>
<HR>
<P>
<IMG SRC="../button/output.gif" tppabs="http://pbs.mcp.com/ebooks/0672312174/button/output.gif">
<P>
The code in Listing 18.9 produces the following output:
<BLOCKQUOTE>
<PRE>
1000
1010
XXX
1030
1040
</PRE>
</BLOCKQUOTE>
<P>
<IMG SRC="../button/analysis.gif" tppabs="http://pbs.mcp.com/ebooks/0672312174/button/analysis.gif">
<UL>
<LI>Line 4 defines a global work area <TT>ztxlfa1</TT>. This work
area is a field string having the same structure as the DDIC table
<TT>ztxlfa1</TT>.
<LI>Line 5 defines internal table <TT>it</TT> without a header
line.
<LI>Line 7 populates the internal table with 5 rows from table
<TT>ztxlfa1</TT>.
<LI>Line 8 transfers control to line 13.
<LI>Line 13 causes the body of the internal table to be passed
and automatically creates a header line for it. The body is passed
by reference, so <TT>pt</TT> is a pointer to the original body
and to the local header line. <TT>structure</TT> is used to make
the structure of the internal table known to the subroutine. Without
it, any access to a component of the internal table would cause
a syntax error.
<LI>Lines 14 and 15 show the other choices available for making
the structure <TT>it</TT> known within the subroutine.
<LI>Line 16 reads row 3 from <TT>pt</TT> and places it into the
local header line. Without the <TT>structure</TT> addition on
line 13, this line would have caused a syntax error.
<LI>Line 17 changes the value of <TT>lifnr</TT> in the header
line. Because the original internal table doesn't have a header
line, this doesn't modify anything outside of the subroutine.
<LI>Line 18 overwrites row 3 from the local header line. Because
the internal table was passed by reference, this modifies the
contents of the original internal table.
<LI>Line 19 returns control to line 8. The memory for the local
header line is freed.
<LI>Lines 9 through 11 write out the contents of the internal
table. Because <TT>it</TT> doesn't have a header line, the field
string <TT>ztxlfa1</TT> is used as an explicit work area. The
output shows that the contents have changed.
</UL>
<P>
If an internal table doesn't have a header line and you want to
pass the body without automatically creating a header line in
the subroutine, you can use the syntax shown in rows two through
five of Table 18.5. By using this syntax, you can pass the body
by reference, by value, or by value and result. If you pass <TT>it</TT>
by reference, changes made to the body of the internal table within
the subroutine are immediately reflected in the original. If you
pass <TT>it</TT> by value, a local copy of <TT>it</TT> is created-changes
are discarded at the end of the subroutine when the local memory
for <TT>it</TT> is freed. If you pass <TT>it</TT> by value and
result, changes are copied back into the original when <TT>endform</TT>
is executed. A <TT>stop</TT> statement within the subroutine will
discard all changes to <TT>it</TT> and transfer control directly
to <TT>end-of-selection</TT>.
<P>
Listing 18.10 illustrates these methods.
<P>
<IMG SRC="../button/input.gif" tppabs="http://pbs.mcp.com/ebooks/0672312174/button/input.gif">
<HR>
<P>
<B>Listing 18.10 How to Pass an Internal Table Without
a Header Line to a Subroutine<BR>
</B>
<BLOCKQUOTE>
<PRE>
1 report ztx1810.
2 * Here, an internal table that doesn't have a header line
3 * is passed without creating a header line automatically
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -