今天研究了一下可编辑的alv,本节讲述如何使用OO实现可编辑的ALV,开始觉得会很难,后来发现相当容易。
最开始的就是将field catelog的edit属性设置为'X',alv可编辑后,我发现再debug进去,内表并没有更新, 所以我想这样去实现:新增一个按钮到alv的tool bar中去, 并且定义一个事件处理器去响应user command事件中新增按钮对应的事件,所以我做了如下工作:
1,在程序中定义一个类,类中定义两个方法:handle_bar_set ,用来增加新按钮 , 再定义一个方法用来处理新增按钮触发的事件
2,后来代码都写好了,发现第一个方法其实没用,只需要新增一个按钮就可以实现编辑功能了,让我其实有些困惑,虽然最后实现了,总觉得这样不是很妥,希望高手多多指教,以下我贴出代码:
主程序:
TABLES: sflight.
TYPE-POOLS: icon.
* Declaration internal table
DATA: gt_sflight TYPE STANDARD TABLE OF sflight.
DATA: gs_sflight TYPE sflight.
* Declaration ALV companents
DATA: gs_field_cat TYPE lvc_s_fcat.
DATA: gt_field_cat TYPE lvc_t_fcat.
DATA: gt_toolbar_ex TYPE TABLE OF sy-ucomm.
DATA: gs_toolbar_ex TYPE ui_func.
* Declare OO components
DATA: go_container TYPE REF TO cl_gui_custom_container.
DATA: go_alv_control TYPE REF TO cl_gui_alv_grid.
DATA: gs_tool_bar TYPE stb_button.
DATA: gt_rows_index TYPE lvc_t_row.
DATA: gs_row_index TYPE lvc_s_row.
* Declare ok code and controlling flag
DATA: ok_code TYPE sy-ucomm.
DATA: g_flag TYPE c.
DATA: g_status(10) TYPE c.
*----------------------------------------------------------------------*
* CLASS cl_event_handler DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS cl_event_handler DEFINITION.
PUBLIC SECTION.
METHODS handle_bar_set FOR EVENT toolbar
OF cl_gui_alv_grid IMPORTING e_object.
ENDCLASS. "cl_event_handler DEFINITION
*----------------------------------------------------------------------*
* CLASS cl_event_handler IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS cl_event_handler IMPLEMENTATION.
METHOD handle_bar_set.
gs_tool_bar-function = 'SAVE'.
gs_tool_bar-icon = icon_system_save.
APPEND gs_tool_bar TO e_object->mt_toolbar.
ENDMETHOD. "change_handler "handle_user_command
ENDCLASS. "cl_event_handler IMPLEMENTATION
START-OF-SELECTION.
PERFORM sub_retrieve_data.
PERFORM sub_generate_field_cat.
CALL SCREEN 9100.
*&---------------------------------------------------------------------*
*& Module STATUS_9100 OUTPUT
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
MODULE status_9100 OUTPUT.
IF g_flag IS INITIAL.
g_status = icon_toggle_display_change.
ELSE.
g_status = icon_display.
ENDIF.
SET PF-STATUS 'STATUS9100'.
ENDMODULE. " STATUS_9100 OUTPUT
*&---------------------------------------------------------------------*
*& Module USER_COMMAND_9100 INPUT
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
MODULE user_command_9100 INPUT.
CASE ok_code.
WHEN 'BACK' OR 'EXIT'.
CALL METHOD go_alv_control->free.
CALL METHOD go_container->free.
LEAVE PROGRAM.
WHEN 'CHAND'.
IF g_flag = 'X'.
PERFORM sub_uneditable_status.
g_flag = ''.
ELSE.
PERFORM sub_editable_status.
g_flag = 'X'.
ENDIF.
* WHEN 'SAVE'.
* PERFORM sub_save_data.
WHEN OTHERS.
ENDCASE.
ENDMODULE. " USER_COMMAND_9100 INPUT
*&---------------------------------------------------------------------*
*& Form SUB_RETRIEVE_DATA
*&---------------------------------------------------------------------*
* Retrieve data from database
*----------------------------------------------------------------------*
FORM sub_retrieve_data .
SELECT *
INTO TABLE gt_sflight
FROM sflight
UP TO 20 ROWS.
ENDFORM. " SUB_RETRIEVE_DATA
*&---------------------------------------------------------------------*
*& Form SUB_GENERATE_FIELD_CAT
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
FORM sub_generate_field_cat .
CALL FUNCTION 'LVC_FIELDCATALOG_MERGE'
EXPORTING
i_structure_name = 'SFLIGHT'
CHANGING
ct_fieldcat = gt_field_cat.
ENDFORM. " SUB_GENERATE_FIELD_CAT
*&---------------------------------------------------------------------*
*& Module ALV_DISPLAY OUTPUT
*&---------------------------------------------------------------------*
* ALV display
*----------------------------------------------------------------------*
MODULE alv_display OUTPUT.
IF go_container IS INITIAL.
DATA: go_handler TYPE REF TO cl_event_handler.
CREATE OBJECT go_container
EXPORTING
container_name = 'GO_CONTAINER'.
CREATE OBJECT go_alv_control
EXPORTING
i_parent = go_container.
CREATE OBJECT go_handler.
SET HANDLER: go_handler->handle_bar_set FOR go_alv_control.
ENDIF.
CALL METHOD go_alv_control->set_table_for_first_display
CHANGING
it_outtab = gt_sflight
it_fieldcatalog = gt_field_cat.
ENDMODULE. " ALV_DISPLAY OUTPUT
*&---------------------------------------------------------------------*
*& Form SUB_EDITABLE_STATUS
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
FORM sub_editable_status .
CLEAR gs_field_cat.
gs_field_cat-edit = 'X'.
MODIFY gt_field_cat FROM gs_field_cat
TRANSPORTING edit
WHERE edit IS INITIAL.
ENDFORM. " SUB_EDITABLE_STATUS
*&---------------------------------------------------------------------*
*& Form SUB_UNEDITABLE_STATUS
*&---------------------------------------------------------------------*
* Change cell's status
*----------------------------------------------------------------------*
FORM sub_uneditable_status .
CLEAR gs_field_cat.
gs_field_cat-edit = ''.
MODIFY gt_field_cat FROM gs_field_cat
TRANSPORTING edit
WHERE edit = 'X'.
ENDFORM. " SUB_UNEDITABLE_STATUS
*&---------------------------------------------------------------------*
*& Form SUB_SAVE_DATA
*&---------------------------------------------------------------------*
* SAVE DATA
*----------------------------------------------------------------------*
FORM sub_save_data .
ENDFORM. " SUB_SAVE_DATA
屏幕中:
PROCESS BEFORE OUTPUT.
MODULE status_9100.
MODULE alv_display.
PROCESS AFTER INPUT.
MODULE user_command_9100.
备注:当中使用了动态status,请读者自行配置