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:
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.