Criando Objetos / Chamando Métodos Dinamicamente

Na busca pela solução de um problema, debugando, debugando e debugando novamente, me deparei com a criação dinâmica de objetos.

Estudando mais a fundo, eis que surge assunto para mais um post! Afinal, quanto mais dinâmicos forem os programas e API´s, melhor será sua performance e re-usabilidade.

O que faz com que consigamos criar o objeto / chamar o método dinamicamente, é a utilização de uma tabela, na qual informamos todos os parâmetros necessários (seja de importing, exporting, changing, etc), ou seja, podemos popular esta tabela de acordo com nossa necessidade em determinado ponto do programa.

Utilizei como exemplo, a criação de um objeto com referência à classe ‘CL_GUI_ALV_GRID’, o qual chamei de r_grid.

Para facilitar o entendimento, segue abaixo o Pattern (modelo) da criação estática deste objeto:

 

CREATE OBJECT r_grid
    EXPORTING
*      i_shellstyle      = 0
*      i_lifetime        =
      i_parent          = r_container
*      i_appl_events     = space
*      i_parentdbg       =
*      i_applogparent    =
*      i_graphicsparent  =
*      i_name            =
*      i_fcat_complete   = space
*    EXCEPTIONS
*      error_cntl_create = 1
*      error_cntl_init   = 2
*      error_cntl_link   = 3
*      error_dp_create   = 4
*      others            = 5.

OBS: o objeto r_container é do ripo CL_GUI_CUSTOM_CONTAINER , criado estaticamente no código abaixo.

Vamos criar o objeto apenas informando o parâmetro obrigatório ‘I_PARENT’, e para isso, utilizaremos uma workarea do tipo abap_parmbind, e uma tabela tipo abap_parmbind_tab, denominadas lwa_param e lt_param respectivamente.

Na propriedade ‘Name’ sempre informaremos o parâmetro, neste caso ‘I_PARENT’.

Na propriedade ‘Kind’, o tipo (Exporting, conforme modelo estático).

Para informar o tipo, precisamos utilizar os atributos da classe ‘CL_ABAP_OBJECTDESCR’, com isso, teremos:

lwa_param-kind = cl_abap_objectdescr=>exporting.

Por fim, necessitamos informar o valor atribuído a este parâmetro, e conforme podemos verificar no código abaixo, o valor é o objeto r_container (objeto de referência a classe CL_GUI_CUSTOM_CONTAINER).

Desta forma, necessitamos incluir a referência do objeto na tabela:

GET REFERENCE OF r_container INTO lwa_param-value.

Agora é só inserirmos nossa workarea na tabela e criarmos o objeto / chamarmos o método (não se esqueça de utilizar o try-catch, de forma a tratar possíveis exceções).

Obs: Verifique a sintax de chamada do método / criação do objeto. Observe que cria-se o objeto do tipo de uma classe (informada na variável lv_type) com os parâmetros inseridos na tabela.

REPORT  z_create_dinnam.

  TYPE-POOLS: abap.

  DATA: lt_param   TYPE abap_parmbind_tab,
        lwa_param  TYPE abap_parmbind.

  DATA: lv_type    TYPE string,
        lv_exc_txt TYPE string.

  DATA: r_except    TYPE REF TO cx_root,
        r_grid      TYPE REF TO cl_gui_alv_grid,
        r_container TYPE REF TO cl_gui_custom_container.

  CLEAR:   lt_param, lwa_param, lv_type, lv_exc_txt.
  REFRESH: lt_param.

*--------------------------------------------------------------------*
START-OF-SELECTION.

  CREATE OBJECT r_container
    EXPORTING
      container_name              = 'CONTAINER_1'
    EXCEPTIONS
      cntl_error                  = 1
      cntl_system_error           = 2
      create_error                = 3
      lifetime_error              = 4
      lifetime_dynpro_dynpro_link = 5
      OTHERS                      = 6.
  IF sy-subrc NE 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
               WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.

*--------------------------------------------------------------------*
  CLASS cl_abap_objectdescr DEFINITION LOAD.

  lv_type = 'CL_GUI_ALV_GRID'.

  lwa_param-name = 'I_PARENT'.
  lwa_param-kind = cl_abap_objectdescr=>exporting.
  GET REFERENCE OF r_container INTO lwa_param-value.
  INSERT lwa_param INTO TABLE lt_param.

*--------------------------------------------------------------------*

  TRY .
      CREATE OBJECT r_grid
        TYPE
          (lv_type)
        PARAMETER-TABLE
          lt_param.

    CATCH cx_sy_create_object_error INTO r_except.
      lv_exc_txt = r_except->get_text( ).
      MESSAGE lv_exc_txt TYPE 'I'.

  ENDTRY.

Fica o desafio: que tal chamar um método dinamicamente e utilizar uma tabela de excessão? Ela funciona da mesma maneira para recuperar as exceções lançadas pelos métodos. Pesquise, tente fazer e em caso de dúvidas, entre em contato!

Você pode gostar...