Additional Blogs by Members
cancel
Showing results for 
Search instead for 
Did you mean: 
MarcinPciak
Active Contributor
0 Kudos

When talking about typing there is also a topic which requires some attention, namely interface parameter typing. The interface here refers to procedure's signature. From developers point of view this is like creating an API and exposing it to world. In other languages like C or VB, we usually see only this procedure interface as an entry point to some functional code behind it. This code can be hashed so it might not be seen by developer. We must therefore ensure that parameters we are passing are correctly typed.

 

Glossary

Before we start talking a little bit about the parameters themselves, I want you to get familiarized with the correct naming. In ABAP world, the procedure is code of block which has a signature (or interface), bodyand is reusable. So the procedure can be a Function Module, a Subroutineor a Method. The signature is nothing but how the procedure is seen outside (how it is exposed to the world). The body can be hidden (hashed) and is the actual code executed by procedure. I this blog I will be using name procedure when referring to any of the above. If referring to any specific I will directly point that out.

 

Local and global typing

In general you can use only global types (DDIC ones) for Function Modules' and Methods' parameters, and either local or global ones for Subroutines'. This however can be overcome, but is off-topic here.

 

Genericity

This term you might be already familiar with, or at least you have heard of that. Generic is something that is specified partly or is not specified at all. In ABAP it especially applies to typing parameters and field symbols. Saying that parameter is of generic type, means that developer (who uses the procedure) knows a little or knows nothing about the type of the parameter that should be passed. This implies that he/she can pass "partly any" or any data object he/she wants.

Let's have a look at the below table of how SAP categorizes parameter typing:

                                                     
 

Category

 
 

Generic formal data type

 
 

Possible actual data type

 
 

Fully generic

 
 

ANY

 
 

Any data type

 
 

Table-like

 
 

ANY TABLE

 
 

Any table   data type

 
 

Index-accessed   table

 
 

INDEX TABLE

 
 

STANDARD/SORTED   table data type

 
 

Standard   table

 
 

STANDARD TABLE, TABLE

 
 

Any   standard table data type

 
 

Sorted   table

 
 

SORTED TABLE

 
 

Any   sorted table data type

 
 

Hashed   table

 
 

HASHED TABLE

 
 

Any   hashed table data type

 
 

Structure-like

 
 

STRUCTURE

 
 

Any DDIC   structure data type (obsolete)

 
 

Elementary,   flat

 
 

c, n, x, p

 
 

Data type   of respective elementary type without length specification

 

 

As you can see parameter of type ANY really accepts data object of ANY data type. The similar is with type ANY TABLE.

 

Shopping relevance

You may think I am crazy but I think the generic typing has much more to do with shopping then we would think. Imagine that a wife (apologies to Ladies and bachelors) sends you to do the shopping in a supermarket. You get the following list of items:

  • 0,5 kg Apples
  • Potatoes
  • One can of spinach
  • 5 tomatoes
  • Some snacks
  • Milk
  • Beer

Such list would make me a little bit confused. While it is very clear to me that under beer she most probably meant six-pack 😉 I am desperately trying to figure out what she meant by Potatoes or Some snack. I am not quite sure whether we need 1kg or 2kg of the former, and which snack she feels like having. Basically we can categorize above lists into several groups:

           
 

I am sure what to buy

 
 

I am not quite sure - I will be guessing or I   will call her

 
 

I have no clue what she meant

 
 

0,5 kg Apples,

 

5   tomatoes,

 

One can   of spinach

 
 

Milk (1   or 2 cartons, how much fat),

 

Beer   (actually she might want some for her)

 
 

Some   snack (I probably buy any)

 

 

The things "I am sure about" in ABAP would map to fully specified. The things "I am not quite sure" in ABAP would be those semi specified (or semi generic). The ones "I have no clue about" are those fully generic.

 

Responsibility

While for shopping list I am taking full responsibility for not being smart enough to figure out what my wife has meant, in ABAP the original developer is the one who must assure data correctness (as different developers under "any" might understand something different).

If we create i.e. Function Module with parameter ANY TABLE we must ensure we are not trying to use it in any type specific operation i.e. the following would cause syntax error:

READ TABLE itab ... INDEX i_index.

Obviously we are trying to access the table via INDEX, but the table can be either STANDARD, SORTED or HASHED one. The last one can only be accessed by key. So although the above seems syntactically correct we would get the error as the system is not sure which kind of table we really mean. In order we could run the program we must change the parameter to typed as INDEX TABLE. This way we restrict "consumer" (developer) to pass only STANDARD or SORTED table, thereby making our function less generic (more specified).

 

Possibilities

The rule is simple, the more generic program is, the more useful it may become. However always you should not overuse this programming "feature". At first place try to provide fully specified type, then if really necessary go for more generic typing.

Example

Let's say we have the developed a generic READ function, which returns the record of any internal table we pass to the function either via index or key access. This function could look like

FUNCTION Z_FM_READ_LINE .
*"----------------------------------------------------------------------
*"*"Local Interface:
*"  IMPORTING
*"     REFERENCE(ITAB) TYPE  INDEX TABLE
*"     REFERENCE(I_KEY_FIELD) TYPE  STRING OPTIONAL
*"     REFERENCE(I_KEY_VALUE) TYPE  ANY OPTIONAL
*"     REFERENCE(I_INDEX) TYPE  I OPTIONAL
*"  EXPORTING
*"     REFERENCE(ES_LINE) TYPE  ANY
*"----------------------------------------------------------------------

  IF i_index IS SUPPLIED.
    IF i_index IS NOT INITIAL.
      READ TABLE itab INTO es_line INDEX i_index.
    ENDIF.
  ELSE.
    READ TABLE itab WITH KEY (i_key_field) = i_key_value into es_line.
  ENDIF.

