Thursday, September 20, 2012

Lesson 23 Sub Routines in ABAP

A subroutine in ABAP 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

A subroutine begins with the FORM statement and ends with ENDFORM.

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.

You can declare local data in a subroutine.

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:

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.

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().

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().

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.

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:

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.

You must specify the type of structures and references.

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 []. In the subroutine, the internal table will not have a header line.

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:

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.

You can only address formal parameters and local data objects from within the subroutine itself.

If you have a formal parameter 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

Address global data objects in the main program and, if you want to use them in the ubroutine, pass them using the interface.

In the subroutine, address only formal parameters and local data objects.

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.

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.

No comments:

Post a Comment