How to create an ALV based on a dynamic structure?

I am trying to streamline processes since several times we need generate reports in ALVs.

The idea is to get the metadata of a structure ( Field name, domain, descriptive ) and so generate the 'fieldcat' in the function of creating the ALV and in the sequence manage to fill it.

Ex.:

Scrolling through the structure fields 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 table creation generic.

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.

{...}- Would populate a field-symbol coom the same structure and use in 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?

 9
Author: Don, 2013-12-18

2 answers

I found a few different ways to get structure field detailing.

Through the assistance class method as below:

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

And the one I found best for my purposes, the following function.

CATSXT_GET_DDIC_FIELDINFO

The final result looked like this:

Properly declared variables.

**---------------------------------------------------------------------*
**     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 submitted structure detail.

   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 target this information for the table that will keep the skeleton of the ALV.

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.

Obs.:

  • I opted for the function CATSXT_GET_DDIC_FIELDINFO for it to return me in addition to the name of the columns the descriptive, domain information, source table and the like.

  • I have maintained two structures purposely the lt_fcat and the lt_fcat_alv, the first will serve for the construction of the pivot table and the other for the display of the ALV.

I hope I helped, hugs.

 4
Author: Don, 2013-12-19 14:49:18

An ABAP here to try to help. I don't know if you still face this problem, but a possible solution would be to use the new ALV classes. The simplest of all builds the ALV without asking you to specify the fields (FIELDCAT). Just pass the inner 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 helped!

 1
Author: Bruno Lucattelli, 2015-06-05 19:50:19