SAP ABAP DYNAMIC

From SapWiki

Ejemplo 01: generar archivo CSV independiente del tipo

FORM crear_csv USING p_tabla TYPE ANY TABLE
            CHANGING p_tabla_csv TYPE ppe_cust_table.

  CONSTANTS: c_field_separator TYPE c VALUE ';',
             c_darl_number(12) TYPE c VALUE '1234567890 '.

  DATA: cl_descr_struc_ref TYPE REF TO cl_abap_structdescr,
        it_components      TYPE abap_compdescr_tab,
        wa_components      LIKE LINE OF it_components.

  DATA lt_data TYPE ppe_cust_table.

  DATA: l_struc_index     TYPE syindex,
        l_len_string      TYPE i,
        l_max_field       TYPE char1024,
        l_struc_raw_data  TYPE char1024,
        l_start_string    TYPE i,
        l_len_field_sep   TYPE i,
        l_date_extern(30) TYPE c,
        l_help_id         LIKE tline-tdline,
        l_tabix           TYPE sytabix.

  FIELD-SYMBOLS <fs_field> TYPE ANY.
  FIELD-SYMBOLS <ls_envio> TYPE ANY.

  l_len_field_sep = STRLEN( c_field_separator ).

  LOOP AT p_tabla ASSIGNING <ls_envio>.
    CLEAR: l_struc_index, l_len_string, l_struc_raw_data, l_start_string.

    IF it_components[] IS INITIAL.
      cl_descr_struc_ref ?= cl_abap_typedescr=>describe_by_data( <ls_envio> ).
* obtener campos de estructura
      it_components = cl_descr_struc_ref->components.
    ENDIF.

    DO.
      ADD 1 TO l_struc_index.
      CLEAR l_len_string.
      READ TABLE it_components INTO wa_components INDEX sy-index.
      IF sy-subrc = 0.
        ASSIGN COMPONENT wa_components-name OF STRUCTURE <ls_envio> TO <fs_field>.

        CASE wa_components-type_kind .
          WHEN 'P'.
            WRITE <fs_field> TO l_date_extern.
            CATCH SYSTEM-EXCEPTIONS conversion_errors  = 4.
              IF sy-subrc <> '0'.
*                MESSAGE e899(ux) WITH l_type <f_source> l_help_id
*                                      l_tabix RAISING conversion_failed.
              ENDIF.
            ENDCATCH.
            CONDENSE l_date_extern.
            ASSIGN l_date_extern TO <fs_field>.
          WHEN 'D'.
            MOVE <fs_field> TO l_date_extern.
*20191220 -> 20/12/2019
            REPLACE FIRST OCCURRENCE OF REGEX '(\d{4})(\d{2})(\d{2})' IN l_date_extern
                                           WITH '$3/$2/$1'.
        ENDCASE.

      ELSE.
        EXIT.
      ENDIF.

      IF l_struc_index <> 1.
        l_max_field+l_len_string(l_len_field_sep) = c_field_separator.
        l_len_string = l_len_field_sep.
      ENDIF.

      l_max_field+l_len_string = <fs_field>.
      l_len_string = STRLEN( l_max_field ).
      CHECK l_len_string <> '0'.
      l_struc_raw_data+l_start_string(l_len_string) = l_max_field.
      l_start_string = l_start_string + l_len_string.
    ENDDO.

    APPEND l_struc_raw_data TO lt_data.

  ENDLOOP.

  p_tabla_csv[] = lt_data[].
ENDFORM.                    "crear_csv

Ejemplo 02: leer archivo desde servidor separado por tabs, independiente del tipo

types: ty_t001 type t001.
  DATA lt_t001 TYPE STANDARD TABLE OF ty_t001.

  PERFORM open_un USING '/tmp/t001_dat2.txt' CHANGING lt_t001.

FORM open_un USING p_file
          CHANGING p_table TYPE ANY TABLE.
  DATA: lr_structdescr TYPE REF TO cl_abap_structdescr,
        lr_datadescr   TYPE REF TO cl_abap_datadescr,
        lr_tabledescr  TYPE REF TO cl_abap_tabledescr,
        line_descr TYPE REF TO cl_abap_typedescr.
  DATA: l_string  TYPE string,
        l_string2 TYPE string,
        l_campo   TYPE string,
        ld_name TYPE string.
  FIELD-SYMBOLS: <fs> TYPE any,
                 <wa> TYPE any.
  DATA: wa_ref TYPE REF TO data.

  lr_tabledescr ?= cl_abap_tabledescr=>describe_by_data( p_table ).
  line_descr = lr_tabledescr->get_table_line_type( ).
  ld_name = line_descr->get_relative_name( ).
