You are on page 1of 13

Adding columns dynamically in ALV table

Generally when displaying report outputs we have a definite table structure which needs to be displayed in an ALV output. But for certain reports where the data determines the number of columns to be displayed in the output we need to use a special approach. Demonstrated below is a sample program which determines the wage types and their amounts which been changed in 2 consecutive payroll runs. Here the number of wage types may vary for which the amount has been changed in 2 consecutive payroll runs. Also, this number might not be the same for the whole list of employees for whom the report is executed. Hence, we need to consider the highest number by comparing the data of all the employees in the selection. The program also demonstrates how to add various ALV functions and set column text dynamically. The main program:

REPORT zhr_payroll_retro_delta.

INCLUDE zhr_payroll_retro_delta_t. INCLUDE zhr_payroll_retro_delta_f. START-OF-SELECTION. GET pernr. *Here we get the changed wagetypes for the selected pernr using Payroll area and For period PERFORM f_get_ee_data USING pernr-pernr p_fper-low p_pyarea-low. END-OF-SELECTION. *After the data for all the employees has been getherd it is arranged in the ALV format and displayed PERFORM process_data.

Getting employee payroll data Steps: Get payroll data for pernr using FM 'CU_READ_RGDIR' Then get the A and P entries for the selected For Period Based on the sequence number for A as well as P records get the Payroll result data using FM 'PYXX_READ_PAYROLL_RESULT' Delet the entries where the wage type amount is 0 Append the entries of A and P payroll results to a common table rt_all. SORT rt_all ASCENDING BY lgart. DELETE ADJACENT DUPLICATES FROM rt_all COMPARING lgart v0typ v0znr. Compare the wagetype amounts and count the wagetypes add to column count in case the count of differing wagetypes is greater than the last count stored in the global variable

Arranging and displaying the data in ALV format

FORM process_data .

* Dynamic Selection fields TYPES: BEGIN OF ty_fields, field TYPE char30, END OF ty_fields, BEGIN OF ty_lgtxt, lgart TYPE lgart, lgtxt TYPE lgtxt, END OF ty_lgtxt.

DATA :i_index(3) TYPE c, col_count(3) TYPE c, lv_fieldname TYPE char30, lt_lgtxt TYPE TABLE OF ty_lgtxt,

wa_lgtxt

TYPE ty_lgtxt.

* Dynamic Table creation DATA: lo_struct lo_element lo_new_type lo_new_tab lo_data TYPE REF TO cl_abap_structdescr,

TYPE REF TO cl_abap_elemdescr, TYPE REF TO cl_abap_structdescr, TYPE REF TO cl_abap_tabledescr, TYPE REF TO data,

lo_line_data TYPE REF TO data, lt_comp lt_tot_comp la_comp TYPE cl_abap_structdescr=>component_table, TYPE cl_abap_structdescr=>component_table, LIKE LINE OF lt_comp.

DATA: lt_fields TYPE STANDARD TABLE OF ty_fields, la_fields TYPE ty_fields.

DATA: lo_alv TYPE REF TO cl_salv_table.

DATA: lo_cols TYPE REF TO cl_salv_columns.

DATA: lo_column TYPE REF TO cl_salv_column.

DATA: gr_layout

TYPE REF TO cl_salv_layout.

DATA: ls_key

TYPE salv_s_layout_key.

DATA: lo_funct TYPE REF TO CL_SALV_FUNCTIONS_LIST.

* field symbols to access the dynamic table FIELD-SYMBOLS: <f_tab> TYPE STANDARD TABLE, <f_line> TYPE ANY, <f_field> TYPE ANY.

*Getting Components from existing type this contains the static components of the table lo_struct ?= cl_abap_typedescr=>describe_by_name( 'T_FINAL_PART1' ). lt_comp =lo_struct->get_components( ). APPEND LINES OF lt_comp TO lt_tot_comp.

CLEAR i_index. DO count_max TIMES. i_index = i_index + 1. CONDENSE i_index. lo_element ?= cl_abap_elemdescr=>describe_by_name( 'LGART' ). CONCATENATE 'LGART' i_index INTO la_comp-name. * Field type la_comp-type = cl_abap_elemdescr=>get_c( p_length = lo_element->length ). APPEND la_comp TO lt_tot_comp. CLEAR: la_comp. *LGTXT

