Search code examples
layoutabapalv

How to read the ALV list saved layout metadata?


I have an ALV list as an output of the program and need to be able to dynamically get / fetch the columns and their positions.

The users can also save the columns / positions as a layout for future use and I want to get this information for the saved layouts.

I am expecting to get the columns and their positions of an ALV list as an internal table, to use it further, for example, to generate .xls file.


Solution

  • You can achieve it in the way described below. I wrote a sample code snippet with comments. Basically the starting table is LTDX.

    First read the layouts for the program using FM LT_VARIANTS_READ_FROM_LTDX. Replace REPORT_NAME_REPLACE with your program name of interest. Additionally you can filter layouts for specific user(s) - uncomment lines with range table lt_r_uname and replace LOGIN_REPLACE with your login.

    TYPES: ty_r_repid TYPE RANGE OF syrepid,
           ty_r_uname TYPE RANGE OF syst_uname.
    
    DATA: lt_variants TYPE TABLE OF ltvariant.
    
    DATA(lt_r_repid) = VALUE ty_r_repid(
      ( sign = 'I' option = 'EQ' low = 'REPORT_NAME_REPLACE' )
    ).
    DATA(lt_r_uname) = VALUE ty_r_uname(
      ( sign = 'I' option = 'EQ' low = 'LOGIN_REPLACE' )
    ).
    
    CALL FUNCTION 'LT_VARIANTS_READ_FROM_LTDX'
      EXPORTING
        i_tool       = 'LT'
        i_text       = 'X'
      TABLES
        et_variants  = lt_variants
        it_ra_report = lt_r_repid.
    *      it_ra_username = lt_r_uname.
    
    IF sy-subrc <> 0.
      WRITE: / 'Not layout(s) found.'.
      EXIT.
    ENDIF.
    

    Next for the found layout(s) read the data - basic field catalog - with FM LT_DBDATA_READ_FROM_LTDX and afterwards the field catalog itself with FM LT_FC_LOAD.

    LOOP AT lt_variants ASSIGNING FIELD-SYMBOL(<fs_variant>).
      DATA: lt_fcat_base TYPE TABLE OF ltdxdata,
            lt_fcat_def  TYPE kkblo_t_fieldcat,
            lt_fcat      TYPE kkblo_t_fieldcat,
            ls_layout    TYPE kkblo_layout.
    
      DATA(ls_key_base) = CORRESPONDING ltdxkey( <fs_variant> ).
      CALL FUNCTION 'LT_DBDATA_READ_FROM_LTDX'
        EXPORTING
          i_tool       = 'LT'
          is_varkey    = ls_key_base
        TABLES
          t_dbfieldcat = lt_fcat_base.
    
      IF sy-subrc = 0.
        DATA(ls_key) = CORRESPONDING disvariant( <fs_variant> ).
        LOOP AT lt_fcat_base ASSIGNING FIELD-SYMBOL(<fs_fcat_base>).
          COLLECT VALUE kkblo_fieldcat( fieldname = <fs_fcat_base>-key1 )
                  INTO lt_fcat_def.
        ENDLOOP.
    
        CALL FUNCTION 'LT_FC_LOAD'
          EXPORTING
            is_variant          = ls_key
            i_tabname           = '1'
          IMPORTING
            et_fieldcat         = lt_fcat
          CHANGING
            cs_layout           = ls_layout
            ct_default_fieldcat = lt_fcat_def.
    
        IF sy-subrc = 0.
          LOOP AT lt_fcat_base ASSIGNING <fs_fcat_base>
            WHERE param = 'NO_OUT' AND value = 'X'.
    
            DELETE lt_fcat WHERE fieldname = <fs_fcat_base>-key1.
          ENDLOOP.
    
          SORT lt_fcat BY col_pos.
    
    *     Field catalog for layout is in internal table lt_fcat
    *     Debug output: layout and fields
    
          WRITE: / |Layout: { <fs_variant>-variant } [{ <fs_variant>-username }] |.
          LOOP AT lt_fcat ASSIGNING FIELD-SYMBOL(<ls_fcat>).
            WRITE: /9 |{ <ls_fcat>-fieldname }|.
          ENDLOOP.
    
        ELSE.
          WRITE: |No field catalog found for layout { <fs_variant>-variant }|.
        ENDIF.
    
        CLEAR: lt_fcat_def.
      ELSE.
        WRITE: |No data found for layout { <fs_variant>-variant }|.
      ENDIF.
    ENDLOOP.
    

    The internal table lt_fcat contains columns of the layout: component fieldname the name of the column and col_pos its position. I filtered out from the internal table the columns which have parameter NO_OUT = 'X' and therefore are not displayed in the layout.