ENDFUNCTION.

For importing parameters we used a fully specified i_key_fieldand i_index, a semi specified table (index table) and fully generic i_key_value(as we can pass any data object here) and es_line(return any structure line we want).

 

Formal vs actual parameter

Formal parameter is the one which a procedure has in its signature (interface), while the actualis the one passed to the procedure during its call. Therefore the formal parameter data type is the one which the parameter is typed with, while the actual has the type of real passed data object. During procedure call the formal parameter receives the actual one's type.

Formal parameter data type must therefore always be at least as "wide" as the actual parameter (or wider - more generic), but never vice versa. It must be possible to system to perform casting during parameter passing.

Note!

This restriction is especially important when passing object references, where casting to parent object is always possible, but to child object not necessarily. This is also a subject for dynamic casting operator ?= . Don't worry, we won't go as deep in our considerations here. This might be a topic for some next blogs.

 

No static component

Another point to consider is that by making es_linegeneric, we can't access its components in the function directly, like

es_line-carrid = … 
es_line-connid = …

This is simply because we don't statically know whether this work area will ever receive the line type which has CARRID or CONNID components. This is only known during runtime - dynamically. So we say, the statictype of work area es_line (type of formal parameter) is generic but the dynamic one (type of actual parameter passed to procedure) will be as line of the table passed to FM.

Therefore in order we could access any of its components, we need to do this dynamically. This is the point where field symbols come into play.

Note!

Typing and working with field symbols is a task for next classes so I won't be discussing it here now.

 

This small piece of code is quite powerful and we could it is such program

DATA: gt_scarr   TYPE STANDARD TABLE OF scarr,
      gt_sflight TYPE SORTED TABLE OF sflight WITH UNIQUE KEY carrid connid fldate.
DATA: wa_scarr   TYPE scarr,
      wa_sflight TYPE sflight.

SELECT * FROM scarr INTO TABLE gt_scarr UP TO 10 ROWS.

SELECT * FROM sflight INTO TABLE gt_sflight
         FOR ALL ENTRIES IN gt_scarr
         WHERE carrid = gt_scarr-carrid.

DESCRIBE TABLE gt_scarr.

DO sy-tfill TIMES.
  CALL FUNCTION 'Z_FM_READ_LINE'
    EXPORTING
      itab    = gt_scarr
      i_index = sy-index
    IMPORTING
      es_line = wa_scarr.

  CALL FUNCTION 'Z_FM_READ_LINE'
    EXPORTING
      itab        = gt_sflight
      i_key_field = 'CARRID'
      i_key_value = wa_scarr-carrid
    IMPORTING
      es_line     = wa_sflight.

  IF wa_scarr   IS NOT INITIAL AND
     wa_sflight IS NOT INITIAL.
    WRITE: / 'First scheduled flight number for ', wa_scarr-carrid,
           ' is ',wa_sflight-connid,
           ' which departs on ', wa_sflight-fldate.
  ENDIF.

  CLEAR: wa_scarr, wa_sflight.
ENDDO.

The real examples are of course more useful and usually advanced then just reading a line of a table, but it basically shows how generic parameter nature makes the code more reusable.

 

Further grouping

Another grouping SAP uses for generic typing is the following

                                 
 

Category

 
 

Generic formal data type

 
 

Possible actual data type

 
 

Elementary,   flat

 
 

SIMPLE

 
 

Any   elementary data type; flat, character structure

 
 

Numeric

 
 

NUMERIC

 
 

Numeric   data types: i, f, p

 
 

Character-like

 
 

CLIKE

 
 

Text-like   data type: c,n,d,t,string

 
 

CSEQUENCE

 
 

Character-like   data type: c, string

 
 

Hexadecimal

 
 

XSEQUENCE

 
 

Byte-like   data type: x, xstring

 

 

These categories are stricter in terms of actual parameter typing, but still allow the developer to work with partly generic data.

 

Preferred order

The order in which we should consider parameter typing is the following

  • Fully specified DDIC types
  • Fully specified local types (for      subroutines only!)
  • Semi specified types -      STANDARD/SORTED/HASHED TABLE, elementary, flat data types
  • Semi specified types - INDEX TABLE, NUMERIC,      CSEQUENCE, XSEQUENCE
  • Semi generic types - CLIKE
  • Semi generic types - SIMPLE
  • Fully generic types - ANY, ANY TABLE

 

Of course the choice depends on different factors i.e. whether we want to use the procedure only for purpose of certain program. Usually there is no need to create highly generic routines just for usage of one program, but on the other hand there is sometimes no point in creating a function module just for one time and case use. So you should always try to balance this thing.

Anyhow the choice should be always made by asking yourself a question in this regard keeping in mind the order of typing to consider.

 

One more way for generic typing

Before we sum up I want you to be aware of one more thing. You can pass the parameter generically by means of its data reference(pointer). Please do not confuse it with passing by reference (the other way is passing by value).

The genericdata reference is of type

type ref to data

The same we have for objects (those typed as ref to class)

type ref to object

This means we can pass reference of any data object we want and later in the procedure body we can dereference it using field symbols (also casting here is possible).  More on this will come in the next part of this blog series.

Note!

Such formal parameter should be treated with special care as actual parameter can pass any reference. So it is like using generic type ANY, but it simply comes in form of a pointer to any data object, rather as data object itself.

 

Conclusion

Although generic parameter typing is tempting, as you can work with partly any or entirely any data object you want, it is also very error prone. You should always try to type the parameter as much specified as it is possible and use more generic types only if the first fails. Well, the true is that this creates opportunities to developer, but also leaves all the responsibility for any inconsistencies in the procedure coming through the generic nature of the formal parameters.

Generic typing is also very useful in combination with field symbols. But this is a subject for next reading...

 

 

1 Comment