Pages

Buy

Buy

Free global data of a program at once

At the very begining when I started to develop in ABAP I was wondering why I cannot clear all global data at once after I do all my calculations? As this is something that it's very useful when you create a report which just show some figures and you don't need anymore all the internal tables or objects that you used to prepare output table. So to free memory then just before calling ALV I was always refreshing all tables and clearing work areas, but this was something that had to be done manually so I was a little bit angry that I cannot automize it... and then I started to look for the way how to automize it.

I knew that SE80 is displaying all globals but I couldn't find how it's done there. As you may know debuggin the code which was done by SAP is creepy usually and after spending some hours on that I gave up. But it returned someday I just simply saw FM 'RS_PROGRAM_INDEX' and that was enough to create fast a method to free all global data for me.

So let's start with definition. We will need a range type which we will use to call the method with objects to be excluded from clearing (like ALV output table or ALV objects)

types: tt_ra_scompo_name type range of scompo-name .
types: t_scompo_name type line of tt_ra_scompo_name .       
type-pools abap .
constants cname_cl_gui_custom_container type abap_abstypename value '\CLASS=CL_GUI_CUSTOM_CONTAINER'
constants cname_cl_gui_textedit type abap_abstypename value '\CLASS=CL_GUI_TEXTEDIT'
constants cname_cl_gui_alv_grid type abap_abstypename value '\CLASS=CL_GUI_ALV_GRID'
 
Method definition is simple, just the table with excluded objects and program name.

   class-methods free_global_data
      
importing
        !it_exclude type tt_ra_scompo_name optional
        !i_program type syst-repid
      preferred 
parameter it_exclude .
Implementation of the method:
method free_global_data.
  field-symbols<any> type any,
                 <comp> type scompo,
                 <token> type stoken,
                 <ccont> type ref to cl_gui_custom_container,
                 <textedit> type ref to cl_gui_textedit,
                 <alvgrid> type ref to cl_gui_alv_grid.

  typestype_tokens     type table of stoken ,
         type_statements type table of sstmnt,
         type_levels     type table of slevel.

  datam_k(30value 'CONSTANTS'.
  datamt_src        type table of string,
        mt_tokens     type type_tokens     ,
        mt_statements type type_statements ,
        mt_keywords   like table of m_k,
        mt_levels     type type_levels  ,
        m_overflow(4096).

  datam_lenght type i.
  datam_shift type i.
  datamt_compo type table of scompo.
  datamt_cross_ref type table of cross.
  datamt_inc type table of d010inc.
  datams_exclude like line of it_exclude.
  datamt_exclude type tt_ra_scompo_name.
  datam_compname(255type c.
  datam_classref type ref to cl_abap_typedescr.
  datam_classname type abap_abstypename.

  "selecting global data names
  call function 'RS_PROGRAM_INDEX'
    exporting
      pg_name             i_program
*   WITHOUT_TREE        = ' '
* IMPORTING
*   MESSAGE_CLASS       = MESSAGE_CLASS
    tables
      compo               mt_compo
      cross_ref           
mt_cross_ref
      inc                 
mt_inc
   
exceptions
     syntax_error        1
     others              2.

  check sy-subrc eq 0.

  "selecting constants to avoid dump
  append m_k to mt_keywords.
  read report i_program into mt_src.

  scan abap-source mt_src
      tokens     
into mt_tokens
      statements 
into mt_statements
      keywords   
from mt_keywords
      levels     
into mt_levels
      
with includes
      
with list tokenization
      preserving identifier escaping
      
frame program   from i_program.

  sort mt_tokens by str ascending.

  "let's find all variables with length definition like var(5) type c
  "and shift it's name to var
  loop at mt_tokens assigning <token> where str ca '()'.
    find '(' in <token>-str.
    <token>-str <token>-str+0(sy-fdpos).
  endloop.

  "if we do not want to exclude any global data then the range is empty,
  "if we let it like this then we will not clear anything
  if it_exclude[] is initial.
    clear ms_exclude.
    ms_exclude-sign 'I'.
    ms_exclude-option 'EQ'.
    ms_exclude-low 'ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ'.
    append ms_exclude to mt_exclude.
  else.
    mt_exclude[] it_exclude[].
  endif.

  "we ommit field symbols as they will be cleared when source data
  "will be cleared.
  loop at mt_compo assigning <comp> where name not in mt_exclude[]
                                    
and   type eq 'D'
                                    and   name na '<>'.

    read table mt_tokens with key str <comp>-name
                                  
transporting no fields binary search.
    if sy-subrc ne 0.
      unassign <any>.
      clear m_compname.
      concatenate '(' i_program ')' <comp>-name into m_compname.
      assign (m_compnameto <any>.
      if <any> is assigned and sy-subrc eq 0.
        m_classref ?=  cl_abap_classdescr=>describe_by_data<any> ).
        if sy-subrc eq and m_classref->kind eq 'R'.
          m_classname cl_abap_classdescr=>get_class_name<any>  ).
          case m_classname.
            when cname_cl_gui_custom_container.
              assign <any> to <ccont>.
              if <ccont> is not initial.
                <ccont>->free(
                  exceptions
                    cntl_error        1
                    cntl_system_error 2
                    others            3
                       ).
                if sy-subrc <> 0.
*
                endif.
              endif.
            when cname_cl_gui_alv_grid.
              assign <any> to <alvgrid>.
              <alvgrid>->free(
                exceptions
                  cntl_error        1
                  cntl_system_error 2
                  others            3
                     ).
              if sy-subrc <> 0.
*
              endif.
            when cname_cl_gui_textedit.
              assign <any> to <textedit>.
              <textedit>->free(
                exceptions
                  cntl_error        1
                  cntl_system_error 2
                  others            3
                     ).
              if sy-subrc <> 0.
*
              endif.
          endcase.
        endif.
        freem_classnamem_classref.
        free <any>clear <any>.
      endif.

      "now try free table, as the one with header line will not
      "be cleared by previous assigment.
      unassign <any>.
      clear m_compname.
      concatenate '(' i_program ')' <comp>-name '[]' into m_compname.
      assign (m_compnameto <any>.
      if <any> is assigned and sy-subrc eq 0.
        free <any>.clear <any>.
      endif.

    endif.
  endloop.

endmethod.
 Example of use: (we can use * in names for faster exclusion)
datafr_exclude type zcl_my_special_class=>tt_ra_scompo_name.
datafs_exclude like line of fr_exclude.

  fs_exclude-sign 'I'.
  fs_exclude-option 'EQ'.
  fs_exclude-low 'GT_PARAMS'.
  append fs_exclude to fr_exclude.
  fs_exclude-option 'CP'.
  fs_exclude-low 'G_DYNPRO_*'.
  append fs_exclude to fr_exclude.
  fs_exclude-option 'CP'.
  fs_exclude-low 'G_DYN_*'.
  append fs_exclude to fr_exclude.


  zcl_my_special_class=>free_global_data(
         it_exclude fr_exclude
         i_program  
sy-repid  ).

1 comment: