SALV Editable with Single (custom) Method
不使用按钮
找到一个被触发但在输出显示给用户之前的事件。 找到一个可以在 Grid 和 Full Screen ALV 中工作的事件。
Full Screen ALV 触发 TOP_OF_PAGE 而不是 Grid ALV,至于 Grid 没有直接的 TOP_OF_PAGE。 Full Screen ALV 在使用 O_SALV->SET_TOP_OF_LIST( ) 方法创建页面顶部时触发它。 这也会在 ALV 中显示一个标题。 对于 Grid,您需要为 CL_DD_DOCUMENT 创建一个对象,将其传递给 Grid 对象并引发事件 TOP_OF_PAGE。 没有 Grid 开始,无法分配标题,因此无法使 TOP_OF_PAGE 事件起作用。
EVENT AFTER_REFRESH
系统完成 ALV 渲染后触发事件 AFTER_REFRESH – 解析字段目录、发送到 DP(数据提供者)又名前端的数据、应用布局、创建工具栏以及所有其他与 ALV 相关的内容。 现在,如何在没有 Grid 对象的情况下捕获此事件。 因此,声明了一个事件处理程序来处理类 CL_GUI_ALV_GRID 的事件 AFTER_REFRESH。 诀窍是使用 SET EVENT HANDLER 添加 FOR ALL INSTANCES 来注册事件。
“To gain an access to the underlying object and do the magic"
SET HANDLER lo_event_h->on_after_refresh
FOR ALL INSTANCES
ACTIVATION ‘X’.
FOR ALL INSTANCES 非常强大。 它可以为该事件所属的任何对象注册该事件,即使该对象是在注册处理程序后实例化的。 这在这种情况下非常有用,因为 Grid 对象尚未实例化。
避免无限循环陷阱
要使 Grid 可编辑,可以使用以下 REFRESH_TABLE_DISPLAY() 调用或方法 SET_READY_FOR_INPUT 调用传递 LAYOUT-EDIT = ‘X’。 问题是,这两种方法都会调用方法 SOFT_REFRESH_TABLE_DISPLAY 并引发事件 AFTER_REFRESH。 这将再次被我们的事件处理程序捕获。 事件处理程序将通过刷新使网格再次可编辑——因此进入循环。
"Deregister the event handler"
SET HANDLER me->on_after_refresh
FOR ALL INSTANCES
ACTIVATION space.
为避免这种情况,我们将关闭 - 更技术地取消注册事件处理程序。 使用 SET HANDLER 中的附加 ACTIVATION 空间将为我们做到这一点。
工具栏
接下来是工具栏。 工具栏中的编辑按钮无需任何额外工作即可显示,但对于 Grid,有一些特殊的逻辑会阻止它在工具栏中创建编辑按钮。 这一切都发生在方法 CL_SALV_CONTROLLER_EVENTS=> RAISE_BUILD_UIFUNCTION 中,其中只显示了几个按钮。
因此,我们将欺骗工具栏添加相同的缺失按钮。 为此,我们需要为 CL_GUI_ALV_GRID 注册事件 TOOLBAR。 使用 FOR ALL INSTANCE 也可以这样做。
"Only for GRID, would need to add the toolbar buttons"
IF io_salv->get_display_object( ) = 3.
SET HANDLER lo_event_h->on_toolbar
FOR ALL INSTANCES
ACTIVATION ‘X’.
ENDIF.
使其可编辑的单一方法
不是开箱即用的单一方法,但将所有这些逻辑都包含在一个方法中。 通过在 DISPLAY 方法之前传递 ALV 对象来调用此方法,一切都完成了。
该方法将注册事件 AFTER_REFRESH 和 TOOLBAR(用于网格)。 该类还在本地类中承载事件处理程序方法。 事件处理程序将使网格可编辑并在工具栏中添加按钮。 使其可编辑的所有复杂性都隐藏并包装在此方法中。
此外,此方法将控制多个 SALV 对象的逻辑。 使用具有对象池设计模式的事件处理程序的可选参数 SENDER。
"Make grid editable: call before display"
zcl_test_np_salv_model=>set_editable( go_alv ).
实现结果
- Full screen ALV generated by SALV in Editable mode
- ALV Grid generated by SALV in Editable mode
- Multiple Grid, only one is editable
完整代码实现
CLASS ZCL_TEST_NP_SALV_MODEL DEFINITION.
PUBLIC FINAL create public.
PUBLIC SECTION.
class-methods SET_EDITABLE
importing !IO_SALV type ref to CL_SALV_TABLE .
PROTECTED SECTION.
PRIVATE SECTION.
class-data o_event_h type ref to OBJECT.
ENDCLASS.
CLASS ZCL_TEST_NP_SALV_MODEL IMPLEMENTATION.
"IO_SALV TYPE REF TO CL_SALV_TABLE"
METHOD set_editable.
DATA: lo_event_h TYPE REF TO lcl_event_handler.
"Event handler"
IF zcl_test_np_salv_model=>o_event_h IS NOT BOUND.
CREATE OBJECT zcl_test_np_salv_model=>o_event_h TYPE lcl_event_handler.
ENDIF.
lo_event_h ?= zcl_test_np_salv_model=>o_event_h.
APPEND io_salv TO lo_event_h->t_salv.
"To gain an access to the underlying object and do the magic"
SET HANDLER lo_event_h->on_after_refresh FOR ALL INSTANCES ACTIVATION ‘X’.
"only for GRID, would need to add the toolbar buttons"
IF io_salv->get_display_object( ) = 3.
SET HANDLER lo_event_h->on_toolbar FOR ALL INSTANCES ACTIVATION ‘X’.
ENDIF.
ENDMETHOD.
ENDCLASS.
*——————————————————————--------------—-*
* Event handler ALV events
*———————————————————————---------------*
CLASS lcl_event_handler DEFINITION.
PUBLIC SECTION.
METHODS: on_after_refresh FOR EVENT after_refresh OF cl_gui_alv_grid
IMPORTING
sender,
on_toolbar FOR EVENT toolbar OF cl_gui_alv_grid
IMPORTING
e_object
e_interactive
sender.
DATA: t_salv TYPE STANDARD TABLE OF REF TO cl_salv_table.
ENDCLASS. "lcl_event_handler DEFINITION"
CLASS lcl_event_handler IMPLEMENTATION.
METHOD on_after_refresh.
DATA: lo_grid TYPE REF TO cl_gui_alv_grid.
DATA: ls_layout TYPE lvc_s_layo.
DATA: lo_salv TYPE REF TO cl_salv_table.
TRY .
LOOP AT t_salv INTO lo_salv.
lo_grid = zcl_test_np_salv_model=>get_grid( lo_salv ).
CHECK lo_grid EQ sender.
"Deregister the event handler"
SET HANDLER me->on_after_refresh FOR ALL INSTANCES ACTIVATION space.
"Set editable"
ls_layout–edit = ‘X’.
lo_grid->set_frontend_layout( ls_layout ).
lo_grid->set_ready_for_input( 1 ).
ENDLOOP.
CATCH cx_salv_error.
ENDTRY.
ENDMETHOD. "ON_AFTER_REFRESH"
METHOD on_toolbar.
DATA: lo_grid TYPE REF TO cl_gui_alv_grid.
DATA: ls_layout TYPE lvc_s_layo.
DATA: mt_toolbar TYPE ttb_button.
DATA: ls_toolbar LIKE LINE OF mt_toolbar.
DATA: lo_salv TYPE REF TO cl_salv_table.
TRY .
LOOP AT t_salv INTO lo_salv.
lo_grid = zcl_test_np_salv_model=>get_grid( lo_salv ).
IF lo_grid EQ sender.
EXIT.
ELSE.
CLEAR lo_grid.
ENDIF.
ENDLOOP.
CATCH cx_salv_msg.
EXIT.
ENDTRY.
CHECK lo_grid IS BOUND.
CHECK lo_grid->is_ready_for_input( ) = 1.
"Toolbar Button CHECK"
CLEAR ls_toolbar.
ls_toolbar–function = cl_gui_alv_grid=>mc_fc_check.
ls_toolbar–quickinfo = text–053. "Eingaben prfen"
ls_toolbar–icon = icon_check.
ls_toolbar–disabled = space.
APPEND ls_toolbar TO mt_toolbar.
"Toolbar Seperator"
CLEAR ls_toolbar.
ls_toolbar–function = ‘&&SEP01’.
ls_toolbar–butn_type = 3.
APPEND ls_toolbar TO mt_toolbar.
"Toolbar Button CUT"
CLEAR ls_toolbar.
ls_toolbar–function = cl_gui_alv_grid=>mc_fc_loc_cut.
ls_toolbar–quickinfo = text–046. "Ausschneiden"
ls_toolbar–icon = icon_system_cut.
ls_toolbar–disabled = space.
APPEND ls_toolbar TO mt_toolbar.
"Toolbar Button COPY"
CLEAR ls_toolbar.
ls_toolbar–function = cl_gui_alv_grid=>mc_fc_loc_copy.
ls_toolbar–quickinfo = text–045. "Kopieren"
ls_toolbar–icon = icon_system_copy.
ls_toolbar–disabled = space.
APPEND ls_toolbar TO mt_toolbar.
"Toolbar Button PASTE OVER ROW"
CLEAR ls_toolbar.
ls_toolbar–function = cl_gui_alv_grid=>mc_fc_loc_paste.
ls_toolbar–quickinfo = text–047.
ls_toolbar–icon = icon_system_paste.
ls_toolbar–disabled = space.
APPEND ls_toolbar TO mt_toolbar.
"Toolbar Button PASTE NEW ROW"
CLEAR ls_toolbar.
ls_toolbar–function = cl_gui_alv_grid=>mc_fc_loc_paste_new_row.
ls_toolbar–quickinfo = text–063.
ls_toolbar–icon = icon_system_paste.
ls_toolbar–disabled = space.
APPEND ls_toolbar TO mt_toolbar.
"Toolbar Button UNDO"
CLEAR ls_toolbar.
ls_toolbar–function = cl_gui_alv_grid=>mc_fc_loc_undo.
ls_toolbar–quickinfo = text–052. “Rckgngig
ls_toolbar–icon = icon_system_undo.
ls_toolbar–disabled = space.
APPEND ls_toolbar TO mt_toolbar.
"Toolbar Separator"
CLEAR ls_toolbar.
ls_toolbar–function = ‘&&SEP02’.
ls_toolbar–butn_type = 3.
APPEND ls_toolbar TO mt_toolbar.
"Toolbar Button APPEND ROW"
CLEAR ls_toolbar.
ls_toolbar–function = cl_gui_alv_grid=>mc_fc_loc_append_row.
ls_toolbar–quickinfo = text–054. “Zeile anhngen"
ls_toolbar–icon = icon_create.
ls_toolbar–disabled = space.
APPEND ls_toolbar TO mt_toolbar.
"Toolbar Button INSERT ROW"
CLEAR ls_toolbar.
ls_toolbar–function = cl_gui_alv_grid=>mc_fc_loc_insert_row.
ls_toolbar–quickinfo = text–048. “Zeile einfgen
ls_toolbar–icon = icon_insert_row.
ls_toolbar–disabled = space.
APPEND ls_toolbar TO mt_toolbar.
"Toolbar Button DELETE ROW"
CLEAR ls_toolbar.
ls_toolbar–function = cl_gui_alv_grid=>mc_fc_loc_delete_row.
ls_toolbar–quickinfo = text–049. “Zeile lschen"
ls_toolbar–icon = icon_delete_row.
ls_toolbar–disabled = space.
APPEND ls_toolbar TO mt_toolbar.
"Toolbar Button COPY ROW"
CLEAR ls_toolbar.
ls_toolbar–function = cl_gui_alv_grid=>mc_fc_loc_copy_row.
ls_toolbar–quickinfo = text–051. “Duplizieren"
ls_toolbar–icon = icon_copy_object.
ls_toolbar–disabled = space.
APPEND ls_toolbar TO mt_toolbar.
"Toolbar Separator"
CLEAR ls_toolbar.
ls_toolbar–function = ‘&&SEP03’.
ls_toolbar–butn_type = 3.
APPEND ls_toolbar TO mt_toolbar.
APPEND LINES OF mt_toolbar TO e_object->mt_toolbar.
ENDMETHOD. "on_toolbar"
ENDCLASS. "lcl_event_handler IMPLEMENTATION"