Gaining access to the object, when working with ABAP Objects Events, which raised the event would be an added advantage for the event handler method.
When you design an event handler, you might end using the same event handler object for both the objects which raised an event. Consider this scenario: You have two editable ALV grid created using CL_GUI_ALV_GRID on the same screen. To handle the event like DATA_CHANGED, DATA_CHANGED_FINISHED or TOOLBAR, you need the event handler. Since both the ALVs are with similar nature, you decided to use the same Event handler for both – Reduces number of objects and complexity.
Within the event handler, you generally wont need to know which object has raised the event, If the event was raised with necessary parameters. If those parameters, don’t satisfy your need, than you would need to get an access to the object which raised this event. With continuation to above scenario, you get the ER_DATA_CHANGED into your event handler because it is exposed from the DATA_CHANGED.
Parameters for an event handler
methods handle_data_changed for event data_changed of cl_gui_alv_grid importing er_data_changed.
SENDER – An implicit output parameter
In addition to all the event parameters, you can also mention SENDER as an importing parameter when declaring handler method. This SENDER parameter is an implicit output parameter for all the events. Events doesn’t need to define SENDER as one of the output parameter. But it is exposed by event, by default. If Event handler has it declared, it would be available in Event handler method.
For example, the event DATA_CHANGED doesn’t have SENDER defined as such,
.. but you can still declare it in event handler.
Event Handler definition with SENDER
methods handle_data_changed for event data_changed of cl_gui_alv_grid importing er_data_changed sender.
Casting to Original Type
SENDER is a fully typed object. The type would same as the type of the object which would raise the event. It would contain the reference of the object which has raised the event. Thus giving you an ability to leverage all public available methods, attributes etc.
SENDER is fully type, Casting is not required as such. But, I prefer to declare a local variable with type of the event raiser class.
Event Handler Implementation
METHOD handle_data_changed. DATA: lo_grid TYPE REF TO cl_gui_alv_grid. lo_grid ?= sender. . . . ENDMETHOD. "handle_data_changed
This gives me couple of abilities over directly using SENDER:
- I can directly drill down to the class which raised the event
- Reading the code would make it easy as you would use more descriptive name than SENDER
I modified the same sample program as given in previous article ABAP Objects Events – Raising and Handling. Now the program has two instances of LCL_MAIN and same event handler. You can notice that, using SENDER, you can get an access to the object.
* CLASS lcl_main DEFINITION. PUBLIC SECTION. DATA: v_num TYPE i. METHODS: process IMPORTING iv_num TYPE i. EVENTS: cutoff_reached. ENDCLASS. "lcl_main DEFINITION * CLASS lcl_event_handler DEFINITION. PUBLIC SECTION. METHODS: handle_cutoff_reached FOR EVENT cutoff_reached OF lcl_main IMPORTING sender. ENDCLASS. "lcl_event_handler DEFINITION * START-OF-SELECTION. DATA: lo_main TYPE REF TO lcl_main. DATA: lo_main_2 TYPE REF TO lcl_main. DATA: lo_event_handler TYPE REF TO lcl_event_handler. * CREATE OBJECT lo_main. CREATE OBJECT lo_main_2. CREATE OBJECT lo_event_handler. SET HANDLER lo_event_handler->handle_cutoff_reached FOR: lo_main, lo_main_2. * lo_main->process( 5 ). lo_main->process( 10 ). * CLASS lcl_main IMPLEMENTATION. METHOD process. v_num = iv_num. IF iv_num GE 2. RAISE EVENT cutoff_reached. ENDIF. ENDMETHOD. "process ENDCLASS. "lcl_main IMPLEMENTATION * CLASS lcl_event_handler IMPLEMENTATION. METHOD handle_cutoff_reached. * DATA: lo_main_sender TYPE REF TO lcl_main. lo_main_sender ?= sender. * WRITE: / 'Event Processed'. WRITE: lo_main_sender->v_num. * ENDMETHOD. "handle_cutoff_reached ENDCLASS. "lcl_event_handler IMPLEMENTATION