How to create an ALV based on a dynamic structure?

9

I'm trying to streamline processes since we need to generate reports in ALVs.

The idea is to get the metadata of a structure (Field Name, Domain, Descriptive) and thus to generate the 'fieldcat' in the ALV creation function and in the sequence to be able to fill it.

Ex:

Traversing the fields of the structure would fill the skeleton table.

CLEAR gs_s_fcat.
gs_s_fcat-fieldname = fieldname. " Nome do campo da Estrutura
gs_s_fcat-outputlen = size.      " O tamanho do conteúdo
gs_s_fcat-tabname   = table.     " Tabela
gs_s_fcat-coltext   = header.    " Texto do cabeçalho
gs_s_fcat-col_pos   = index.     " Índice da coluna
gs_s_fcat-emphasize = style.     " Estilo, cores e etc.
APPEND gs_s_fcat TO gt_t_fcat.

Call the creation of the generic table.

CALL METHOD cl_alv_table_create=>create_dynamic_table
EXPORTING
  i_style_table             = 'X'
  it_fieldcatalog           = gt_t_fcat
IMPORTING
  ep_table                  = gt_generic_table
EXCEPTIONS
  generate_subpool_dir_full = 1
  OTHERS                    = 2.

{...} - I would fill a field-symbol with the same structure and use the display

CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
EXPORTING
  i_buffer_active          = 'X'
  i_callback_program       = sy-repid
  is_layout                = gs_layout
  it_fieldcat              = gt_t_fcat
TABLES
  t_outtab                 = <fs_table>
EXCEPTIONS
  program_error            = 1
  OTHERS                   = 2.

Ideas?

    
asked by anonymous 18.12.2013 / 18:02

2 answers

4

I found some different ways to get the detailing of frame fields.

By the assistance class method as below:

tabela_de_detalhe ?= cl_abap_typedescr=>describe_by_name( 'NOME_ESTRUTURA' ).

And the one I thought best for my purposes, the function to follow.

CATSXT_GET_DDIC_FIELDINFO

The end result looks like this:

Variables properly declared.

**---------------------------------------------------------------------*
**     Tabelas internas                                                *
**---------------------------------------------------------------------*
  DATA: lt_fields   TYPE ddfields,
        lt_fcat     TYPE lvc_t_fcat,
        lt_fcat_alv TYPE slis_t_fieldcat_alv.
**---------------------------------------------------------------------*
**     Estrutura                                                       *
**---------------------------------------------------------------------*
  DATA: ls_fcat     TYPE lvc_s_fcat,
        ls_fields   LIKE LINE OF lt_fields,
        ls_fcat_alv LIKE LINE OF lt_fcat_alv.
*----------------------------------------------------------------------*
*      Variaveis                                                       *
*----------------------------------------------------------------------*
  DATA: lv_index  TYPE i.

The function call that returns the detail of the submitted structure.

   CALL FUNCTION 'CATSXT_GET_DDIC_FIELDINFO'
    EXPORTING
      im_structure_name = structure_name
    IMPORTING
      ex_ddic_info      = lt_fields
    EXCEPTIONS
      failed            = 1
      OTHERS            = 2.

  IF sy-subrc <> 0.
    RAISE structure_not_found.
  ENDIF.

Now you need to direct this information to the table that will keep the ALV skeleton.

LOOP AT lt_fields INTO ls_fields.

    CLEAR: ls_fcat.

    lv_index = lv_index + 1.

    MOVE-CORRESPONDING:  ls_fields to ls_fcat_alv,
                         ls_fields to ls_fcat.

    IF ls_fields-scrtext_m IS NOT INITIAL.
      ls_fcat-coltext   = ls_fields-scrtext_m.
    ELSEIF ls_fields-scrtext_l IS NOT INITIAL.
      ls_fcat-coltext   = ls_fields-scrtext_l.
    ELSEIF ls_fields-scrtext_s IS NOT INITIAL.
      ls_fcat-coltext   = ls_fields-scrtext_s.
    ELSEIF ls_fields-fieldtext IS NOT INITIAL.
      ls_fcat-coltext   = ls_fields-fieldtext.
    ENDIF.

    ls_fcat_alv-seltext_l = ls_fcat-coltext.

    ls_fcat-col_pos   = lv_index.
    ls_fcat-key       = ls_fields-keyflag.

    APPEND: ls_fcat to lt_fcat,
            ls_fcat_alv to lt_fcat_alv.
ENDLOOP.
  

Note:

     
  • I have chosen the CATSXT_GET_DDIC_FIELDINFO function because it returns the column descriptor, domain information, source table, and the like.   

  • I've intentionally maintained two structures for lt_fcat and lt_fcat_alv , the first one will build the PivotTable and another for the ALV display.

  •   

I hope to have helped, hugs.

    
19.12.2013 / 15:42
1

An ABAP here to try to help. I do not know if you still face this problem, but a possible solution would be to use the new ALV classes. The simplest of all already builds the ALV without asking you to specify the fields (FIELDCAT). Just pass the internal table and the rest it already does, as the example below:

REPORT z_teste_brl.

DATA t_t000 TYPE TABLE OF t000 WITH DEFAULT KEY.

SELECT * FROM t000 INTO TABLE t_t000.

DATA o_alv TYPE REF TO cl_salv_table.

CALL METHOD cl_salv_table=>factory
  IMPORTING
    r_salv_table = o_alv
  CHANGING
    t_table      = t_t000.

o_alv->display( ).

To make this dynamic, you can change the above program to something like this:

REPORT z_teste_brl.

PARAMETER tn TYPE dd02l-tabname OBLIGATORY.

DATA table_name TYPE string.
table_name = tn.

DATA line_type_native TYPE REF TO cl_abap_typedescr.
CALL METHOD cl_abap_typedescr=>describe_by_name
  EXPORTING
    p_name         = table_name
  RECEIVING
    p_descr_ref    = line_type_native
  EXCEPTIONS
    type_not_found = 1
    OTHERS         = 2.

CHECK sy-subrc IS INITIAL.

DATA line_type TYPE REF TO cl_abap_structdescr.
line_type ?= line_type_native.

DATA table_type TYPE REF TO cl_abap_tabledescr.
table_type = cl_abap_tabledescr=>create( p_line_type = line_type
                                         p_table_kind = cl_abap_tabledescr=>tablekind_std ).

DATA internal_table TYPE REF TO data.
CREATE DATA internal_table TYPE HANDLE table_type.

FIELD-SYMBOLS <internal_table> TYPE STANDARD TABLE.
ASSIGN internal_table->* TO <internal_table>.

SELECT * FROM (tn) INTO TABLE <internal_table>.

DATA o_alv TYPE REF TO cl_salv_table.

CALL METHOD cl_salv_table=>factory
  IMPORTING
    r_salv_table = o_alv
  CHANGING
    t_table      = <internal_table>.

o_alv->display( ).

Simple, right? I hope I have helped!

    
05.06.2015 / 21:50