目录
一、问题展示及解决
1、出现问题:在选中sel 选择框后,根据选中行条件同步选中其他行选择框,这是成功的,但是当再次选中别的行选择框后,第一次的选择数据却变为了未选中,数据没有保存下来,如下图所示:
这里内表里sel字段确实是X的状态
但第二次选中后,发现内表里第一次选中的sel变为空了,也就是第一次的sel实际上并没有成功更新到内表中,令人百思不得齐姐
2、解决问题
有没有发现选中后,行选择颜色变了,因为设置了这个语句:
gs_layout-box_fname = 'SEL'.
该语句的优先级高于fieldcat的选择框,导致了此现象
FORM init_fieldcat .DATA: lv_colpos TYPE lvc_s_fcat-col_pos.REFRESH gt_fieldcat.CLEAR:lv_colpos,gs_fieldcat.DEFINE m_fieldcat.lv_colpos = lv_colpos + 1.gs_fieldcat-col_pos = lv_colpos. "显示位置gs_fieldcat-fieldname = &1. "字段名gs_fieldcat-coltext = &2. "字段描述gs_fieldcat-scrtext_s = &2. "字段描述gs_fieldcat-scrtext_m = &2. "字段描述gs_fieldcat-scrtext_l = &2. "字段描述gs_fieldcat-ref_table = &3. "参考表gs_fieldcat-ref_field = &4. "参考字段gs_fieldcat-edit = &5. "可否编辑gs_fieldcat-outputlen = &6. "输出长度gs_fieldcat-no_zero = &7. "前导0gs_fieldcat-just = &8. "对齐方式 R右 C中 L左gs_fieldcat-hotspot = &9. "热点IF gs_fieldcat-fieldname = 'SEL'.gs_fieldcat-checkbox = 'X'.ENDIF.IF gs_fieldcat-fieldname = 'SEL' ORgs_fieldcat-fieldname = 'STATUS' ORgs_fieldcat-fieldname = 'MESSAGE' ORgs_fieldcat-fieldname = 'WERKS' ORgs_fieldcat-fieldname = 'MATNR' ORgs_fieldcat-fieldname = 'VERID' .gs_fieldcat-FIX_COLUMN = 'X'.ENDIF.APPEND gs_fieldcat TO gt_fieldcat.CLEAR gs_fieldcat.END-OF-DEFINITION.m_fieldcat 'SEL' '选择' '' '' 'X' '3' '' 'C' '' .
ENDFORM.
把报表layout级的选择框语句去掉即可
二、修改数据更新至内表语句
FORM user_command USING r_ucomm LIKE sy-ucommrs_selfield TYPE slis_selfield.DATA: lv_flg TYPE char01.rs_selfield-refresh = 'X'. "控制从内部表内容向ALV屏幕更新数据DATA: lr_grid TYPE REF TO cl_gui_alv_grid.IF lr_grid IS INITIAL.CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'IMPORTINGe_grid = lr_grid.ENDIF.CALL METHOD lr_grid->check_changed_data.rs_selfield-refresh = 'X'.rs_selfield-col_stable = 'X'.rs_selfield-row_stable = 'X'.CASE r_ucomm.WHEN 'BACK'.LEAVE TO SCREEN 0.WHEN 'EXIT'.LEAVE PROGRAM.WHEN 'ALL'.gs_bb-sel = 'X'.MODIFY gt_bb FROM gs_bb TRANSPORTING sel WHERE sel = ''.WHEN 'SAL'.gs_bb-sel = ''.MODIFY gt_bb FROM gs_bb TRANSPORTING sel WHERE sel = 'X'.WHEN 'POST'.PERFORM frm_send_data.ENDCASE.rs_selfield-refresh = 'X'.CALL METHOD lr_grid->refresh_table_display.
ENDFORM. "USER_COMMAND
三、change事件注册demo
1、alv REUSE_ALV_GRID_DISPLAY_LVC展示函数注册并监听修改事件
DATA: gs_setting TYPE lvc_s_glay.
DATA: gs_event type slis_alv_event,gt_events type table of slis_alv_event.FORM frm_display .gs_setting-edt_cll_cb = 'X'. "参数回调"注册CALLER_EXIT事件,在CALLER_EXIT事件中注册其他事件CLEAR: gs_event ,gt_events[].gs_event-name = 'DATA_CHANGED'. "设置注册的事件gs_event-form = 'FRM_DATA_CHANGE'. "设置响应事件的FORMAPPEND gs_event TO gt_events.CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC'EXPORTINGi_callback_program = sy-repidi_callback_pf_status_set = 'PF_STATUS_SET'i_callback_user_command = 'USER_COMMAND'it_events = gt_events[]is_layout_lvc = gs_layoutit_fieldcat_lvc = gt_fieldcati_grid_settings = gs_setting "设置参数回调,屏幕修改值,自动保存到ALV 内表
* I_DEFAULT = 'X'i_save = 'A'TABLESt_outtab = gt_alv[]EXCEPTIONSprogram_error = 1OTHERS = 2.IF sy-subrc <> 0.MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgnoWITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.ENDIF.
ENDFORM.
form frm_data_change using rr_data_changed type ref to cl_alv_changed_data_protocol.data: l_name type char20,lw_stable type lvc_s_stbl,ls_cells type lvc_s_modi.data: l_grid type ref to cl_gui_alv_grid. "用来获取最新值data l_message type char100.data:lv_change_flag(1).
*设置ALV刷新时的焦点,避免每次刷新都自动跳到第一列lw_stable-row = 0.lw_stable-col = 0.* 取当前ALV信息call function 'GET_GLOBALS_FROM_SLVC_FULLSCR'importinge_grid = l_grid.loop at rr_data_changed->mt_mod_cells into ls_cells. "读取被修改了的单元格read table gt_alv into gw_alv index ls_cells-row_id. "读取修改行号case ls_cells-fieldname.when 'SEL'.gw_alv-sel = ls_cells-value.when others.endcase.modify gt_alv from gw_alv index ls_cells-row_id .endloop.call method l_grid->refresh_table_displayexportingis_stable = lw_stable. "刷新ALVendform.
2、事件类方式注册修改change事件
(1)、事件类定义及实现
*----------------------------------------------------------------------*
* CLASS lcl_event_receiver IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_event_receiver DEFINITION.PUBLIC SECTION.DATA: ucomm TYPE sy-ucomm.METHODS handle_data_changed FOR EVENT data_changed OF cl_gui_alv_gridIMPORTING er_data_changed.METHODS handle_data_changed_finished FOR EVENT data_changed_finished OF cl_gui_alv_gridIMPORTING e_modified et_good_cells sender.PRIVATE SECTION.
ENDCLASS.
*----------------------------------------------------------------------*
* CLASS lcl_event_receiver IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_event_receiver IMPLEMENTATION.METHOD handle_data_changed. "修改前触发
* PERFORM frm_when_changed USING er_data_changed.ENDMETHOD. "handle_data_changedMETHOD handle_data_changed_finished. "修改后触发PERFORM frm_finished_changed USING e_modified et_good_cells.ENDMETHOD. "handle_data_changed_finishedENDCLASS. "lcl_event_receiver IMPLEMENTATIONDATA: event_receiver TYPE REF TO lcl_event_receiver.*& INITIALIZATION/选择屏幕前初始化 *
*&---------------------------------------------------------------------*
INITIALIZATION.
**&---屏幕初始化
(2)、事件绑定alv
*&---------------------------------------------------------------------*
*& Form FRM_DISPLAY
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* -->P_GT_DD text
*----------------------------------------------------------------------*
FORM frm_display .gs_setting-edt_cll_cb = 'X'. "参数回调"注册CALLER_EXIT事件,在CALLER_EXIT事件中注册其他事件CLEAR: gt_events,gt_events[].gt_events-name = 'CALLER_EXIT'. "设置注册的事件gt_events-form = 'FRM_EVENTS_CALLER'. "设置响应事件的FORMAPPEND gt_events.CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC'EXPORTINGi_callback_program = sy-repidi_callback_pf_status_set = 'PF_STATUS_SET'i_callback_user_command = 'USER_COMMAND'it_events = gt_events[]is_layout_lvc = gs_layoutit_fieldcat_lvc = gt_fieldcati_grid_settings = gs_setting "设置参数回调,屏幕修改值,自动保存到ALV 内表
* I_DEFAULT = 'X'i_save = 'A'TABLESt_outtab = gt_bb[]EXCEPTIONSprogram_error = 1OTHERS = 2.IF sy-subrc <> 0.MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgnoWITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form frm_events_caller
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* -->LS_DATA text
*----------------------------------------------------------------------*
FORM frm_events_caller USING ls_data TYPE slis_data_caller_exit. "ls_data形参DATA: lr_grid TYPE REF TO cl_gui_alv_grid.IF lr_grid IS INITIAL.CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'IMPORTINGe_grid = lr_grid.ENDIF."如果call ALV未设置参数回调参数I_GRID_SETTINGS,需要注册EDIT事件
* CALL METHOD go_grid->register_edit_event
* EXPORTING
* i_event_id = cl_gui_alv_grid=>mc_evt_modified.CREATE OBJECT event_receiver.SET HANDLER event_receiver->handle_data_changed FOR lr_grid.SET HANDLER event_receiver->handle_data_changed_finished FOR lr_grid.ENDFORM. "frm_events_caller
(3)、触发事件业务逻辑实现form块
*&---------------------------------------------------------------------*
*& Form frm_when_changed
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* -->PR_DATA_CHANGED text
*----------------------------------------------------------------------*
FORM frm_when_changed USING pr_data_changed TYPE REF TO cl_alv_changed_data_protocol.* DATA: ls_mod_cells TYPE lvc_s_modi.
*
* DATA lt_errormsg TYPE tsmesg.
* DATA ls_errormsg LIKE LINE OF lt_errormsg.
* CLEAR:lt_errormsg[], ls_errormsg.
*
*
* IF pr_data_changed->mt_mod_cells IS NOT INITIAL.
* READ TABLE pr_data_changed->mt_mod_cells INTO ls_mod_cells INDEX 1.
* IF sy-subrc EQ 0.
* ls_errormsg-msgty = 'S'.
* ls_errormsg-arbgb = 'Z001'.
* ls_errormsg-txtnr = '001'.
* ls_errormsg-msgv1 = |行:{ ls_mod_cells-row_id }值即将被改变|.
* APPEND ls_errormsg TO lt_errormsg.
*
* IF lt_errormsg[] IS NOT INITIAL.
* CALL FUNCTION 'FB_MESSAGES_DISPLAY_POPUP'
* EXPORTING
* it_smesg = lt_errormsg[]
* EXCEPTIONS
* no_messages = 1
* popup_cancelled = 2
* OTHERS = 3.
* ENDIF.
* ENDIF.
*
* ENDIF.
ENDFORM. "frm_when_changed
*&---------------------------------------------------------------------*
*& Form frm_finished_changed
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* -->PV_MODIFIED text
* -->PT_GOOD_CELLS text
*----------------------------------------------------------------------*
FORM frm_finished_changed USING pv_modifiedpt_good_cells TYPE lvc_t_modi.DATA: ls_mod_cells TYPE lvc_s_modi.DATA: lw_stable TYPE lvc_s_stbl.*设置ALV刷新时的焦点,避免每次刷新都自动跳到第一列lw_stable-row = 0.lw_stable-col = 0.IF pt_good_cells IS NOT INITIAL.READ TABLE pt_good_cells INTO ls_mod_cells INDEX 1.IF sy-subrc EQ 0.READ TABLE gt_bb INTO gs_bb INDEX ls_mod_cells-row_id.IF sy-subrc = 0.MODIFY gt_bb FROM gs_bb TRANSPORTING sel WHERE matnr = gs_bb-matnrAND werks = gs_bb-werks.ENDIF.ENDIF.ENDIF.DATA: lr_grid TYPE REF TO cl_gui_alv_grid.IF lr_grid IS INITIAL.CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'IMPORTINGe_grid = lr_grid.ENDIF."Refresh ALV displayCALL METHOD lr_grid->refresh_table_displayEXPORTINGis_stable = lw_stable. "刷新ALVENDFORM. "frm_finished_changed