Modularization: Includes, Subroutines & Macros

Includes are just inserted text; they can't be run alone.

12.1 Overview

Methods (local/global classes) Encapsulated, typed, testable Function modules Global, RFC-capable, update tasks

Still needed (RFC, BAPI, update, legacy APIs) Subroutines (FORM/PERFORM) Obsolete — read, don't write Macros (DEFINE) Obsolete, not debuggable Source code splitting Structural only, no own context

12.2 Includes

Includes are just inserted text; they can't be run alone. Function groups and module pools generate a standard include structure (L<fg>TOP, L<fg>UXX, …).

REPORT zorders_report.
INCLUDE zorders_top.    " global data declarations
INCLUDE zorders_sel.    " selection screen
INCLUDE zorders_c01.    " local classes
INCLUDE zorders_f01.    " subroutines (legacy)

12.3 Subroutines (legacy)

Parameter passing: USING (by reference unless VALUE( )), CHANGING (by reference, or VALUE( ) = copy-in/copy-out), TABLES (obsolete). Forms see all global data, which makes them hard to test — replace with methods of a local class.

DATA gv_result TYPE i.

START-OF-SELECTION.
  PERFORM add_numbers USING 3 4 CHANGING gv_result.
  WRITE gv_result.

FORM add_numbers USING    iv_a TYPE i
                          iv_b TYPE i
                 CHANGING cv_sum TYPE i.
  cv_sum = iv_a + iv_b.
ENDFORM.

12.4 Macros (legacy)

Macros can't be debugged step by step and hide logic. Use methods or VALUE instead.

DEFINE add_row.
  APPEND VALUE #( id = &1 name = &2 ) TO lt_items.
END-OF-DEFINITION.

add_row 1 'Alpha'.
add_row 2 'Beta'.

12.5 Local classes as the modern replacement

REPORT zcalc.

CLASS lcl_calculator DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS add IMPORTING iv_a TYPE i iv_b TYPE i RETURNING VALUE(rv_sum) TYPE i.
ENDCLASS.

CLASS lcl_calculator IMPLEMENTATION.
  METHOD add.
    rv_sum = iv_a + iv_b.
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.
  WRITE lcl_calculator=>add( iv_a = 3 iv_b = 4 ).