目录
一、问题展示及解决
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. "前导0
gs_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' OR
gs_fieldcat-fieldname = 'STATUS' OR
gs_fieldcat-fieldname = 'MESSAGE' OR
gs_fieldcat-fieldname = 'WERKS' OR
gs_fieldcat-fieldname = 'MATNR' OR
gs_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-ucomm
rs_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'
IMPORTING
e_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'. "设置响应事件的FORM
APPEND gs_event TO gt_events.
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC'
EXPORTING
i_callback_program = sy-repid
i_callback_pf_status_set = 'PF_STATUS_SET'
i_callback_user_command = 'USER_COMMAND'
it_events = gt_events[]
is_layout_lvc = gs_layout
it_fieldcat_lvc = gt_fieldcat
i_grid_settings = gs_setting "设置参数回调,屏幕修改值,自动保存到ALV 内表
* I_DEFAULT = 'X'
i_save = 'A'
TABLES
t_outtab = gt_alv[]
EXCEPTIONS
program_error = 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.
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'
importing
e_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_display
exporting
is_stable = lw_stable. "刷新ALV
endform.
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_grid
IMPORTING er_data_changed.
METHODS handle_data_changed_finished FOR EVENT data_changed_finished OF cl_gui_alv_grid
IMPORTING 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_changed
METHOD handle_data_changed_finished. "修改后触发
PERFORM frm_finished_changed USING e_modified et_good_cells.
ENDMETHOD. "handle_data_changed_finished
ENDCLASS. "lcl_event_receiver IMPLEMENTATION
DATA: 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'. "设置响应事件的FORM
APPEND gt_events.
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC'
EXPORTING
i_callback_program = sy-repid
i_callback_pf_status_set = 'PF_STATUS_SET'
i_callback_user_command = 'USER_COMMAND'
it_events = gt_events[]
is_layout_lvc = gs_layout
it_fieldcat_lvc = gt_fieldcat
i_grid_settings = gs_setting "设置参数回调,屏幕修改值,自动保存到ALV 内表
* I_DEFAULT = 'X'
i_save = 'A'
TABLES
t_outtab = gt_bb[]
EXCEPTIONS
program_error = 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.
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'
IMPORTING
e_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_modified
pt_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-matnr
AND 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'
IMPORTING
e_grid = lr_grid.
ENDIF.
"Refresh ALV display
CALL METHOD lr_grid->refresh_table_display
EXPORTING
is_stable = lw_stable. "刷新ALV
ENDFORM. "frm_finished_changed