quinta-feira, 28 de novembro de 2013

Criação de tabela dinâmica 2 formas

- Criação de tabela dinâmica normal.
- Declara um objeto tipo DATA e depois cria o objeto referenciado a estrutura do tipo de tabela que se deseja.



DATA: t_out_tab     TYPE REF TO data.
DATA: wa_out_tab  TYPE REF TO data.

 FIELD-SYMBOLS: <fs_out_tab> TYPE STANDARD TABLE,
               <fsw_out_tab> TYPE any,


Data: l_tabname TYPE tabname.

    CASE 'X'.
      WHEN p_r1.
               l_tabname = 'Z_STRUC1'.
            WHEN p_r2.
       l_tabname = 'Z_STRUC2'.
    ENDCASE.

   "Tabela dinâmica
    CREATE DATA t_out_tab TYPE TABLE OF (l_tabname).
    ASSIGN t_out_tab->* TO <fs_out_tab>.


    "Estrutura da tabela dinâmica
    CREATE DATA wa_out_tab TYPE (l_tabname).    ASSIGN wa_out_tab->* TO <fsw_out_tab>.



- Essa forma criando com o TYPE TABLE OF como demonstrei acima funciona bem, mas eu tive um problema criando dessa forma uma vez que tive que montar uma função para fazer cálculo de condição para SD, nesse caso minha função acessava uma tabela que tinha relacionado uma lista de tabelas de valores de acordo com a condição selecionada, nisso o programa fazia um LOOP e fazia um teste para cada tabela criando tabela dinâmica. Se o número de tabelas a se acessada era muito grande um DUMP ocorria e na busca de uma solução achei a correção usando em vez do TYPE TABLE OF criar com TYPE HANDLE, conforme exemplo abaixo.

FIELD-SYMBOLS: <ft_dyntable> TYPE STANDARD TABLE,
               <fw_dyntable>,
               <fw_fldval> TYPE ANY,
               <fw_struct>.

DATA: t_newtable TYPE REF TO data,
      t_newline  TYPE REF TO data,
      t_fldcat   TYPE lvc_t_fcat.


*&---------------------------------------------------------------------*
*&      Form  CRIAR_TAB_DINAMICA
*&---------------------------------------------------------------------*
FORM criar_tab_dinamica USING p_tabname.

  DATA: lwcl_struc       TYPE REF TO cl_abap_structdescr,
        lwcl_struc_table TYPE REF TO cl_abap_tabledescr.

  DATA: lw_fldcat TYPE lvc_s_fcat.

  UNASSIGN <ft_dyntable>.
  UNASSIGN <fw_dyntable>.

  REFRESH t_fldcat.
  CLEAR: t_fldcat, t_newtable.

  LOOP AT t_dd03l WHERE tabname eq p_tabname.
    MOVE-CORRESPONDING t_dd03l TO lw_fldcat.
    APPEND lw_fldcat TO t_fldcat.
  ENDLOOP.

  CHECK sy-subrc = 0.

  PERFORM create_internal_structure TABLES t_fldcat
                                  CHANGING lwcl_struc
                                           lwcl_struc_table.

*Create references to dyn internal table and work area
  CREATE DATA t_newline TYPE HANDLE lwcl_struc_table.
  ASSIGN t_newline->* TO <ft_dyntable>.
  CREATE DATA t_newline TYPE HANDLE lwcl_struc.
  ASSIGN t_newline->* TO <fw_dyntable>.


ENDFORM.                    " CRIAR_TAB_DINAMICA

 
*&--------------------------------------------------------------*
*&      Form  CREATE_INTERNAL_STRUCTURE
*&--------------------------------------------------------------*
*       Create internal structure
*---------------------------------------------------------------*
FORM create_internal_structure TABLES p_fcattab TYPE lvc_t_fcat
                  CHANGING p_struc TYPE REF TO cl_abap_structdescr
                           p_struc_table TYPE REF TO cl_abap_tabledescr.

  DATA: ls_comp TYPE abap_componentdescr,
        lw_fcat TYPE lvc_s_fcat,
        lt_comp TYPE cl_abap_structdescr=>component_table,
        lv_integer TYPE i.

  LOOP AT p_fcattab INTO lw_fcat.
    ls_comp-name = lw_fcat-fieldname.
    lv_integer = lw_fcat-intlen.
    ls_comp-type = cl_abap_elemdescr=>get_c( lv_integer ).
    APPEND ls_comp TO lt_comp.
  ENDLOOP.

  TRY.
      p_struc =
              cl_abap_structdescr=>create( p_components = lt_comp ).
    CATCH cx_sy_struct_creation .
  ENDTRY.

  TRY.
      p_struc_table = cl_abap_tabledescr=>create( p_struc ).
    CATCH cx_sy_table_creation .
  ENDTRY.

