Making ABAP programs forget

In ABAP, everything that executes ABAP code is a program:

  • Reports are programs
  • Module pools are programs
  • Function groups are programs
  • Even classes are programs

Sometimes we wish that these programs forgot about things.

Example:
When we use a BAPI function to create many documents in a row (say Incoming Invoices) and that BAPI was NOT tested for that scenario.
We end up getting the first document right, and all the others with something a bit off. After countless hours of painful debugging (standard code wasn’t really meant for you to debug it anyway) you find out that some internal table hidden deep down the stack from the BAPI had some data left uncleared from the previous calls.

If we could make programs forget everything (meaning having all their variables cleared, as if it they had just been loaded) whenever we wanted, those precious hours could be spared.

Well, that’s exactly what this little FORM routine does:

*&---------------------------------------------------------------------*
*&      Form  clear_global_data
*&---------------------------------------------------------------------*
*       Clears all the global variables in a program/module poool/
*        function group.
*----------------------------------------------------------------------*
*      -->P_REPID    Program name
*----------------------------------------------------------------------*
form clear_global_data using p_repid.
  data: lt_globals type table of rfieldlist,
        lv_fieldname type string.

  field-symbols: <global> like line of lt_globals,
                 <field> type any,
                 <table> type any table.

  "// Get all the global variables' names
  call function 'GET_GLOBAL_SYMBOLS'
    exporting
      program   = p_repid
    tables
      fieldlist = lt_globals.

  "// Clear them
  loop at lt_globals assigning <global>
    where
      name(1) na '<%' and "// Don't touch field-symbols
      name <> 'SY' and
      name <> 'SYST' and
      flitl is initial. "// neither read-only variables
    "// Cross-program field-symbols access, format: '(PROGRAM)VARIABLE'
    concatenate '(' p_repid ')' <global>-name into lv_fieldname.
    case <global>-type.
      when cl_abap_typedescr=>typekind_table. "// Table
        assign (lv_fieldname) to <table>.
        if sy-subrc = 0.
          free <table>.
        endif.
      when others. "// Anything else
        assign (lv_fieldname) to <field>.
        if sy-subrc = 0.
          free <field>.
        endif.
    endcase.
  endloop.
endform.                    "clear_global_data

You give it a program name, and if automatically makes this program forget everything. It just calls FREE on every one of its modifiable global variables.

Try it out! Here’s a little example to show how it works:
Without calling the clear_global_data routine, the log message gets saved. You can see it in transaction SLG1:
The SLG1 selection screen
The log message in SLG1

Now if you let it call the clear_global_data routine, the message won’t be saved.

data: s_log type bal_s_log,
      v_log_handle type balloghndl.

"// Create a new Log handle
s_log-object = 'ALERT'.
s_log-subobject = 'DELIVER'.

call function 'BAL_LOG_CREATE'
  exporting
    i_s_log                 = s_log
  importing
    e_log_handle            = v_log_handle
  exceptions
    log_header_inconsistent = 1
    others                  = 2.
if sy-subrc <> 0.
  message id sy-msgid type sy-msgty number sy-msgno
    with sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
endif.

"// Add a text message to the log
call function 'BAL_LOG_MSG_ADD_FREE_TEXT'
  exporting
    i_log_handle     = v_log_handle
    i_msgty          = 'S'
    i_text           = 'You have successfuly added this message!'
  exceptions
    log_not_found    = 1
    msg_inconsistent = 2
    log_is_full      = 3
    others           = 4.
if sy-subrc <> 0.
  message id sy-msgid type sy-msgty number sy-msgno
    with sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
endif.

"//
"// If this line is executed, the messages will NOT be saved.
"//
perform clear_global_data using 'SAPLSBAL'.

"// Save the log
call function 'BAL_DB_SAVE'
  exporting
    i_save_all       = 'X'
  exceptions
    log_not_found    = 1
    save_not_allowed = 2
    numbering_error  = 3
    others           = 4.
if sy-subrc <> 0.
  message id sy-msgid type sy-msgty number sy-msgno
    with sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
endif.
 

abapninja

A coder/dancer/actor/singer, usually in that order. Works as an SAP consultant/developer, and loves to tinker with software.