📄 ch17.htm
字号:
<HR>
<P>
<IMG SRC="../button/analysis.gif" tppabs="http://pbs.mcp.com/ebooks/0672312174/button/analysis.gif">
<UL>
<LI>Line 15 defines a group of radio buttons. Choosing one will
cause the statement mentioned in the comment to be executed as
indicated. For example, choosing <TT>exit_sos</TT> causes the
<TT>exit</TT> statement to be executed in the <TT>start-of-selection</TT>
event.
<LI><TT>check 1 = 2</TT> is hard-coded so it always returns a
negative result.
<LI>You may wish to increase the line count to make the output
more readable. It is set so that the <TT>bottom-of-page</TT> event
will be triggered.
</UL>
<H3><A NAME="ReturningfromtheList">
Returning from the List</A></H3>
<P>
Let's look more closely at events in the context of a report that
has a selection screen. (Recall that the <TT>parameters</TT> statement
generates a selection screen.)
<P>
When the user executes the report, the driver triggers <TT>initialization</TT>
and then shows the selection screen. After pressing the Execute
button, the driver triggers the remaining events, the program
ends and the user sees the list. The user presses the Back button
to return. The driver then restarts processing beginning at the
top of the event list. It triggers the <TT>initialization</TT>
event, and then all subsequent events follow again in their normal
sequence. The result is that the user sees the selection screen
after pressing the Back button. There is, however, a difference
in processing when a restart occurs.
<P>
The selection screen has its own copy of all variables that are
displayed on it. The first time the report runs and the driver
program regains control after the <TT>initialization</TT> event
has finished, it copies values from program variables to the corresponding
selection screen variables and displays them. The user can modify
the input fields. When the user presses the Execute button, the
driver stores the values from the selection screen into two data
areas: one belonging to the selection screen and then into your
program's variables.
<P>
However, this dual action only occurs the first time you run the
program. When the user presses Back from the list, <TT>initialization</TT>
is triggered again. When control returns to the driver, it doesn't
copy your program variables into the screen data area. Instead,
it shows the existing values from the screen data area; it still
contains the values the user entered. The result is that the user
sees the values that he last entered regardless of what has changed
in your program. Then, after the user presses the Execute button,
the values onscreen are copied to the screen's data area and then
to your program, overwriting any differences. For example, if
you set up values during <TT>initialization</TT>, those values
will be seen on the selection screen when you start the program.
When you press the Back button on the selection screen, <TT>initialization</TT>
will execute but values set within it won't be shown. The user
will instead see the values that he entered.
<H2><A NAME="Subroutines"><FONT SIZE=5 COLOR=#FF0000>
Subroutines</FONT></A></H2>
<P>
<IMG SRC="../button/newterm.gif" tppabs="http://pbs.mcp.com/ebooks/0672312174/button/newterm.gif">
<P>
A <I>subroutine</I> is a reusable section of code. It is like
a mini-program that can be called from another point in your program.
Within it you can define variables, execute statements, compute
results, and write output. To define a subroutine, use the <TT>form</TT>
statement to indicate the start of a subroutine, and use <TT>endform</TT>
to indicate the end of the subroutine. The name of a subroutine
cannot exceed 30 characters.
<P>
To call a subroutine, use the <TT>perform</TT> statement.
<P>
Listing 17.6 provides a sample program that defines and calls
a subroutine.
<P>
<IMG SRC="../button/input.gif" tppabs="http://pbs.mcp.com/ebooks/0672312174/button/input.gif">
<HR>
<P>
<B>Listing 17.6 Defining and Calling a Subroutine<BR>
</B>
<BLOCKQUOTE>
<PRE>
1 report ztx1706.
2
3 write: / 'Before call 1'.
4 perform sub1.
5 write: / 'Before call 2'.
6 perform sub1.
7 write: / 'After calls'.
8
9 form sub1.
10 write: / 'Inside sub1'.
11 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 17.6 produces the following output:
<BLOCKQUOTE>
<PRE>
Before call 1
Inside sub1
Before call 2
Inside sub1
After calls
</PRE>
</BLOCKQUOTE>
<P>
<IMG SRC="../button/newterm.gif" tppabs="http://pbs.mcp.com/ebooks/0672312174/button/newterm.gif">
<UL>
<LI>Line 3 executes.
<LI>Line 4 transfers control to line 9.
<LI>Line 10 executes.
<LI>Line 11 transfers control back to line 4.
<LI>Line 5 executes.
<LI>Line 6 transfers control to line 9.
<LI>Line 10 executes.
<LI>Line 11 returns control to line 6.
<LI>Line 7 executes.
</UL>
<P>
There are two types of subroutines:
<UL>
<LI>Internal subroutines
<LI>External subroutines
</UL>
<P>
Listing 17.6 illustrated a call to an internal subroutine.
<H3><A NAME="DefiningandCallingInternalSubroutines">
Defining and Calling Internal Subroutines</A></H3>
<P>
Subroutine definitions are usually placed at the end of the program,
after all events. The <TT>form</TT> statement defines the end
of the preceding event, and the beginning of a subroutine. Subroutines
cannot be nested inside of events.
<H4>Syntax for the form Statement</H4>
<BLOCKQUOTE>
<PRE>
form <I>s</I> [tables <I>t1 t2 ...</I>]
[using <I>u1 value(u2) ...</I>]
[changing <I>c1 value(c2) ...</I>].
---
endform.
</PRE>
</BLOCKQUOTE>
<P>
where:
<UL>
<LI><TT><I>s</I></TT> is the name
of the subroutine.
<LI><TT><I>t1</I></TT>, <TT><I>t2</I></TT>,
<TT><I>u1</I></TT>, <TT><I>u2</I></TT>,
<TT><I>c1</I></TT><I>,</I> and
<TT><I>c2</I></TT> are parameters.
<LI><TT>tables</TT> allows internal tables to be passed as parameters.
<LI>The <TT>value</TT> addition cannot be used after <TT>tables</TT>.
<LI>The <TT>value</TT> addition can be applied to any variables
passed via <TT>using</TT> or <TT>changing</TT>.
<LI><TT>---</TT> represents any number of lines of code.
</UL>
<P>
The following points apply:
<UL>
<LI>All additions are optional.
<LI>When they are coded, additions must appear in the order shown
here. If coded, <TT>tables</TT> must come first, then <TT>using</TT>,
and then <TT>changing</TT>.
<LI>Each addition can only be specified once. For example, the
<TT>tables</TT> addition can only appear once. However, multiple
tables can appear after it.
<LI>Do not use commas to separate parameters.
<LI><TT>tables</TT> only allows internal tables to be passed-not
database tables.
<LI>A subroutine can call another subroutine.
<LI>Recursion is supported. A subroutine can call itself or a
subroutine that calls it.
<LI>Subroutine definitions cannot be nested. (You cannot define
a subroutine within another subroutine.)
</UL>
<H4>Syntax for the perform Statement</H4>
<BLOCKQUOTE>
<PRE>
perform a) <I>s
</I> b) <I>n</I> of <I>s1</I> <I>s2</I> <I>s3</I> ...
[tables <I>t1 t2 ...</I>]
[using <I>u1 u2 ...</I>]
[changing <I>c1 c2 ...</I>].
</PRE>
</BLOCKQUOTE>
<P>
where:
<UL>
<LI><TT><I>s</I></TT><I>, </I><TT><I>s1</I></TT><I>,
</I><TT><I>s2</I></TT><I>, </I><TT><I>s3</I></TT><I>,</I>
are subroutine names.
<LI><TT><I>n</I></TT> is a numeric
variable.
<LI><TT>a)</TT> and <TT>b)</TT> are mutually exclusive.
<LI><TT>tables</TT>, <TT>using</TT>, and <TT>changing</TT> can
appear with either <TT>a)</TT> or <TT>b)</TT>.
<LI>The addition <TT>value()</TT> cannot be used with <TT>perform</TT>.
</UL>
<P>
Using syntax <TT>b)</TT> you can specify that one of a list of
subroutines be performed. The <TT><I>n</I></TT>th
subroutine in the list of subroutine names following <TT>of</TT>
is performed. For example, if <TT><I>n</I></TT>
is 2, the second subroutine in the list will be performed. Listing
17.7 illustrates this syntax.
<P>
<IMG SRC="../button/input.gif" tppabs="http://pbs.mcp.com/ebooks/0672312174/button/input.gif">
<HR>
<P>
<B>Listing 17.7 Calling a Series of Subroutines<BR>
</B>
<BLOCKQUOTE>
<PRE>
1 report ztx1707.
2 do 3 times.
3 perform sy-index of s1 s2 s3.
4 enddo.
5
6 form s1.
7 write: / 'Hi from s1'.
8 endform.
9
10 form s2.
11 write: / 'Hi from s2'.
12 endform.
13
14 form s3.
15 write: / 'Hi from s3'.
16 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 17.7 produces the following output:
<BLOCKQUOTE>
<PRE>
Hi from s1
Hi from s2
Hi from s3
</PRE>
</BLOCKQUOTE>
<P>
<IMG SRC="../button/analysis.gif" tppabs="http://pbs.mcp.com/ebooks/0672312174/button/analysis.gif">
<UL>
<LI>Line 2 begins a loop that executes three times. <TT>Sy-index</TT>
is the loop counter, and is incremented by one with each loop
pass.
<LI>The first time line 3 is executed, <TT>sy-index</TT> has a
value of 1. Therefore, the first subroutine (<TT>s1</TT>) is performed.
<LI>The second time line 3 is executed, <TT>sy-index</TT> has
a value of 2. Therefore, the second subroutine (<TT>s2</TT>) is
performed.
<LI>The third time line 3 is executed, <TT>sy-index</TT> has a
value of 3. Therefore, the third subroutine (<TT>s3</TT>) is performed.
</UL>
<H3><A NAME="LeavingaSubroutine">
Leaving a Subroutine</A></H3>
<P>
You can exit out of a subroutine at any time using the following
statements:
<UL>
<LI><TT>exit</TT>
<LI><TT>check</TT>
<LI><TT>stop</TT>
</UL>
<P>
The following paragraphs describe the effect of <TT>check</TT>
and <TT>exit</TT> when they are coded within a subroutine but
outside of a loop. The effect of <TT>stop</TT> within a subroutine
is the same, regardless of whether is it coded within a loop.
<P>
In subroutines
<UL>
<LI><TT>check</TT> and <TT>exit</TT> immediately leave the subroutine
and processing continues with the next executable statement following
<TT>perform</TT>.
<LI><TT>stop</TT> immediately <TT>leaves</TT> the subroutine and
goes directly to the <TT>end-of-selection</TT> event.
</UL>
<P>
<TT>check</TT>, <TT>exit</TT>, and <TT>stop</TT> do not set the
value of <TT>sy-subrc</TT>. If you want to set it, assign a numeric
value to it before leaving.
<P>
Listing 17.8 illustrates the effects of these statements within
subroutines.
<P>
<IMG SRC="../button/input.gif" tppabs="http://pbs.mcp.com/ebooks/0672312174/button/input.gif">
<HR>
<P>
<B>Listing 17.8 Effects of exit, check, and stop Within
a Subroutine<BR>
</B>
<BLOCKQUOTE>
<PRE>
1 report ztx1708.
2 data f1 value 'X'.
3
4 clear sy-subrc.
5 perform s1. write: / 'sy-subrc =', sy-subrc.
6 perform s2. write: / 'sy-subrc =', sy-subrc.
7 perform s3. write: / 'sy-subrc =', sy-subrc.
8 perform s4. write: / 'sy-subrc =', sy-subrc.
9
10 end-of-selection.
11 write: 'Stopped, sy-subrc =', sy-subrc.
12 if sy-subrc = 7.
13 stop.
14 endif.
15 write: / 'After Stop'.
16
17 form s1.
18 do 4 times.
19 exit.
20 enddo.
21 write / 'In s1'.
22 exit.
23 write / 'After Exit'.
24 endform.
25
26 form s2.
27 do 4 times.
28 check f1 = 'Y'.
29 write / sy-index.
30 enddo.
31 write / 'In s2'.
32 check f1 = 'Y'.
33 write / 'After Check'.
34 endform.
35
36 form s3.
37 do 4 times.
38 sy-subrc = 7.
39 stop.
40 write / sy-index.
41 enddo.
42 endform.
43
44 form s4.
45 write: / 'In s4'.
46 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 17.8 produces the following output:
<BLOCKQUOTE>
<PRE>
In s1
sy-subrc = 0
In s2
sy-subrc = 0
Stopped, sy-subrc = 7
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -