Skip to end of metadata
Go to start of metadata

SUBROUTINES:
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 :

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, and p4) in the interface.
There are three possibilities:

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

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

3) 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:

1) You may specify the type for elementary types.

If you do, the syntax checks 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.

2) You must specify the type of structures and references.

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

                  How to Call Subroutine in Sap Script:-

 

Calling ABAP Subroutines: PERFORM
You can use the PERFORM command to call an ABAP subroutine(form) from any program, subject to the normal ABAP runtime authorization
Checking. You can use such calls to subroutines for carrying out calculations, for obtaining data from the database that is needed at display or print time, for formatting data, and so on.
PERFORM commands, like all control commands, are executed when a Document is formatted for display or printing.
Communication between a subroutine that you call and the document is by way of symbols whose Values are set in the subroutine.
The system does not execute the PERFORM command within SAP script replace modules, such as TEXT_SYMBOL_REPLACE or
TEXT_INCLUDE_REPLACE.
The replace modules can only replace symbol values or resolve include Texts, but not interpret SAP script control commands.
Syntax in a form window:
/: PERFORM <form> IN PROGRAM <prog>
/: USING &INVAR1&
/: USING &INVAR2&
......
/: CHANGING &OUTVAR1&
/: CHANGING &OUTVAR2&
......
/: ENDPERFORM
INVAR1 and INVAR2 are variable symbols and may be of any of
the four
SAP script symbol types.
OUTVAR1 and OUTVAR2 are local text symbols and must
therefore be
Character strings.
The ABAP subroutine called via the command line stated
above must be
defined in the ABAP report prog as follows:
FORM <form> TABLES IN_TAB STRUCTURE ITCSY
OUT_TAB STRUCTURE ITCSY.
...
ENDFORM.
The values of the SAP script symbols passed with /: USING...
are now
Stored in the internal table IN_TAB. Note that the system
passes the
values as character string to the subroutine, since the
field Field VALUE in structure ITCSY has the domain TDSYMVALUE (CHAR
80). See the
Example below on how to access the variables.
The internal table OUT_TAB contains names and values of the
CHANGING
Parameters in the PERFORM statement. These parameters are
local text
Symbols, that is, character fields. See the example below
on how to
Return the variables within the subroutine.
From within a SAP script form, a subroutine GET_BARCODE in
the ABAP
Program QCJPERFO is called. Then the simple barcode
contained there
('First page', 'Next page', 'Last page') is printed as
local variable
Symbol.
Definition in the SAP script form:
/: PERFORM GET_BARCODE IN PROGRAM QCJPERFO
/: USING &PAGE&
/: USING &NEXTPAGE&
/: CHANGING &BARCODE&
/: ENDPERFORM
/
/ &BARCODE&
Coding of the calling ABAP program:
REPORT QCJPERFO.
FORM GET_BARCODE TABLES IN_PAR STUCTURE ITCSY
OUT_PAR STRUCTURE ITCSY.
DATA: PAGNUM LIKE SY-TABIX, "page number
NEXTPAGE LIKE SY-TABIX. "number of next page
READ TABLE IN_PAR WITH KEY 'PAGE'.
CHECK SY-SUBRC = 0.
PAGNUM = IN_PAR-VALUE.
READ TABLE IN_PAR WITH KEY 'NEXTPAGE'.
CHECK SY-SUBRC = 0.
NEXTPAGE = IN_PAR-VALUE.
READ TABLE OUT_PAR WITH KEY 'BARCODE'.
CHECK SY-SUBRC = 0.
IF PAGNUM = 1.
OUT_PAR-VALUE = '|'. "First page
ELSE.
OUT_PAR-VALUE = '||'. "Next page
ENDIF.
IF NEXTPAGE = 0.
OUT_PAR-VALUE+2 = 'L'. "Flag: last page
ENDIF.
MODIFY OUT_PAR INDEX SY-TABIX.
ENDFORM.

 

 

  • No labels