Anda di halaman 1dari 8

Event Handling in 2 Grids simultaneously(ALV OOPS(SAP ABAP))

Purpose:

Handling Events in two grids simultaneously on the same Screen.


As being developed by OOPS, ALV grid control has some events that are triggered during
interaction between the user.
These events are used to utilize some additional functionalities of the ALV grid.
For these types of functionalities we require a class to be implemented to be the event handler for
the ALV Grid instance.

Technical Information:

Handling Events in two grids at the same time using ALV with OOPS:

1) Step 1:
First create a screen including two custom containers (CONT1 and CONT2) in it.
On these two containers we are going to handle the data changes and capture them on any user
interaction.

2) Step 2:
In the PBO(Process Before Output) section of the screen ,include a Module to display the ALV
grid in the container.
Ex: Module alv_display.

3) Step 3:
In the Module alv_display-

a.)Create an object for the 1st custom container exporting the name as parameter which links
the program to the screen element.
CREATE OBJECT ob_custom1
EXPORTING
container_name = 'CONT1'.

Where container_name is the name of the container given in the screen.

b.)Next create an object for the ALV Grid1 exporting the parent container name.
CREATE OBJECT ob_grid1
EXPORTING
i_parent = ob_custom1.

c.)Create an object event receiver and then set a handler on all the cells of the grid for
handling any change in data in any of the cells of the grid.
CREATE OBJECT event_receiver.
SET HANDLER event_receiver->handle_data_changed FOR ob_grid1.

d.)Register the event you want to handle.For ex:”Enter” event.


CALL METHOD ob_grid1->register_edit_event
EXPORTING
i_event_id = cl_gui_alv_grid=>mc_evt_enter.
This registers the enter event to all the cells present in the grid i.e on changing any value in any
of the cells and pressing enter will capture the value in the grid.

e.)Build the fieldcatalog and the Layout for the grid.


And call the Method to display the data in the Grid passing the final internal table
containing the values ,the fieldcatalog and the layout for the first time when the container is
empty.

If ob_custom1 is initial.
CALL METHOD ob_grid1->set_table_for_first_display
EXPORTING
is_layout = l_layout
CHANGING
it_fieldcatalog = t_fcat_final1
it_outtab = t_final1.
Endif.

f.)If the custom container is not empty (i.e having some values and the grid needs to be
populated with new values),a method to refresh the grid needs to be called.

If ob_custom1 is not initial.


CALL METHOD ob_grid1->refresh_table_display
EXPORTING
is_stable = l_lvc_s_stbl
EXCEPTIONS
finished = 1
OTHERS = 2.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
Endif.

Repeat the same steps for the 2nd container as well.

4) Step 4:
A class is implemented to handle the events in the two Grids.
In the class definition we call the event for controlling data changes when ALV grid is
editable which invokes the class implementation on any interaction by the user when there is any
change in the ALV grid..

CLASS lcl_event_receiver DEFINITION.


PUBLIC SECTION.
METHODS handle_data_changed
FOR EVENT data_changed OF cl_gui_alv_grid
IMPORTING
er_data_changed
sender.
ENDCLASS.

Here Sender is an importing parameter which passes all the grids present on the screen to
the class implementation.

5) Step 5:
In the class implementation, handle the events that you want to be triggered i.e the actual
handling of event is done.

CLASS lcl_event_receiver IMPLEMENTATION.


METHOD handle_data_changed.
CASE sender.
WHEN ob_grid1.
TRY.
*populate all the changed data into ont table with their roww_ids*
LOOP AT er_data_changed->mt_mod_cells INTO l_good .
CLEAR : w_error_flag.
CASE l_good-fieldname.

* check if column 'F1' of this row was changed


WHEN 'F1'.
v_F1_flg = 'X'.
"Flag set to indicate the row modification
IF l_good-value IS NOT INITIAL.
w_F1 = l_good-value.
ENDIF.

* check if column 'F2' of this row was changed


WHEN 'F2'.
v_F2_flg = 'X'.
"Flag set to indicate the row modification
IF l_good-value IS NOT INITIAL.
w_F2 = l_good-value.
ENDIF.
ENDCASE.

* Populating t_changed_rows table with all the changed row ids *


AT END OF row_id.

IF w_error_flag IS INITIAL.
"if no error that row id is marked for futher manipulation of data
READ TABLE t_final2 ASSIGNING <fs_final> INDEX
l_good-row_id.