lo_element ?= cl_abap_elemdescr=>describe_by_name( 'LGTXT' ). CONCATENATE 'LGTXT' i_index INTO la_comp-name. * Field type la_comp-type = cl_abap_elemdescr=>get_c( p_length = lo_element->length ). APPEND la_comp TO lt_tot_comp. CLEAR: la_comp. lo_element ?= cl_abap_elemdescr=>describe_by_name( 'BETRG' ). CONCATENATE 'OLD_AMT' i_index INTO la_comp-name. * Field type la_comp-type = cl_abap_elemdescr=>get_p( p_length = lo_element->length p_decimals = lo_element->decimals ).

APPEND la_comp TO lt_tot_comp. CLEAR: la_comp. lo_element ?= cl_abap_elemdescr=>describe_by_name( 'BETRG' ). CONCATENATE 'NEW_AMT' i_index INTO la_comp-name. * Field type la_comp-type = cl_abap_elemdescr=>get_p( p_length = lo_element->length p_decimals = lo_element->decimals ). APPEND la_comp TO lt_tot_comp. CLEAR: la_comp. ENDDO.

lo_new_type = cl_abap_structdescr=>create(lt_tot_comp ). *After all the components are added to the structure *The New Table type is created lo_new_tab = cl_abap_tabledescr=>create( p_line_type =lo_new_type p_table_kind = cl_abap_tabledescr=>tablekind_std p_unique * *data to handle the new table type CREATE DATA lo_data TYPE HANDLE lo_new_tab. CREATE DATA lo_line_data TYPE HANDLE lo_new_type. * * New internal table in the fieldsymbols ASSIGN lo_data->* TO <f_tab>. ASSIGN lo_line_data->* TO <f_line>. = abap_false ).

SORT i_pernr_detail ASCENDING BY pernr. *Getting wage type text SELECT lgartlgtxt FROM t512t INTO TABLE lt_lgtxt FOR ALL ENTRIES IN i_pernr_detail WHERE lgart = i_pernr_detail-lgart AND sprsl = sy-langu. LOOP AT i_pernr_detail INTO wa_pernr_detail . AT NEW pernr. CLEAR col_count.

ENDAT. CLEAR wa_lgtxt.

ASSIGN COMPONENT 'PERNR' OF STRUCTURE <f_line> TO <f_field>. <f_field> = wa_pernr_detail-pernr. UNASSIGN <f_field>. ASSIGN COMPONENT 'FOR_PER' OF STRUCTURE <f_line> TO <f_field>. <f_field> = wa_pernr_detail-for_per. UNASSIGN <f_field>. ASSIGN COMPONENT 'IN_PER' OF STRUCTURE <f_line> TO <f_field>. <f_field> = wa_pernr_detail-in_per. UNASSIGN <f_field>.

col_count = col_count + 1. CONDENSE col_count. CONCATENATE 'LGART' col_count INTO lv_fieldname. ASSIGN COMPONENT lv_fieldname OF STRUCTURE <f_line> TO <f_field>. <f_field> = wa_pernr_detail-lgart. UNASSIGN <f_field>.

CLEAR lv_fieldname. CONCATENATE 'LGTXT' col_count INTO lv_fieldname. ASSIGN COMPONENT lv_fieldname OF STRUCTURE <f_line> TO <f_field>. READ TABLE lt_lgtxt INTO wa_lgtxt WITH KEY lgart = wa_pernr_detail-lgart. IF wa_lgtxtIS NOT INITIAL.

<f_field> = wa_lgtxt-lgtxt. ENDIF. UNASSIGN <f_field>."lg_text CLEAR lv_fieldname. CONCATENATE 'OLD_AMT' col_count INTO lv_fieldname. ASSIGN COMPONENT lv_fieldname OF STRUCTURE <f_line> TO <f_field>. <f_field> = wa_pernr_detail-old_amt. UNASSIGN <f_field>. CLEAR lv_fieldname. CONCATENATE 'NEW_AMT' col_count INTO lv_fieldname. ASSIGN COMPONENT lv_fieldname OF STRUCTURE <f_line> TO <f_field>. <f_field> = wa_pernr_detail-new_amt. UNASSIGN <f_field>. AT END OF pernr. APPEND <f_line> TO <f_tab>. ENDAT.

