Create ALV with Dynamic Column from Excel Table

Tufan Şaşmaz
4 min readSep 6, 2024

--

The CL_ALV_TABLE_CREATE=>CREATE_DYNAMIC_TABLE method is used to create dynamic internal tables in SAP ABAP. This method creates an internal table with a known type at runtime using the ALV (ABAP List Viewer) field catalog.

We want to transfer the table in the Excel file below to SAP and display it dynamically in ALV.

The relevant code required to do this is below;


REPORT ZTS_P_DYNAMIC_ALV.

**>Data definitions
DATA : gt_excel TYPE TABLE OF alsmex_tabline,
gt_value TYPE TABLE OF lvc_fname,
gt_fieldcat TYPE lvc_t_fcat,
gs_fieldcat TYPE lvc_s_fcat.

DATA: go_alv_grid_0100 TYPE REF TO cl_gui_alv_grid.

FIELD-SYMBOLS : <gfs_dynamic> TYPE STANDARD TABLE.

**->Selection-Screen for excel file location
SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME.
PARAMETERS : p_file TYPE rlgrap-filename OBLIGATORY MODIF ID mid.
SELECTION-SCREEN END OF BLOCK b1.

AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_file.
**->F4 help for p_file
CALL FUNCTION 'F4_FILENAME'
EXPORTING
field_name = 'P_FILE'
IMPORTING
file_name = p_file.

START-OF-SELECTION.
PERFORM get_excel_data.

CALL SCREEN 0100.
*&---------------------------------------------------------------------*
*& Form get_excel_data
*&---------------------------------------------------------------------*
FORM get_excel_data.
**-->Get data in excel file from file location
CALL FUNCTION 'ALSM_EXCEL_TO_INTERNAL_TABLE'
EXPORTING
filename = p_file
i_begin_col = 1
i_begin_row = 1
i_end_col = 100
i_end_row = 999
TABLES
intern = gt_excel.

IF gt_excel IS NOT INITIAL.

SORT gt_excel BY col row.

LOOP AT gt_excel INTO DATA(ls_excel) WHERE row EQ 1.
**->The first row of the EXCEL is reserved for field names,
APPEND ls_excel-value TO gt_value.
**->We transfer the field names to the internal table
**->named gt_value in this loop.
ENDLOOP.

**->Creating fieldcatalog using that itab
gt_fieldcat = VALUE #( FOR lv_value IN gt_value
( scrtext_s = lv_value fieldname = lv_value ) ).

ENDIF.

IF lines( gt_fieldcat ) IS NOT INITIAL.
PERFORM create_dyn_tab.
ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form create_dyn_tab
*&---------------------------------------------------------------------*
FORM create_dyn_tab.
DATA : lv_value TYPE string,
lv_fname TYPE lvc_fname VALUE '<lfs_line>-'.

DATA : lo_line TYPE REF TO data.

**->This method is used to create a dynamic internal table from gt_fieldcat.
cl_alv_table_create=>create_dynamic_table(
EXPORTING it_fieldcatalog = gt_fieldcat
IMPORTING ep_table = DATA(lt_dynamic) ).

IF sy-subrc IS INITIAL.
**->It Assigns dynamic table named lt_dynamic
**->to the field symbol named gfs_dynamic.
ASSIGN lt_dynamic->* TO <gfs_dynamic>.
**->It Create a data object named lo_line similar to the row
**-> structure of the dynamic table named gfs_dynamic.
CREATE DATA lo_line LIKE LINE OF <gfs_dynamic>.
**->It Assigns the data object named lo_line
**->to the field symbol named lfs_line.
ASSIGN lo_line->* TO FIELD-SYMBOL(<lfs_line>).
ENDIF.

SORT gt_excel BY row col.

LOOP AT gt_excel INTO DATA(ls_excel) WHERE row NE '1'.
TRY.
**->It tries to assign the relevant row from the gt_fieldcat table
gs_fieldcat = gt_fieldcat[ ls_excel-col ].
**->to the gs_fieldcat variable based on the col value inside ls_excel.
CATCH cx_sy_itab_line_not_found.
**- If the row cannot be found, an error is caught and the process
DATA(lv_check) = abap_true.
ENDTRY.

CHECK lv_check IS INITIAL.
**->It Assigns the combined values of lv_fname and
**->gs_fieldcat-fieldname to the variable lv_value.
lv_value = |{ lv_fname }{ gs_fieldcat-fieldname }|.
**->It Assigns the value inside lv_value to the field symbol named <lfs_value>.
ASSIGN (lv_value) TO FIELD-SYMBOL(<lfs_value>).

**->If the field symbol <lfs_value> is assigned, meaning
**->it points to a valid memory address.
IF <lfs_value> IS ASSIGNED.
**->“It assigns the value inside ls_excel to the field symbol <lfs_value>.
<lfs_value> = ls_excel-value.
**->This essentially means assigning the value
**->to the relevant field inside lfs_line.
ENDIF.

AT END OF row.
**->When the end of the row column is reached,
APPEND <lfs_line> TO <gfs_dynamic>.
**->it adds the values inside lfs_line to the dynamic table named gfs_dynamic.
ENDAT.

ENDLOOP.

ENDFORM.
*&---------------------------------------------------------------------*
*& Module status_0100 OUTPUT
*&---------------------------------------------------------------------*
MODULE status_0100 OUTPUT.
SET PF-STATUS sy-dynnr.
SET TITLEBAR sy-dynnr.
**-> Display ALV
IF go_alv_grid_0100 IS INITIAL.

CREATE OBJECT go_alv_grid_0100 EXPORTING
i_parent = cl_gui_container=>default_screen.

go_alv_grid_0100->set_table_for_first_display(
EXPORTING
i_bypassing_buffer = abap_true
i_default = abap_true
i_save = 'A'
CHANGING
it_outtab = <gfs_dynamic>
it_fieldcatalog = gt_fieldcat ).

ELSE.
go_alv_grid_0100->refresh_table_display( ).
ENDIF.

ENDMODULE.
*&---------------------------------------------------------------------*
*& Module USER_COMMAND_0100 INPUT
*&---------------------------------------------------------------------*
MODULE user_command_0100 INPUT.
CASE sy-ucomm.
WHEN '&BACK'.
LEAVE TO SCREEN 0.
ENDCASE.
ENDMODULE.

Result;

--

--