02-13-2006 8:55 PM
hi
can anyone explain me with an example how to deal with the internal tables in subroutines such as
perform using....
changing...
rg
sandeep
02-13-2006 9:00 PM
Hi Sandeep,
Please check SAP help there are some good examples avialable on this :
Example Tables :
TYPES: BEGIN OF T_X.
INCLUDE STRUCTURE SFLIGHT.
TYPES: ADDITION(8) TYPE C,
END OF T_X.
...
DATA: X TYPE STANDARD TABLE OF T_X WITH NON-UNIQUE
DEFAULT KEY INITIAL SIZE 0.
FORM U TABLES X STRUCTURE SFLIGHT.
...
PERFORM U TABLES X.
...
FORM U TABLES X STRUCTURE SFLIGHT.
WRITE: X-FLDATE.
ENDFORM.
Example for USING from SAP Help:
DATA: NUMBER_I TYPE I VALUE 5,
NUMBER_P TYPE P VALUE 4,
BEGIN OF PERSON,
NAME(10) VALUE 'Paul',
AGE TYPE I VALUE 28,
END OF PERSON,
ALPHA(10) VALUE 'abcdefghij'.
FIELD-SYMBOLS TYPE ANY.
ASSIGN NUMBER_P TO .
PERFORM CHANGE USING 1
NUMBER_I
NUMBER_P
PERSON
ALPHA+NUMBER_I().
FORM CHANGE USING VALUE(PAR_1)
PAR_NUMBER_I
PAR_NUMBER_P
PAR_POINTER
PAR_PERSON STRUCTURE PERSON
PAR_PART_OF_ALPHA.
ADD PAR_1 TO PAR_NUMBER_I.
PAR_NUMBER_P = 0.
PAR_PERSON-NAME+4(1) = ALPHA.
PAR_PERSON-AGE = NUMBER_P + 25.
ADD NUMBER_I TO PAR_POINTER.
PAR_PART_OF_ALPHA = SPACE.
ENDFORM.
Lanka
Message was edited by: Lanka Murthy
02-13-2006 9:01 PM
You can pass them thru the TABLES parameter.
report zrich_0003.
data: it001 type table of t001 with header line.
start-of-selection.
perform get_company_codes tables it001.
loop at it001.
write:/ it001-bukrs, it001-butxt.
endloop.
*&---------------------------------------------------------------------*
*& Form get_company_codes
*&---------------------------------------------------------------------*
form get_company_codes tables itab.
select * into table itab from t001.
endform.
Regards,
Rich Heilman
02-13-2006 9:08 PM
A subroutine is an internal modularization unit within a program, to which you can pass data using an
interface. You use subroutines to encapsulate parts of your program, either to make the program
easier to understand, or because a particular section of coding is used at several points in the
program. Your program thus becomes more function-oriented, with its task split into different
constituent functions, and a different subroutine responsible for each one.
As a rule, subroutines also make your programs easier to maintain. For example, you can execute them
"invisibly" in the Debugger, and only see the result. Consequently, if you know that there are no
mistakes in the subroutine itself, you can identify the source of the error faster.
Structure of a Subroutine
n A subroutine begins with the FORM statement and ends with ENDFORM.
n After the subroutine name, you program the interface. In the FORM statement, you specify the
formal parameters , and assign them types if required. The parameters must occur in a fixed
sequence - first the importing parameters, then the importing/exporting parameters. Within the
subroutine, you address the data that you passed to it using the formal parameters.
n You can declare local data in a subroutine.
n After any local data declarations, you program the statements that are executed as part of the
subroutine.
You define the way in which the data from the main program (actual parameters do1, do2, do3, and
do4) are passed to the data objects in the subroutine (formal parameters p1, p2, p3, p4) in the
interface . There are three possibilities:
n Call by reference (p1, p3)
The dereferenced address of the actual parameter is passed to the subroutine.
The USING and CHANGING additions both have the same effect (in technical terms). However,
USING leads to a warning in the program check.
n Call by value (p2)
A local "read only" copy of the actual parameter is passed to the subroutine. Do this using the form
USING value(<formal parameter>).
n Call by value and result (p4)
A local changeable copy of the actual parameter is passed to the subroutine. Do this using the form
CHANGING value(<formal parameter>).
You should use this method when you want to be sure that the value of the actual parameter is not
changed if the subroutine terminates early.
n When you use internal tables as parameters, you should use call by reference to ensure that the
system does not have to copy what could be a large internal table.
The data objects that you pass to a subroutine can have any data type . In terms of specifying data
types, there are various rules:
n You may specify the type for elementary types.
If you do, the syntax check returns an error message if you try to pass an actual parameter with a
different type to the formal parameter. Not specifying a type is the equivalent of writing TYPE ANY.
In this case, the formal parameter "inherits" its type from the actual parameter at runtime. If the
statements in the subroutine are not compatible with this inherited data type, a runtime error occurs.
Data types I, F, D, and T are already fully-specified. If, on the other hand, you use P, N, C, or X, the
missing attributes are made up from the actual parameter. If you want to specify the type fully, you
must define a type yourself (although a user-defined type may itself be generic). When you use
STRING or XSTRING, the full specification is not made until runtime.
n You must specify the type of structures and references.
n You must specify the type of an internal table, but you can use a generic type, that is, program the
subroutine so that the statements are valid for different types of internal table, and then specify the
type:
Using the corresponding interface specification:
TYPE [ANY|INDEX|STANDARD|SORTED|HASHED] TABLE,
(TYPE TABLE is the short form of TYPE STANDARD TABLE)
Using a user-defined generic table type.
When you call a subroutine, the parameters are passed in the sequence in which they are listed.
The type of the parameters and the way in which they are passed is determined in the interface
definition. When you call the subroutine, you must list the actual parameters after USING and
CHANGING in the same way. There must be the same number of parameters in the call as in the
interface definition.
The best thing to do is to define the subroutine and then use the Pattern function in the ABAP Editor to
generate the call. This ensures that you cannot make mistakes with the interface. The only thing you
have to do is replace the formal parameters with the appropriate actual parameters.
If you pass an internal table with a header line, the name is interpreted as the header line . To pass the
body of an internal table with header line, use the form <itab>[]. In the subroutine, the internal table
will not have a header line.
Example
DATA it_spfli TYPE TABLE OF spfli WITH HEADER LINE.
...
PERFORM demosub CHANGING it_spfli[].
...
FORM demosub CHANGING p_spfli LIKE it_spfli[].
DATA wa_p_spfli LIKE LINE OF p_spfli.
...
ENDFORM.
Formal parameters and local data objects that you define in a subroutine are only visible while the
subroutine is active. This means that the relevant memory space is not allocated until the subroutine
is called, and is released at the end of the routine. The data can only be addressed during this time.
The general rules are as follows:
n You can address global data objects from within the subroutine. However, you should avoid this
wherever possible, since in doing so you bypass the interface, and errors can creep into your coding.
n You can only address formal parameters and local data objects from within the subroutine itself.
n If you have a formal paramete r or local data object with the same name as a global data object, we
say that the global object is locally obscured by the local object. This means that if you address an
object with the shared name in the subroutine , the system will use the local object, if you use the
same name outside the subroutine , the system will use the global object.
Summary
n Address global data objects in the main program and, if you want to use them in the subroutine, pass
them using the interface.
n In the subroutine, address only formal parameters and local data objects.
n Avoid assigning identical names to global and local objects. For example, use a prefix such as p_
for a parameter and l_ for local data.
This example calls the subroutine demosub. It contains a local data object with a starting value, and
alters the four formal parameters.
The system allocates two memory areas p2 and p4 for the two call by value parameters d2 and d4,
and fills them with the respective values. It also allocates memory for the local data object l_do, and
fills it with the starting value.
There is no VALUE addition for p1 or p3, This means that changes at runtime affect the actual
parameters directly, and you can address do1 directly via p1.
Here, the change to p1 directly affects the contents of do1.
The formal parameter p2 is declared as a local copy with read access. This means that any changes will
not affect the actual parameter do2 at all.
The same applies to p3 as to p1. If you do not use the VALUE addition, USING and CHANGING have
the same effect.
The contents of do3 are affected directly by the changes to p3.
As for p2, we have created a local copy for p4. Consequently, the changes to the formal parameter do
not affect the actual parameter while the subroutine is running.
The changes are not written back to the actual parameters until the ENDFORM statement.
If demosub is interrupted for any reason, do4 would have the same value afterwards as it had before
the call.
Now that demosub has finished running, the memory occupied by its local data objects is released.
You now cannot address these data objects any more.
Note that do2 still has its old value, even though p2 was changed in the subroutine.
In the example here, the subroutine should work out the number of free seats on a plane based on the
aircraft type and the number of seats already occupied.
The parameters p_planetype and p_seatsocc are passed by reference to the subroutine
get_free_seats. In the interface, USING indicates that you can only access them to read them.
The result p_seatsfree, on the other hand, is returned by copying its value.
For simplicity, the main program has been restricted to a selection screen on which the user can enter
values, the subroutine call itself, and the list display.
It is technically possible to call subroutines from other main programs. However, this technique is
obsolete, and you should use function modules instead. Function modules provide considerable
advantages, and are important components in the ABAP Workbench. For further information, refer to
the unit Function Groups and Function Modules.
Another typical use of subroutines is recursive calls. Although all other modularization units can, in
principle, be called recursively, the runtime required is often excessive for small easily-programmed
recursions.
This example uses a recursive solution to find a connection between two cities. To find a connection
between A and Z, the program looks for a flight from A to B, and then from B to Z. The subroutine
find_conn calls itself.
n If there is no direct connection, the program uses the current city (p_pos) to compile a list of all
cities that can be reached (l_poss_list), that are not yet in the route list (p_step_list). The
route list is defined as a standard table so that the sequence of the cities on the route is retained.
For simplicity, the system removes duplicate entries from the list of cities. This means that the
subroutine ends up with only one possible connection.
However, it would also be possible to suppress this, and examine all of the possible connections, for
example, for the number of stopovers, total distance, and so on.
n If it is not possible to reach any cities other than those already visited on the same journey, the
current city on the route is marked as a "dead end".
n Otherwise, the cities to which it is possible to travel are processed in a loop. Each city is included in
the route list, so that the program can continue searching from here. However, before that, the
program has to check whether the city has already been marked as a dead end in a previous search.
n Once the destination is reached, we can terminate the processing. Any further search from this point
would be unsuccessful anyway. The city is marked in the route list, and the search carries on with the
next reachable city.
n The processing logic for this subroutine is contained in the function group
LBC402_SURD_RECURSION, include program LBC402_SURD_RECURSIONF01. The
subroutine is called from function module BC402_SURD_TRAVEL_LIST, which is itself called
from the executable program SAPBC402_SURD_RECURSION. This program lists all of the
possible flights in the flight data mode, and in particular those with stopovers.