ENDLOOP.

TRY. cl_salv_table=>factory( EXPORTING list_display = abap_false IMPORTING r_salv_table = lo_alv

CHANGING t_table = <f_tab> ).

CATCH cx_salv_msg . ENDTRY. * **** Set column texts * Get columns object

lo_cols = lo_alv->get_columns( ). DATA :lv_column_name TYPE lvc_fname, lv_longtext TYPE scrtext_l, lv_medtext TYPE scrtext_m, lv_shorttext TYPE scrtext_s.

CLEAR i_index. *Add the number of columns based on the Max column count DO count_max TIMES. i_index = i_index + 1. CONDENSE i_index. CONCATENATE: 'LGART' i_index INTO lv_column_name, 'Wagetype' i_index INTO lv_longtext, 'Wagetype' i_index INTO lv_medtext, 'WageTy' i_index INTO lv_shorttext.

TRY .

lo_column = lo_cols->get_column(lv_column_name ). lo_column->set_long_text(lv_longtext ). lo_column->set_medium_text(lv_medtext ). lo_column->set_short_text(lv_shorttext ). lo_column->set_output_length( 10 ). CATCH cx_salv_not_found." #EC NO_HANDLER

ENDTRY.

CLEAR: lv_column_name, lv_longtext, lv_medtext, lv_shorttext.

CONCATENATE: 'LGTXT' i_index INTO lv_column_name, 'Description' i_index INTO lv_longtext, 'Description' i_index INTO lv_medtext, 'Desc' i_index INTO lv_shorttext.

TRY . lo_column = lo_cols->get_column(lv_column_name ). lo_column->set_long_text(lv_longtext ). lo_column->set_medium_text(lv_medtext ). lo_column->set_short_text(lv_shorttext ). * lo_column->set_output_length( 10 ).

CATCH cx_salv_not_found." #EC NO_HANDLER

ENDTRY.

CLEAR: lv_column_name, lv_longtext, lv_medtext, lv_shorttext.

CONCATENATE: 'OLD_AMT' i_index INTO lv_column_name, 'Old Amount' i_index INTO lv_longtext, 'Old Amount' i_index INTO lv_medtext, 'Old Amt' i_index INTO lv_shorttext. TRY . lo_column = lo_cols->get_column(lv_column_name ). lo_column->set_long_text(lv_longtext ). lo_column->set_medium_text(lv_medtext ). lo_column->set_short_text(lv_shorttext ). lo_column->set_output_length( 10 ). CATCH cx_salv_not_found." #EC NO_HANDLER

ENDTRY. CLEAR: lv_column_name, lv_longtext, lv_medtext,

lv_shorttext.

CONCATENATE: 'NEW_AMT' i_index INTO lv_column_name, 'New Amount' i_index INTO lv_longtext, 'New Amount' i_index INTO lv_medtext, 'New Amt' i_index INTO lv_shorttext.

TRY . lo_column = lo_cols->get_column(lv_column_name ). lo_column->set_long_text(lv_longtext ). lo_column->set_medium_text(lv_medtext ). lo_column->set_short_text(lv_shorttext ). lo_column->set_output_length( 10 ). CATCH cx_salv_not_found." #EC NO_HANDLER

ENDTRY. ENDDO.

* Add layout variants in report TRY. gr_layout = lo_alv->get_layout( ). "*... set the Layout Key ls_key-report = sy-repid. gr_layout->set_key(ls_key ). "*... set usage of default Layouts

gr_layout->set_default(abap_true ). *... set Layout save restriction gr_layout->set_save_restriction(if_salv_c_layout=>restrict_none ). ENDTRY.

*Add function buttons lo_funct = lo_alv->GET_FUNCTIONS( ). lo_funct->SET_ALL(abap_true ). *Display ALV output lo_alv->display( ).

ENDFORM." PROCESS_DATA

You might also like