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!