ALV 列项目自定义检索帮助
发布日期:2024/07/15
大多数时候,我们需要定义alv事件时会直接用OO ALV实现,这样定义事件比较简洁。但有时候,我们在初期用REUSE_ALV_GRID_DISPLAY_LVC简单地实现了一个ALV,但后续要求我们为alv的列项目追加检索帮助,此时我们就需要为函数添加事件。
案例:根据alv输出项目中仓库编号,有效组的值为存储类型定义检索帮助,选中存储类型后自动带出存储类型描述。
1.代码:
代码有一点点繁杂。
主要有这几个步骤:
1.0 定义事件类,类方法的定义和实现是分开的。在实现中写自定义搜索帮助的具体内容。PERFORM frm_on_f4
1.1 REUSE_ALV_GRID_DISPLAY_LVC函数中关联事件内表
it_events = gt_events "关联事件
1.2 设置gt_events
FORM frm_set_event.
1.3 将g_grid绑定已定义的alv。指定添加搜索帮助的字段。这里注意,因为lt_f4是sort表,当要添加多个字段到lt_f4时,要按照字段值顺序添加,否则会dump。为g_grid注册F4事件。
FORM frm_caller_exit.
1.4 自定义搜索帮助的内容。
FORM frm_on_f4
完整代码:
REPORT zmm_rpt_538_wu.
TABLES: sscrfields.
TYPES:BEGIN OF gs_alv,
lgnum TYPE /scwm/t331-lgnum, "仓库编号
avlgrp TYPE /scwm/t331-avlgrp, "有效组
lgtyp TYPE /scwm/t331-lgtyp, "存储类型
ltypt TYPE /scwm/t301t-ltypt, "存储类型描述
END OF gs_alv.
DATA:gs_fcat TYPE lvc_s_fcat,
gt_fcat TYPE lvc_t_fcat,
gt_events TYPE slis_t_event, " 设置ALV 的事件参数表
gs_layout TYPE lvc_s_layo,
gs_stbl TYPE lvc_s_stbl,
gt_alv TYPE TABLE OF gs_alv,
g_grid TYPE REF TO cl_gui_alv_grid.
*定义事件
CLASS lcl_event_receiver DEFINITION.
PUBLIC SECTION.
METHODS: handle_f4
FOR EVENT onf4 OF cl_gui_alv_grid
IMPORTING e_fieldname "字段名称
es_row_no "行号,注意这是个结构
er_event_data . "事件数据
ENDCLASS.
*方法实现
CLASS: lcl_event_receiver IMPLEMENTATION.
METHOD handle_f4.
DATA: ls_stable TYPE lvc_s_stbl. "定义基于稳定的刷新所需要参数。
ls_stable-row = 'X'. "行固定
ls_stable-col = 'X'. "列固定
PERFORM frm_on_f4 USING e_fieldname "字段名称
es_row_no "行号,注意这是个结构
er_event_data. "事件数据
CALL METHOD g_grid->refresh_table_display " 使用类:CL_GUI_ALV_GRID的实例的方法,稳定刷新
EXPORTING
is_stable = ls_stable.
ENDMETHOD.
ENDCLASS.
INITIALIZATION.
START-OF-SELECTION.
PERFORM frm_data_get.
PERFORM frm_data_display.
FORM frm_data_get.
SELECT lgnum,avlgrp
FROM /scwm/t331
INTO CORRESPONDING FIELDS OF TABLE @gt_alv.
ENDFORM.
FORM frm_data_display.
gs_layout-zebra = 'X'.
gs_layout-cwidth_opt = 'X'.
gs_layout-no_rowmark = 'X'.
gs_stbl-row = 'X'.
gs_stbl-col = 'X'.
gt_fcat = VALUE #( BASE gt_fcat ( fieldname = 'LGNUM' coltext = '仓库编号') ).
gt_fcat = VALUE #( BASE gt_fcat ( fieldname = 'AVLGRP' coltext = '有效组') ).
gt_fcat = VALUE #( BASE gt_fcat ( fieldname = 'LGTYP' coltext = '存储类型' edit = 'X' f4availabl = 'X') ).
gt_fcat = VALUE #( BASE gt_fcat ( fieldname = 'LTYPT' coltext = '存储类型描述' ) ).
PERFORM frm_set_event.
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC'
EXPORTING
i_callback_program = sy-repid
* i_callback_pf_status_set = 'STATUS_PF'
* i_callback_user_command = 'USER_COMMAND'
is_layout_lvc = gs_layout
it_fieldcat_lvc = gt_fcat[]
it_events = gt_events "关联事件
i_save = 'A'
TABLES
t_outtab = gt_alv.
ENDFORM.
*设置事件
FORM frm_set_event.
DATA: ls_events TYPE slis_alv_event.
ls_events-name = 'CALLER_EXIT' .
ls_events-form = 'FRM_CALLER_EXIT'.
APPEND ls_events TO gt_events.
ENDFORM.
FORM frm_caller_exit USING e_grid TYPE slis_data_caller_exit.
DATA:
lo_event_receiver TYPE REF TO lcl_event_receiver.
DATA:lt_f4 TYPE lvc_t_f4 WITH HEADER LINE.
IF g_grid IS INITIAL.
CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'
IMPORTING
e_grid = g_grid.
ENDIF.
* 设置事件-回车
CALL METHOD g_grid->register_edit_event
EXPORTING
i_event_id = cl_gui_alv_grid=>mc_evt_enter
EXCEPTIONS
error = 1
OTHERS = 2.
*指定OOALV 中F4字段
lt_f4-fieldname = 'LGTYP'. "指定字段'LGTYP'有搜索帮助
lt_f4-register = 'X'.
lt_f4-getbefore = 'X'.
lt_f4-chngeafter = 'X'.
APPEND lt_f4.
CALL METHOD g_grid->register_f4_for_fields
EXPORTING
it_f4 = lt_f4[].
**** 注册F4 搜索帮助处理方法
CREATE OBJECT lo_event_receiver.
SET HANDLER lO_event_receiver->handle_f4 FOR g_grid.
ENDFORM.
*搜索帮助内容
FORM frm_on_f4 USING iv_fieldname TYPE lvc_fname
is_row_no TYPE lvc_s_roid
io_event_data TYPE REF TO cl_alv_event_data.
DATA:
ls_modi TYPE lvc_s_modi,
lt_ret_tab TYPE STANDARD TABLE OF ddshretval.
FIELD-SYMBOLS: <itab> TYPE lvc_t_modi.
READ TABLE gt_fcat INTO DATA(ls_fieldcat)
WITH KEY fieldname = iv_fieldname.
*读取鼠标所在行
READ TABLE gt_alv INTO DATA(ls_alv) INDEX is_row_no-row_id.
CHECK sy-subrc = 0.
CASE iv_fieldname.
WHEN 'LGTYP'.
*获取可选的存储类型和存储类型描述存储到内表
SELECT a~lgnum,a~lgtyp,b~ltypt
FROM /scwm/t331 AS a
INNER JOIN /scwm/t301t AS b "#EC CI_BUFFJOIN
ON a~lgnum = b~lgnum
AND a~lgtyp = b~lgtyp
INTO TABLE @DATA(lt_lgtyp)
WHERE a~lgnum = @ls_alv-lgnum
AND a~avlgrp = @ls_alv-avlgrp
AND spras = @sy-langu.
IF sy-subrc = 0.
SORT lt_lgtyp BY lgnum lgtyp ltypt.
DELETE ADJACENT DUPLICATES FROM lt_lgtyp COMPARING lgnum lgtyp ltypt.
ELSE.
MESSAGE '未查询到存储类型' TYPE 'S' DISPLAY LIKE 'E'.
RETURN.
ENDIF.
*调用F4函数展示搜索帮助内容
CALL FUNCTION 'F4IF_INT_TABLE_VALUE_REQUEST'
EXPORTING
retfield = iv_fieldname
value_org = 'S'
window_title = ls_fieldcat-reptext
dynprofield = 'LGTYP' "Screen Field name
TABLES
value_tab = lt_lgtyp
return_tab = lt_ret_tab
EXCEPTIONS
parameter_error = 1
no_values_found = 2
OTHERS = 3.
ENDCASE.
ASSIGN io_event_data->m_data->* TO <itab>.
READ TABLE lt_ret_tab INTO DATA(ls_ret_tab) INDEX 1.
IF sy-subrc = 0.
ls_modi-row_id = is_row_no-row_id.
ls_modi-fieldname = iv_fieldname.
ls_modi-value = ls_ret_tab-fieldval.
APPEND ls_modi TO <itab>.
*根据选中的仓库类型带出仓库类型描述
IF iv_fieldname = 'LGTYP'.
READ TABLE lt_lgtyp INTO DATA(ls_lgtyp)
WITH KEY lgtyp = ls_ret_tab-fieldval.
IF sy-subrc = 0.
ls_alv-ltypt = ls_lgtyp-ltypt.
MODIFY gt_alv FROM ls_alv INDEX is_row_no-row_id TRANSPORTING ltypt.
ENDIF.
ENDIF.
ENDIF.
*Submit
CALL METHOD cl_gui_cfw=>flush.
io_event_data->m_event_handled = 'X'.
ENDFORM.
2.让我们看看最后的效果吧:
点击搜索帮助按钮后,弹出可选择内容。
选择存储类型9010后自动带出了存储类型描述
当没有合适的存储类型时,会返回错误消息“未查询到存储类型”。
实现成功!