Generowanie katalogu pól ALV na podstawie dynamicznego typu danych

Niedawno implementowałem raport ALV z dynamicznie definiowanymi kolumnami. Zwykle kolumny raportu ALV są określane na podstawie struktury słownika danych lub kolumny są dodawane w kodzie do katalogu pól ALV. W moim przypadku wymaganiem było, aby kolumny raportu wynikały z konfiguracji systemu, która może zmienić się w przyszłości. Raport miał się dopasować do takiej zmiany bez konieczności zmian w kodzie ABAP. Wtedy właśnie zdałem sobie sprawę z potencjału dynamicznie definiowanych typów danych:

CREATE DATA ... TYPE HANDLE ...

oraz klas CL_ABAP_DATADESCR, CL_ABAP_STRUCTDESCR i CL_ABAP_TABLEDESCR. Dzięki temu mogłem szybko zdefiniować wewnętrzną tablicę o dynamicznej strukturze ustalanej na podstawie bieżącej konfiguracji. Otwartą kwestią pozostało zbudowanie katalogu pól ALV. Jedną możliwością było dodawanie pól pojedynczo w kodzie raportu. Inną – przygotowanie uniwersalnej procedury budującej katalog pól ALV, która zrobi to automatycznie.

Oto ta procedura:

FORM build_fieldcat
USING pt_tab TYPE REF TO data
CHANGING pt_fc TYPE slis_t_fieldcat_alv.

DATA:
lo_tabledescr TYPE REF TO cl_abap_tabledescr,
lo_structdescr TYPE REF TO cl_abap_structdescr,
lt_components TYPE abap_component_tab,
lo_elemdescr TYPE REF TO cl_abap_elemdescr,
lv_pos LIKE sy-tabix,
ls_dfies LIKE dfies.

FIELD-SYMBOLS:
<comp> LIKE LINE OF lt_components,
<fc> LIKE LINE OF pt_fc.

lo_tabledescr ?= cl_abap_tabledescr=>describe_by_data_ref( pt_tab ).
lo_structdescr ?= lo_tabledescr->get_table_line_type( ).
lt_components = lo_structdescr->get_components( ).

LOOP AT lt_components ASSIGNING <comp>.
  lv_pos = sy-tabix.
  APPEND INITIAL LINE TO pt_fc ASSIGNING <fc>.

  lo_elemdescr ?= <comp>-type.
  ls_dfies = lo_elemdescr->get_ddic_field( p_langu = sy-langu ).
  MOVE-CORRESPONDING ls_dfies TO <fc>.

  CLEAR <fc>-tabname.

  <fc>-col_pos = lv_pos.
  <fc>-fieldname = <comp>-name.
  <fc>-reptext_ddic = ls_dfies-reptext.

  IF ls_dfies-convexit IS NOT INITIAL.
    CONCATENATE '==' ls_dfies-convexit INTO <fc>-edit_mask.
  ENDIF.
ENDLOOP.
ENDFORM.                    "build_fieldcat

Procedura odczytuje przy pomocy klas CL_ABAP_*DESCR pola dynamicznie zadeklarowanej tablicy wewnętrznej. Następnie zakładając, że te pola zostały zdefiniowane na podstawie elementów danych DDIC, procedura odczytuje ich atrybuty i buduje katalog pól ALV. Naturalnie ta uniwersalna procedura może być dopasowywana do indywidualnych zastosowań np. poprzez określenie pól jednostek miary czy waluty.

Podejście obiektowe

Analogiczną funkcjonalność Łukasz Pęgiel opisał na swoim blogu ABAPblog.com w artykule Create fieldcatalog from internal table:

class-methods lvc_fcat_from_internal_table
  importing
    it_table type any table
  returning value(rt_fcat) type lvc_t_fcat.
method lvc_fcat_from_internal_table.
    data: table type ref to data.
    create data table like it_table.
    assign table->* to field-symbol(
<table>).
    try.
        cl_salv_table=>factory( importing
                                  r_salv_table   = data(salv_table)
                                changing
                                  t_table        = 
<table>  ).
        rt_fcat = cl_salv_controller_metadata=>get_lvc_fieldcatalog(
            r_columns      = salv_table->get_columns( ) " ALV Filter
            r_aggregations = salv_table->get_aggregations( ) " ALV Aggregations
    ).
      catch cx_root.
    endtry.
  endmethod.

Dziękuję Łukasz za komentarze, powyższy przykład i ciekawy artykuł!

Komentarze o “Generowanie katalogu pól ALV na podstawie dynamicznego typu danych

Zostaw komentarz

This site uses Akismet to reduce spam. Learn how your comment data is processed.