IF <fs_final> IS ASSIGNED .
IF v_F1_flg IS NOT INITIAL.
<fs_final>-F1 = w_ F1.
ENDIF.
IF v_F2_flg IS NOT INITIAL.
<fs_final>-F2 = w_ F2.
ENDIF.
w_change_flag = abap_true.
CLEAR:w_F1, v_F1_flg, w_F2 ,v_F2_flg,

UNASSIGN <fs_final>.
ENDIF.
ENDIF.
ENDLOOP.

*& Get the cursor id from the cell on which data was modified&*
CLEAR : l_row_no, l_col_id ,l_row_id.
ob_grid2->get_current_cell(
IMPORTING
es_row_id = l_row_id
es_col_id = l_col_id
es_row_no = l_row_no
).

*& Refreshing the grid with modified data&*


IF t_final1 IS NOT INITIAL.
CALL METHOD ob_grid1->refresh_table_display
EXPORTING
is_stable = l_lvc_s_stbl
EXCEPTIONS
finished = 1
OTHERS = 2.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
ENDIF.

*& Set the cursor to the cell on which data was modified&*
ob_grid1->set_current_cell_via_id( is_row_id = l_row_id
is_column_id = l_col_id
is_row_no = l_row_no ).
CATCH cx_sy_conversion_no_number INTO error_ref.
err_text = error_ref->get_text( ).
WRITE err_text.
CATCH cx_root INTO oref.
text = oref->get_text( ).
ENDTRY.

WHEN ob_grid2.
TRY.
*populate all the changed data into ont table with their roww_ids*
LOOP AT er_data_changed->mt_mod_cells INTO l_good .
CLEAR : w_error_flag.
CASE l_good-fieldname.

* check if column 'G1' of this row was changed


WHEN 'G1'.
v_G1_flg = 'X'.
"Flag set to indicate the row modification
IF l_good-value IS NOT INITIAL.
w_G1 = l_good-value.
ENDIF.

* check if column 'G2' of this row was changed


WHEN 'G2'.
v_G2_flg = 'X'.
"Flag set to indicate the row modification
IF l_good-value IS NOT INITIAL.
w_G2 = l_good-value.
ENDIF.
ENDCASE.

* Populating t_changed_rows table with all the changed row ids *


AT END OF row_id.

IF w_error_flag IS INITIAL.
"if no error that row id is marked for futher manipulation of data
READ TABLE t_final2 ASSIGNING <fs_final> INDEX
l_good-row_id.

IF <fs_final> IS ASSIGNED .
IF v_G1_flg IS NOT INITIAL.
<fs_final>-G1 = w_ G1.
ENDIF.
IF v_G2_flg IS NOT INITIAL.
<fs_final>-G2 = w_ G2.
ENDIF.

w_change_flag = abap_true.
CLEAR:w_G1, v_G1_flg, w_G2 ,v_G2_flg,

UNASSIGN <fs_final>.
ENDIF.
ENDIF.
ENDLOOP.

*& Get the cursor id from the cell on which data was modified&*
CLEAR : l_row_no, l_col_id ,l_row_id.

ob_grid2->get_current_cell(
IMPORTING
es_row_id = l_row_id
es_col_id = l_col_id
es_row_no = l_row_no
).

*& Refreshing the grid with modified data&*


IF t_final2 IS NOT INITIAL.
CALL METHOD ob_grid2->refresh_table_display
EXPORTING
is_stable = l_lvc_s_stbl
EXCEPTIONS
finished = 1
OTHERS = 2.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
ENDIF.

*& Set the cursor to the cell on which data was modified&*
ob_grid2->set_current_cell_via_id( is_row_id = l_row_id
is_column_id = l_col_id
is_row_no = l_row_no ).

CATCH cx_sy_conversion_no_number INTO error_ref.


err_text = error_ref->get_text( ).
WRITE err_text.
CATCH cx_root INTO oref.
text = oref->get_text( ).
ENDTRY.
ENDCASE.
ENDMETHOD.
ENDCLASS.

6) Step 6:
Whenever there is any change in data in the grid and you press some Function Code it doesn’t
register the changes you made to the grid.
For the Function Codes like SAVE etc. you need to call the method explicitly in the
PAI(Process After Input) of the screen.

WHEN 'SAVE'.
CLEAR : ok_code.
CALL METHOD ob_grid1->check_changed_data.
CALL METHOD ob_grid2->check_changed_data.
ENDCASE.

Which triggers the class implementation if there is any change in data and any Func. Code button
is pressed for both the grids.