User Tools

Site Tools


abap:dynamic_programming

This is an old revision of the document!


Programmation dynamique

La programmation dynamique en ABAP est un art particulier qui requiert acrobaties et équilibrismes…

Les field-symbols

L'élément central de la programmation dynamique : les field-symbols.

/!\ Ne pas tenter de manipuler un field-symbol non assigné, sinon gare au GETWA_NOT_ASSIGNED ! /!\

Déclaration

  FIELD-SYMBOLS : <et_plip> TYPE STANDARD TABLE, " Table
                  <ls_plop> TYPE any, " Whatever
                  <fs1>. "Whatever, short form...

Assignation

ASSIGN ls_plop TO <ls_plop>. "Var
ASSIGN (ls_plop) TO <fs1>. "Content of var. ie. if ls_foo-bar = '1234' ; ls_plop = 'ls_foo-bar' then <fs1> = '1234'.
ASSIGN et_plip[] TO <et_plip>[]. "Table content

Typage dynamique

Au delà de l'assignation de field-symbols depuis des sources instanciées et typées (même si le type peut ne pas être connu à l'avance), il faut aussi parfois pouvoir manipuler des données qui vont être crées lors de l'exécution et dont le type est inconnu à l'avance. Pour cela il va falloir recourir à des commandes particulières et à des fonctions qui vont puiser des informations directement auprès du kernel (autrefois des FM ALV, aujourd'hui des classes dédiées).

Typage par comparaison

DATA: dy_line  TYPE REF TO data.
 
CREATE DATA dy_line LIKE LINE OF <et_plip>.
ASSIGN dy_line->* TO <les_plop>.

Jouer avec les composants d'une structure

Quelques classes utiles :

  • cl_abap_tabledescr
  • cl_abap_structdescr
  • cl_abap_typedescr

Exemple pratique : un MOVE-CORRESPONDING dynamique (agnostique sur la structure d'entrée comme de sortie) !

DATA:  ls_line TYPE abap_compdescr.
  REFRESH <et_plip>.
  LOOP AT lit_ausp ASSIGNING <ls_ausp>.
    " Get output structure components
    descr_ref ?= cl_abap_typedescr=>describe_by_data( <ls_ausp> ).
    LOOP AT  descr_ref->components INTO ls_line.
      ASSIGN COMPONENT ls_line-name OF STRUCTURE <ls_ausp> TO <fs1>.
      IF sy-subrc NE 0.
        EXIT.
      ENDIF.
      ASSIGN COMPONENT ls_line-name OF STRUCTURE <ls_plop> TO <fs2>.
      IF sy-subrc = 0.
        <fs2> = <fs1>.
      ENDIF.
    ENDLOOP.
    APPEND <ls_plop> TO <et_plip>.
  ENDLOOP.

NB : il est évidemment possible d'enrichir ce code avec des fonctionnalités pour par exemple ne pas transporter les champs vides de la structure 1 vers la 2 ou encore faire des transcos au passage…

NB2 : Si la classe cl_abap_typedescr n'est pas dispo, zieuter vers GET_COMPONENT_LIST et GET_GLOBAL_SYMBOLS.

Créer une itab ex nihilo

Sauce

    METHOD create_data.
        DATA:
          lo_structdescr         TYPE REF TO cl_abap_structdescr,
          lo_typedescr           TYPE REF TO cl_abap_typedescr,
          lo_tabledescr          TYPE REF TO cl_abap_tabledescr,
          lt_lvc_scol            TYPE lvc_t_scol,
          lt_lvc_styl            TYPE lvc_t_styl,
          lt_comp_all            TYPE cl_abap_structdescr=>component_table.
        FIELD-SYMBOLS:
          <component>            TYPE LINE OF abap_component_tab.
 
        APPEND INITIAL LINE TO lt_comp_all ASSIGNING <component>.
        <component>-type ?= cl_abap_datadescr=>describe_by_data( lt_lvc_styl ).
        <component>-name = lc_fieldname_t_styl.
 
        APPEND INITIAL LINE TO lt_comp_all ASSIGNING <component>.
        <component>-type ?= cl_abap_datadescr=>describe_by_data( lt_lvc_scol ).
        <component>-name = lc_fieldname_t_color.
 
    * create structure description
        lo_structdescr = cl_abap_structdescr=>create( lt_comp_all ).
 
    * create table description for structure
        lo_tabledescr = cl_abap_tabledescr=>create(
                        p_line_type  = lo_structdescr
                        p_table_kind = cl_abap_tabledescr=>tablekind_std
                        p_unique     = abap_false ).
 
    * create data object
        CREATE DATA rr_dispodata TYPE HANDLE lo_tabledescr.
 
      ENDMETHOD.

Exemples

Select dans table dynamique

abap/dynamic_programming.1500646008.txt.gz · Last modified: 2017/07/21 16:06 by ginko