0

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.

AlexSchell
  • 953
  • 1
  • 1
  • 18
Bigflatfoot
  • 45
  • 2
  • 13
  • Can you please clarify what do you exactly want to achive, I cannot understand it from your question, ".. and to get/fetch the column positions of it." Users can save ALV layouts and can set a default layout. You can also make an export of data with the current layout to excel from ALV and than manupilate this data in excel as needed. – AlexSchell May 19 '23 at 10:46
  • @AlexSchell I'm having trouble as I'm clueless on how to fetch the layout of my current ALV. This is a custom program that displays an ALV. A user may save the layout. The user may enter the layout name in the selection screen prior executing the program in SA38. – Bigflatfoot May 20 '23 at 07:24
  • @AlexSchell Currently, the display of my layout is like this: |EBELN|BUKRS|MATNR|MATKL|AEDAT| However, the user sometimes wants this layout: |AEDAT|EBELN|BUKRS|MATNR|MATKL| I want to know how to fetch the column positions of the columns above so I can create an xls file following the layout. – Bigflatfoot May 20 '23 at 07:28

1 Answers1

1

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.

AlexSchell
  • 953
  • 1
  • 1
  • 18
  • Thanks Alex! I think I was able to fetch the column positions saved in a layout. However, is it possible to specify the specifc layout? Because in my selection screen, there is a parameter that allows the user to enter the layout that’s going to be used. The field name is named p_layout. – Bigflatfoot May 22 '23 at 07:31
  • 1
    By calling the function **LT_VARIANTS_READ_FROM_LTDX** all layouts are returned in an internal table **lt_variants**, which I looped over just an example. Afterwards you can just read from this internal table the layout you need by matching the **variant** compoment. Another option is to pass to LT_VARIANTS_READ_FROM_LTDX the parameter **it_ra_variant** to filter out the layout(s) you want to retreive (build it up analogous to lt_r_repid / lt_r_uname in an example). – AlexSchell May 22 '23 at 07:40
  • Thanks Alex. APologies for the additional question. But currently the data of ALV is being passed to T_FIELDCAT and the structure of it comes from T_FINAL. `The T_FINAL is coded like this: DATA: BEGIN OF T_FINAL, EBELN like , BUKRS like , MATNR like , MATKL like , AEDAT like . END OF T_FINAL.` `DATA: T_FIELDCAT TYPE SLIS_T_FIELDCAT_ALV.` Both tables were used in this function module: `REUSE_ALV_FIELDCATALOG_MERGE' EXPORTING i_program_name = sy-repid i_internal_tabname = 'T_FINAL' CHANGING ct_fieldcat = t_fieldcat[].` It it possible to use the t_fcat here? – Bigflatfoot May 22 '23 at 08:04
  • 1
    I cannot say it from code, but you can compare the types / components and also modify them as necessary. I do not know why do you want to use it and what do you want to achive. You can already retrieve the saved layouts, the fields and their order. Try not to overcompicate things where it is not necessary. – AlexSchell May 22 '23 at 08:06
  • It looks like the system is following how the fields are declared in T_FINAL table. Therefore, the result of column position in T_FIELDCAT is like this: EBELN - 1 BUKRS - 2 MATNR - 3 MATKL - 4 AEDET - 5 While the position of columns in LT_FCAT is like this: AEDAT - 1 EBELN - 2 BUKRS - 3 MATNR - 4 MATKL - 5. Is it possible to pass the column positions of LT_FCAT into T_FIELDCAT? – Bigflatfoot May 22 '23 at 08:09
  • Set the component **col_pos** for each line of internal table t_fieldcat after you get it from REUSE_ALV_FIELDCATALOG_MERGE FM to the value positions you need. – AlexSchell May 22 '23 at 08:20