*     get the field list of the table linetype
  DATA(lt_components) = CAST cl_abap_structdescr( cl_abap_typedescr=>describe_by_name( ld_name ) )->components.

  CREATE DATA wa_ref TYPE (ld_name).   "Suitable work area
  ASSIGN wa_ref->* TO <wa>.

  OPEN DATASET p_file FOR INPUT IN TEXT MODE
                            ENCODING DEFAULT
                            WITH SMART LINEFEED.
  IF sy-subrc <> 0.
    RETURN.
  ENDIF.

  WHILE sy-subrc = 0.
    READ DATASET p_file INTO l_string.
    CHECK l_string IS NOT INITIAL.
    DATA(l_index) = 1.
    WHILE l_string IS NOT INITIAL.
      SPLIT l_string AT cl_abap_char_utilities=>horizontal_tab INTO l_string2 l_string.
      READ TABLE lt_components INTO data(ls_comp) INDEX l_index.
      IF sy-subrc = 0.
        ADD 1 TO l_index.
        CONCATENATE '<WA>' ls_comp-name INTO l_campo SEPARATED BY '-'.
        ASSIGN (l_campo) TO <fs>.
        MOVE l_string2 TO <fs> .
      ELSE.
        EXIT.
      ENDIF.
    ENDWHILE.
    INSERT <wa> INTO TABLE p_table.
  ENDWHILE.

ENDFORM.

Ejemplos varios

Crear tabla

FORM form01 USING p_tabla TYPE STANDARD TABLE.
  FIELD-SYMBOLS <work_tab> TYPE ANY TABLE.
  DATA work_tab_ref TYPE REF TO data.

  CREATE DATA work_tab_ref LIKE p_tabla[].

  ASSIGN work_tab_ref->* TO <work_tab>.

ENDFORM.

FORM form02.
  FIELD-SYMBOLS <pannnn_wa> TYPE any.
  FIELD-SYMBOLS <pacccc_wa> TYPE c.
  FIELD-SYMBOLS <pannnn>    TYPE STANDARD TABLE.

  DATA dbtab         TYPE t777d-dbtab.
  DATA pannnn_ref    TYPE REF TO data.
  DATA pannnn_wa_ref TYPE REF TO data.

  dbtab = 'PA0008'.
  CREATE DATA pannnn_ref TYPE STANDARD TABLE OF (dbtab).
  ASSIGN pannnn_ref->* TO <pannnn>.
  CREATE DATA pannnn_wa_ref TYPE (dbtab).
  ASSIGN pannnn_wa_ref->* TO <pannnn_wa>.
  ASSIGN <pannnn_wa> TO <pacccc_wa> CASTING.

  SELECT * FROM (dbtab) INTO TABLE <pannnn> UP TO 100 ROWS.

  LOOP AT <pannnn> INTO <pannnn_wa>.
  ENDLOOP.

ENDFORM.

Crear tabla basado en campos

Tomar componentes de tabla T001, menos columna MANDT, y asignarlos dinamicamente a tabla interna.

FORM crear.
  DATA: struct_type TYPE REF TO cl_abap_structdescr,
        itab_type   TYPE REF TO cl_abap_tabledescr,
        comp_tab    TYPE cl_abap_structdescr=>component_table.

  DATA: lr_tabdata TYPE REF TO data.
  FIELD-SYMBOLS: <lt_table> TYPE STANDARD TABLE.

  struct_type ?= cl_abap_typedescr=>describe_by_name( 'T001' ).

  CALL METHOD struct_type->get_components
    RECEIVING
      p_result = comp_tab.

  DELETE TABLE comp_tab WITH TABLE KEY name = 'MANDT'.
  TRY.
      CALL METHOD cl_abap_structdescr=>create
        EXPORTING
          p_components = comp_tab
*         p_strict     = TRUE
        RECEIVING
          p_result     = struct_type.
    CATCH cx_sy_struct_creation .
  ENDTRY.

  itab_type = cl_abap_tabledescr=>create( struct_type ).

* combine
  CREATE DATA lr_tabdata TYPE HANDLE itab_type.
  ASSIGN lr_tabdata->* TO <lt_table>.

ENDFORM.

Combine

form combine_recs_by_key using
                           it_keys type abap_keydescr_tab
                         changing
                           ct_data type standard table
                         .

  data:
      lr_tabdata type ref to data
    , lo_line_type  type ref to cl_abap_structdescr
    , lo_tab_type   type ref to cl_abap_tabledescr
      .
  field-symbols:
      <lt_combined> type sorted table
    , <ls_line>     type any
    .

* create new table with key
  lo_tab_type ?= cl_abap_tabledescr=>describe_by_data( ct_data ).
  lo_line_type ?= lo_tab_type->get_table_line_type( ).
  call method cl_abap_tabledescr=>create
    exporting
      p_line_type  = lo_line_type
      p_table_kind = cl_abap_tabledescr=>tablekind_sorted
      p_unique     = abap_true
      p_key        = it_keys
      p_key_kind   = cl_abap_tabledescr=>keydefkind_user
    receiving
      p_result     = lo_tab_type.

* combine
  create data lr_tabdata type handle lo_tab_type.
  assign lr_tabdata->* to <lt_combined>.

  loop at ct_data assigning <ls_line>.
    collect <ls_line> into <lt_combined>.
  endloop.

  clear ct_data.
  loop at <lt_combined> assigning <ls_line>.
    append <ls_line> to ct_data.
  endloop.
  sort ct_data.

endform.                    " combine_recs_by_key