In one of our post, we showed the usage of Dynamic Where Condition . In this article, we would show one out of the many ways to generate Dynamic Internal Table and display it in ALV output.
Say you have a requirement where you want to show a report to indicate one Material is present in how many Plants. Say your input material ‘M1’ is present in two plants say ‘P1’ and ‘P2’. So the output ALV report should show only two three columns, M1, P1 and P2. Say you have another material ‘M2’ which is present in 5 plants ‘P1’, ‘P2’, ‘P3’, ‘P4’ and ‘P5’. Then the output table would have six columns. M1, P1, P2, P3, P4 and P5.
Make a note, the number of columns are changing based on the input. Let us see a real example.
Check the MARC table.
Above screenshot shows that Material ‘100522’ is present in two plants. Our ALV would show as below.
Check the MARC screenshot, Material ‘100567’ is present in four plants. Our ALV would show as below.
Did you notice, the number of columns are changing dynamically as per the data? This can be done in many ways, but the most convenient way is to create dynamic structure/internal table and display it.
[adToAppearHere]
Function Module ‘DDIF_FIELDINFO_GET‘ would help us to fetch table field information. Check the code below, we are replacing ‘MARC-WERKS’ field label, with the actual Plant number. This was just a specific project requirement. You might have some other requirement.
Material is a fixed column but Plants are dynamic based on data from MARC. Check we are looping through the internal table and using FM ‘DDIF_FIELDINFO_GET‘ to determine and populate field catalog information.
Once we have the field catalog (i_fcat), we need to build the dynamic internal table with the required columns determined by i_fcat. For this example, we are using method ‘CREATE_DYNAMIC_TABLE‘ of class CL_ALV_TABLE_CREATE.
The below two steps are the most important ones. Here we are assigning the dynamic structure to the <field-symbol> table and <field-symbol> work area which would be used later to display the ALV.
* Assign the structure of dynamic table to field symbol ASSIGN i_dynamic_table->* TO <i_dyn_table>. * Create the dynamic work area CREATE DATA wa_dyn_line LIKE LINE OF <i_dyn_table>. ASSIGN wa_dyn_line->* TO <wa_dyn>.
Also Read: ‘SAP HANA from space level’.
There is some mathematic done to mark ‘X’ for the column where the material is present. So do not be confused. In debugging, it shows that although MATNR has 18 characters, the dynamic table show 36 (just the double). Same with Plant, it shows 8 instead of 4. So, this is something you want to check before you put your data.
Once you have populated the data in the dynamic internal table, displaying data in ALV is a cake walk. Just use the FM ‘REUSE_ALV_GRID_DISPLAY‘.
Check the code behaviour in Debugging mode”
Check I_FCAT table, it has 4 rows of fields. This means, the dynamic internal table would have 4 columns. One fixed for Material and 3 dynamic for plants.
This is the class and method which actually creates the dynamic internal table.
Check I_DYNAMIC_TABLE, it has now 3 columns for plants. This is the structure you need. Now just create the internal table and work area and populate your final data and display it.
Let us see, how the output would look like when we input 3 materials which are available in multiple plants.
Check, the number of plant columns are the union of all the three materials. Isn’t it dynamic?
Please find the working program for the above requirement here.
REPORT zsapyard. *----------------------------------------------------------------------* * Created by : SAPYard (http://www.sapyard.com/) * * Purpose : Program to show Dynamic Internal table * * Visit http://www.sapyard.com/ for SAP Technical Tips & Solutions * *----------------------------------------------------------------------* *---------------------------------------------------------------------* * POOLS * *---------------------------------------------------------------------* TYPE-POOLS: slis. *---------------------------------------------------------------------* * TABLES * *---------------------------------------------------------------------* TABLES: mara. *---------------------------------------------------------------------* * TYPES *---------------------------------------------------------------------* TYPES: BEGIN OF x_data, matnr TYPE matnr, werks TYPE werks_d, END OF x_data. *---------------------------------------------------------------------* * DATA * *---------------------------------------------------------------------* DATA: * Internal tables i_data TYPE STANDARD TABLE OF x_data, i_data_temp TYPE STANDARD TABLE OF x_data, i_fcat TYPE lvc_t_fcat, i_dynamic_table TYPE REF TO data, i_plant TYPE STANDARD TABLE OF x_plant, i_fieldcat TYPE slis_t_fieldcat_alv, * Work ara wa_fcat TYPE lvc_s_fcat, wa_dyn_line TYPE REF TO data, wa_plant TYPE x_plant, wa_data TYPE x_data, * Variable v_field_name TYPE fieldname, v_tabix TYPE sytabix, v_fieldname TYPE fieldname, v_seltext TYPE scrtext_l. *---------------------------------------------------------------------* * Field Symbols * *---------------------------------------------------------------------* FIELD-SYMBOLS: <i_dyn_table> TYPE STANDARD TABLE, <i_final_table> TYPE STANDARD TABLE, <wa_dyn> TYPE any, <wa_final> TYPE any. *---------------------------------------------------------------------* * SELECTION SCREEN * *---------------------------------------------------------------------* SELECT-OPTIONS: s_matnr FOR mara-matnr. *---------------------------------------------------------------------* * INITIALIZATION * *---------------------------------------------------------------------* INITIALIZATION. * Select data *---------------------------------------------------------------------* * START-OF-SELECTION. * *---------------------------------------------------------------------* START-OF-SELECTION. PERFORM sub_slect_data. *---------------------------------------------------------------------* * END-OF-SELECTION. * *---------------------------------------------------------------------* END-OF-SELECTION. * Populate the dynamic columns needed for each run PERFORM sub_populate_catlog. * Build the dynamic internal table PERFORM sub_build_int_table. * Build ALF Field Catalog information PERFORM sub_alv_field_cat. * Display data PERFORM sub_display_data. *---------------------------------------------------------------------* * SUB ROUTINES * *---------------------------------------------------------------------* *&---------------------------------------------------------------------* *& Form SUB_SLECT_DATA *&---------------------------------------------------------------------* FORM sub_slect_data . SELECT matnr werks INTO TABLE i_data FROM marc WHERE matnr IN s_matnr. IF sy-subrc EQ 0. SORT i_data BY matnr. i_data_temp[] = i_data[]. SORT i_data_temp BY werks. DELETE ADJACENT DUPLICATES FROM i_data_temp COMPARING werks. ENDIF. ENDFORM. *&---------------------------------------------------------------------* *& Form SUB_POPULATE_CATLOG *&---------------------------------------------------------------------* FORM sub_populate_catlog . v_field_name = 'MATNR'. * There is one Material column PERFORM sub_pop_field_catlog USING v_field_name. v_field_name = 'WERKS'. * There would be 'N' number of dynamic Plant columns * depending on the material and plants combination LOOP AT i_data_temp INTO wa_data. PERFORM sub_pop_field_catlog USING v_field_name. ENDLOOP. ENDFORM. *&---------------------------------------------------------------------* *& Form SUB_POP_FIELD_CATLOG *&---------------------------------------------------------------------* FORM sub_pop_field_catlog USING p_l_field_name TYPE fieldname. DATA: l_i_dfies TYPE STANDARD TABLE OF dfies, l_wa_dfies TYPE dfies. * Call FM CALL FUNCTION 'DDIF_FIELDINFO_GET' EXPORTING tabname = 'MARC' fieldname = p_l_field_name TABLES dfies_tab = l_i_dfies EXCEPTIONS not_found = 1 internal_error = 2 OTHERS = 3. IF sy-subrc EQ 0. CLEAR l_wa_dfies. READ TABLE l_i_dfies INTO l_wa_dfies INDEX 1. CLEAR wa_fcat. * Since we want the Plant number to be the header text * Replacing the field name with actual plant value IF v_field_name = 'WERKS'. l_wa_dfies-fieldname = wa_data-werks. ENDIF. MOVE-CORRESPONDING l_wa_dfies TO wa_fcat. APPEND wa_fcat TO i_fcat. ENDIF. ENDFORM. *&---------------------------------------------------------------------* *& Form SUB_BUILD_INT_TABLE *&---------------------------------------------------------------------* FORM sub_build_int_table . * Prepare the dynamic internal table with required columns of each run CALL METHOD cl_alv_table_create=>create_dynamic_table EXPORTING it_fieldcatalog = i_fcat IMPORTING ep_table = i_dynamic_table EXCEPTIONS generate_subpool_dir_full = 1 OTHERS = 2. * Assign the structure of dynamic table to field symbol ASSIGN i_dynamic_table->* TO <i_dyn_table>. * Create the dynamic work area CREATE DATA wa_dyn_line LIKE LINE OF <i_dyn_table>. ASSIGN wa_dyn_line->* TO <wa_dyn>. ENDFORM. *&---------------------------------------------------------------------* *& Form SUB_ALV_FIELD_CAT *&---------------------------------------------------------------------* FORM sub_alv_field_cat . * Build field catalog for Material PERFORM sub_fill_alv_field_cat USING 'MATNR' '<I_DYN_TABLE>' 'L' 'Material Number' 36. * Number of Plant columns would be dynamic for Plants LOOP AT i_data_temp INTO wa_data. v_fieldname = wa_data-werks. v_seltext = wa_data-werks. PERFORM sub_fill_alv_field_cat USING v_fieldname '<I_DYN_TABLE>' 'L' v_seltext 8. ENDLOOP. ENDFORM. *&---------------------------------------------------------------------* *& Form SUB_FILL_ALV_FIELD_CAT *&---------------------------------------------------------------------* FORM sub_fill_alv_field_cat USING p_fldnam TYPE fieldname p_tabnam TYPE tabname p_justif TYPE char1 p_seltext TYPE dd03p-scrtext_l p_outlen TYPE i. DATA l_lfl_fcat TYPE slis_fieldcat_alv. l_lfl_fcat-fieldname = p_fldnam. l_lfl_fcat-tabname = p_tabnam. l_lfl_fcat-just = p_justif. l_lfl_fcat-seltext_l = p_seltext. l_lfl_fcat-outputlen = p_outlen. APPEND l_lfl_fcat TO i_fieldcat. CLEAR l_lfl_fcat. ENDFORM. *&---------------------------------------------------------------------* *& Form SUB_DISPLAY_DATA *&---------------------------------------------------------------------* FORM sub_display_data . DATA: l_count TYPE i, l_factor TYPE i, l_wa_layout TYPE slis_layout_alv. LOOP AT i_data INTO wa_data. CLEAR: l_factor, l_count. READ TABLE i_data_temp WITH KEY werks = wa_data-werks TRANSPORTING NO FIELDS BINARY SEARCH. IF sy-subrc EQ 0. <wa_dyn>+0(18) = wa_data-matnr. l_factor = sy-tabix - 1. l_count = 36 + ( 8 * l_factor ). <wa_dyn>+l_count(8) = 'X'. AT END OF matnr. APPEND <wa_dyn> TO <i_dyn_table>. CLEAR <wa_dyn>. ENDAT. ENDIF. ENDLOOP. l_wa_layout-colwidth_optimize = 'X'. l_wa_layout-zebra = 'X'. * Funtion module for displaying the ALV report CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY' EXPORTING i_callback_program = sy-repid is_layout = l_wa_layout it_fieldcat = i_fieldcat TABLES t_outtab = <i_dyn_table> EXCEPTIONS program_error = 1 OTHERS = 2. ENDFORM.
If you want to get such practical tweaks and tricks straight to your inbox, please SUBSCRIBE. We respect your privacy and take protecting it seriously.
If you liked this post, please hit the share buttons. Please like us at facebook and encourage us. If you have any suggestions, criticism, comments or questions, please comment or reach out to us.
Thank you very much for your time!!
Image source: www.mobygames.com (modified)