Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

internal table in subroutines

Former Member
0 Kudos
1,691

hi

can anyone explain me with an example how to deal with the internal tables in subroutines such as

perform using....

changing...

rg

sandeep

3 REPLIES 3

Former Member
0 Kudos
217

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

RichHeilman
Developer Advocate
Developer Advocate
0 Kudos
217

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

former_member181966
Active Contributor
0 Kudos
217

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.