ENDFORM.                    " CREATE_INTERNAL_STRUCTURE



================  10/11/2022
CALL METHOD cl_alv_table_create=>create_dynamic_table
EXPORTING
i_style_table             = 
‘X’
it_fieldcatalog           = gt_dyn_fcat
IMPORTING
ep_table                  = gt_dyn_table
EXCEPTIONS
generate_subpool_dir_full = 
1
OTHERS                    = 2.

IF sy-subrc EQ 0.
* Assign the new table to field symbol
ASSIGN gt_dyn_table->* TO <gfs_dyn_table>.
* Create dynamic work area for the dynamic table
CREATE DATA gw_line LIKE LINE OF <gfs_dyn_table>.
CREATE DATA gw_line1 LIKE LINE OF <gfs_dyn_table>.
ASSIGN gw_line->* TO <gfs_line>.
ASSIGN gw_line1->* TO <gfs_line1>.
ENDIF

===========================

DATA lr_table TYPE REF TO data.
DATA lr_structdescr TYPE REF TO cl_abap_structdescr.
lr_structdescr ?= cl_abap_typedescr=>describe_by_data_ref( ref #( ls_structure ) ).
DATA lr_tabledescr TYPE REF TO cl_abap_tabledescr.
lr_tabledescr ?= cl_abap_tabledescr=>create( p_line_type = lr_structdescr ).

CREATE DATA lr_table TYPE HANDLE lr_tabledescr.
ASSIGN lr_table->* TO FIELD-SYMBOL(<ft_table>).


============================================================

* Create a new Line with the same structure of the table.
  ASSIGN lo_table_mon->* TO <lt_table_mon>.

  LOOP AT <l_table4> ASSIGNING FIELD-SYMBOL(<ls_table4>).

    APPEND INITIAL LINE TO <lt_table_mon> ASSIGNING FIELD-SYMBOL(<ls_table_mon>).

    DATA(lt_comp) = CAST cl_abap_structdescr(
                cl_abap_typedescr=>describe_by_data( <ls_table4> ) )->components.

    LOOP AT lt_comp ASSIGNING FIELD-SYMBOL(<ls_comp>).

      CHECK <ls_comp>-name NS 'STYLE'.

      IF <ls_comp>-name(5) <> |W{ v_month1(4) }| AND
         <ls_comp>-name(5) <> |W{ v_monthn(4) }| AND
         <ls_comp>-name(5) <> |W{ v_week1(4) }|.

        ASSIGN COMPONENT <ls_comp>-name OF STRUCTURE <ls_table4> TO <ls_value_w>.
        ASSIGN COMPONENT <ls_comp>-name OF STRUCTURE <ls_table_mon> TO <ls_value_m>.
        <ls_value_m> = <ls_value_w>.

      ELSE.

        ls_mon_str = <ls_comp>-name.
        DATA(l_month) = |{ ls_mon_str-m }{ ls_mon_str-year }{ ls_mon_str-month }|.
        ASSIGN COMPONENT <ls_comp>-name OF STRUCTURE <ls_table4> TO <ls_value_w>.
        ASSIGN COMPONENT l_month OF STRUCTURE <ls_table_mon> TO <ls_value_m>.
        IF sy-subrc = 0.
          ADD <ls_value_w> TO <ls_value_m>.
        ENDIF.

      ENDIF.

    ENDLOOP.

  ENDLOOP.




Um comentário:

  1. Bom dia,
    usei o exemplo do colega acima e fiz um pequeno ajuste e funcionou corretamente.
    segue abaixo.
    DATA: l_tabname TYPE tabname.
    ls_knumh TYPE a917-knumh.

    CONCATENATE 'A' 'B' INTO l_tabname.

    SELECT SINGLE knumh
    INTO ls_knumh
    FROM (l_tabname)
    WHERE kunrg = komk-knrze.

    ResponderExcluir