Skip to Content

Background

Our BW developers frequently use a start routine in transformations to manipulate records of the DTP source package. Wanting to write reusable code, they perform the bulk of this source package manipulation in function modules. To pass a source package to its corresponding function module, they had been defining a structure in the data dictionary that exactly duplicates the source package structure from the start routine.

Defining a dictionary structure for each DTP source package processed by a function module is a lot of work though, so our BW developers posed the question of whether there is an alternate approach.

An Alternate Approach

It is possible to pass the DTP source package– indeed any internal table– to a function module, subroutine or other procedure using a generic table type. Doing so removes the burden of having to define a static structure in the data dictionary to match the source package structure. The trade-off is that instead of directly referencing source package fields at design-time, the developer must instead use field-symbols to reference any individual field or record in the generically typed source package.

The Function Module Interface

Instead of defining the source package in the function module interface as a statically typed table, define a changing parameter of type standard table. We use standard table and not any table so that we may perform operations on the source package that require a table index, e.g., deleting records.

Capture.JPG

The remainder of this document gives code examples of various operations that might be performed on the generically typed source package and shows how to implement these operations using field-symbols.

Code Examples

Sort the Source Package

DATA ls_sort_field  TYPE abap_sortorder.
DATA lt_sort_fields TYPE abap_sortorder_tab.
* Append, in order, the fields by which to sort source_package
ls_sort_field-name           = 'FIELDNAME'.
ls_sort_field-descending = abap_true.
ls_sort_field-astext          = abap_false.
APPEND ls_sort_field TO lt_sort_fields.
SORT source_package BY (lt_sort_fields).

Create a Structure Having the Line Type of Source Package

DATA line_reference TYPE REF TO data.
FIELD-SYMBOLS <source_package_line> TYPE ANY.
CREATE DATA line_reference LIKE LINE OF source_package.
ASSIGN line_reference->* TO <source_package_line>.

Create a Local Copy of the Source Package

DATA table_reference TYPE REF TO data.
FIELD-SYMBOLS <copy_of_source_package> TYPE STANDARD TABLE.
CREATE DATA table_reference LIKE source_package.
ASSIGN table_reference->* TO <copy_of_source_package>.
<copy_of_source_package> = source_package.

Read Source Package Records

FIELD-SYMBOLS <source_package_line> TYPE ANY.
READ TABLE source_package ASSIGNING <source_package_line>
                       WITH KEY ('FIELDNAME') = some_value
                       BINARY SEARCH. " binary search only if source_package is sorted

Loop Through the Source Package

FIELD-SYMBOLS <source_package_field> TYPE data_element.
* We cannot use a WHERE condition with a generically typed field-symbol, but the
* following is equivalent to LOOP AT source_package WHERE fieldname = some_value
LOOP AT source_package ASSIGNING <source_package_line>.
     ASSIGN COMPONENT 'FIELDNAME'
                   OF STRUCTURE <source_package_line> TO <source_package_field>.
     CHECK <source_package_field> = some_value.
     ...
ENDLOOP.

Append New Records to Source Package

FIELD-SYMBOLS <source_package_field> TYPE data_element.
LOOP AT some_other_table INTO workarea.
*    This assignment assumes <source_package_line> has been defined as in the
*    earlier example to have the same line type as source_package
     ASSIGN COMPONENT 'FIELDNAME'
                   OF STRUCTURE <source_package_line> TO <source_package_field>.
     <source_package_field> = workarea-some_value.
     ...
     APPEND <source_package_line> to source_package.
ENDLOOP.


Delete Records from Source Package

LOOP AT source_package ASSIGNING <source_package_line>.
     ...
     DELETE source_package.
ENDLOOP.
To report this post you need to login first.

4 Comments

You must be Logged on to comment or reply to a post.

  1. Arunan C

    Hello Amy,

    This is really cool. Thanks for sharing. You have mentioned avoiding lots of work as advantage for using a generic table type. But we had a more serious problem. Our DSO structure kept changing with time and whenever we had a change, we had to check the impact to the function module and take care of implementing the changes in many places incase of static dictionary tables. We too implemented this approach in your blog. Now I wonder why didn’t I blog about it? 😛

    The abstraction of start routine logic in function module is also particularly useful when there are different source systems loading to different region DSOs. In this case change in business logic can be implemented in one single place.

    Regards,

    Arunan C

    (0) 
    1. Amy King Post author

      Hi Arunan,

      Agreed, not having to update a static dictionary definition whenever a DSO structure changes is one of the benefits of the approach and was also a main concern of our BW developers.

      I’m glad you liked the document; you’ll have to blog about the next cool thing you do. 🙂

      Cheers,

      Amy

      (0) 

Leave a Reply