ABAP ALV中自定义搜索帮助

一、干货:

  1. 在fieldcat-ref_table 和 fieldcat-ref_field 填入参考表和参考字段,搜索帮助就自动出来了。
  2. 想要选择屏幕添加自定义搜索帮助-转到这里
  3. ALV自定义搜索帮助。
    实例效果:
    ABAP ALV中自定义搜索帮助_第1张图片
    双击选择之后:
    ABAP ALV中自定义搜索帮助_第2张图片

自定义搜索帮助的实现方法

1.定义事件类

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 
                  et_bad_cells.
ENDCLASS.

2.实现handle_f4 方法

CLASS lcl_event_receiver IMPLEMENTATION.
  METHOD  handle_f4.

*     窗口时间参数的自定义f4检索帮助
    CASE e_fieldname.
      WHEN 'EMPLOYEE'.   "内表字段名称
        PERFORM f4_help_employee USING e_fieldname  "列名
                                       es_row_no  "行号
                                       er_event_data.
    ENDCASE.
*     设置后,alv稳定刷新
    stbl-row = 'X'." 基于行的稳定刷新
    stbl-col = 'X'." 基于列稳定刷新
    CALL METHOD g_grid->refresh_table_display
      EXPORTING
        is_stable = stbl.
  ENDMETHOD.                    "HANDLE_F4
ENDCLASS.      

"方法perform的内容
FORM f4_help_employee USING p_fieldname  TYPE lvc_fname
                            p_row_no     TYPE lvc_s_roid
                            er_event_data TYPE REF TO cl_alv_event_data.
  DATA: lt_return TYPE STANDARD TABLE OF ddshretval,
        ls_return TYPE ddshretval.
  DATA :lv_eqart TYPE eqart.

  CLEAR gs_alv.
  READ TABLE gt_alv INTO gs_alv INDEX p_row_no-row_id.

  IF p_fieldname = 'EMPLOYEE'.  "展示内表字段
    DATA:lt_VS TYPE TABLE OF ztemorg."收件人搜索帮助表
    CLEAR:lt_VS,lt_return.
    SELECT * FROM ztemorg  INTO TABLE @lt_VS ."Z开头自定义的表,也是你搜索帮助要显示的内容
    SORT lt_VS BY employee .
    CALL FUNCTION 'F4IF_INT_TABLE_VALUE_REQUEST'
      EXPORTING
*       DDIC_STRUCTURE   = ' '
        retfield         = 'EMPLOYEE'            "这个参数为帮助表中返回到ALV的字段的参数
*       PVALKEY          = ' '
        dynpprog         = sy-repid           "当前程序,不写会有问题
        dynpnr           = sy-dynnr           "当前屏幕,不写会有问题
        value_org        = 'S'                "默认为C但是此处不用S不行
        callback_program = sy-repid
      TABLES
        value_tab        = lt_VS            "F4帮助值的表
        return_tab       = lt_return
      EXCEPTIONS
        parameter_error  = 1
        no_values_found  = 2
        OTHERS           = 3.
    IF sy-subrc = 0.
****将选的值填入ALV字段中
      READ TABLE gt_alv INTO gs_alv INDEX p_row_no-row_id.
      IF sy-subrc = 0.
        READ TABLE lt_return INTO ls_return  INDEX 1.
        IF ls_return-fieldval IS NOT INITIAL.
          gs_alv-employee = ls_return-fieldval.
        ENDIF.
        CLEAR:ls_return.
        MODIFY gt_alv FROM gs_alv INDEX p_row_no-row_id
        TRANSPORTING employee.
      ENDIF.
    "X表示事件已经处理,不会去调取系统标准搜索帮助,(不填写参考字段参考表,也可以忽略这个标识)
     er_event_data->m_event_handled = 'X'.
    ENDIF.
  ENDIF.
ENDFORM.

3.注册事件

FORM fm_button USING E_grid TYPE slis_data_caller_exit.
  DATA: lv_event_receiver TYPE REF TO lcl_event_receiver,
        lt_f4             TYPE lvc_t_f4,
        ls_f4             TYPE lvc_s_f4.

  IF g_grid IS INITIAL.
    CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'
      IMPORTING
        e_grid = g_grid.
  ENDIF.

* 设置enter事件
  CALL METHOD g_grid->register_edit_event
    EXPORTING
      *       I_EVENT_ID = CL_GUI_ALV_GRID=>MC_EVT_ENTER. "回车时触发
        i_event_id = cl_gui_alv_grid=>mc_evt_modified. "单元格失去焦点触发
    EXCEPTIONS
      error      = 1
      OTHERS     = 2.

  "注册事件,设置,触发F4的搜索帮助
  CREATE OBJECT lv_event_receiver.
  SET HANDLER lv_event_receiver->handle_f4 FOR g_grid.

  ls_f4-fieldname  = 'EMPLOYEE'.   "窗口时间参数(需要定义F4帮助按钮的字段)
  ls_f4-register   = 'X'.
  ls_f4-getbefore  = 'X'.
  ls_f4-chngeafter = 'X'.
  INSERT ls_f4 INTO TABLE lt_f4.

 CALL METHOD g_grid->register_f4_for_fields
   EXPORTING
     it_f4 = lt_f4[].
ENDFORM.

4.fieldcat的配置

 ls_fieldcat-edit = 'X'.    "把这一列变为可修改
 ls_fieldcat-f4availabl = 'X'. "这个一定要打上X

5.具体实例

TYPE-POOLS: slis.
TYPE-POOLS: kcde.

*&---------------------------------------------------------------------*
*&      TABLES
*&---------------------------------------------------------------------*
TABLES: spfli,ztemorg.

*----------------------------------------------------------------------*
* GLOBAL INTERNAL TABLES DECLARATION
*----------------------------------------------------------------------*
DATA: gt_file TYPE filetable.

*----------------------------------------------------------------------*
* GLOBAL VARIANTS DECLARATION
*----------------------------------------------------------------------*
DATA: g_repid TYPE sy-repid.
DATA: gt_field TYPE slis_t_fieldcat_alv.
*定义读入EXCEL的内表

TYPES : BEGIN OF typ_alv ,
          carrid   TYPE spfli-carrid    , "
          connid   TYPE spfli-connid,
          cityfrom TYPE spfli-cityfrom,
          airpfrom TYPE spfli-airpfrom,
          employee TYPE ztemorg-employee, "人
          sel      TYPE c,
        END OF typ_alv .
DATA : gs_alv   TYPE typ_alv,
       gt_print TYPE TABLE OF typ_alv,
       gt_alv   TYPE TABLE OF typ_alv.

*创建字段宏定义
DEFINE add_field.
  ls_fieldcat-fieldname = '&1' .  "字段名称
  ls_fieldcat-ref_table = &2. "关联表格
  ls_fieldcat-ref_field = &3."参考字段
  ls_fieldcat-coltext = &4. "描述文本
  APPEND ls_fieldcat TO gt_fieldcat.
  CLEAR ls_fieldcat.
END-OF-DEFINITION.

* ALVDATA:
  gs_layout   TYPE lvc_s_layo,
  gv_repid    TYPE repid,
  gt_fieldcat TYPE lvc_t_fcat,
  ls_fieldcat TYPE lvc_S_fcat.
DATA: g_grid TYPE REF TO cl_gui_alv_grid.
DATA stbl TYPE lvc_s_stbl.
DATA:gt_event TYPE slis_t_event WITH HEADER LINE.

"定义事件
CLASS lcl_event_receiver DEFINITION.
  PUBLIC SECTION.
    "F4
    METHODS:
      handle_f4 FOR EVENT onf4 OF cl_gui_alv_grid
        IMPORTING e_fieldname   "列名
                  es_row_no     "行号
                  er_event_data
                  et_bad_cells.
ENDCLASS.

"方法实施
CLASS lcl_event_receiver IMPLEMENTATION.
  METHOD  handle_f4.

*     窗口时间参数的自定义f4检索帮助
    CASE e_fieldname.
      WHEN 'EMPLOYEE'.   "内表字段名称
        PERFORM f4_help_employee USING e_fieldname  "列名
                                       es_row_no  "行号
                                       er_event_data.
    ENDCASE.
*     设置后,alv稳定刷新
    stbl-row = 'X'." 基于行的稳定刷新
    stbl-col = 'X'." 基于列稳定刷新
    CALL METHOD g_grid->refresh_table_display
      EXPORTING
        is_stable = stbl.
  ENDMETHOD.                    "HANDLE_F4

ENDCLASS.                    "LCL_EVENT_RECEIVER IMPLEMENTATION


*--------选择条件
SELECTION-SCREEN BEGIN OF BLOCK bl01 WITH FRAME TITLE TEXT-001.

  SELECT-OPTIONS:S_carrid FOR spfli-carrid , "航线
                 s_connid FOR spfli-connid."航班
SELECTION-SCREEN END OF BLOCK bl01.


*DATA: GT_ALVDATA LIKE BDCDATA OCCURS 0 WITH HEADER LINE.
*DATA: G_LIGHTS_NAME TYPE LVC_CIFNM VALUE 'LIGHT'.
*&---------------------------------------------------------------------*
*&   EVENT AT INITIALIZATION
*&---------------------------------------------------------------------*
INITIALIZATION .

AT SELECTION-SCREEN OUTPUT .

*----------------------------------------------------------------------*
* EVENT OCCURS AFTER THE SELECTION SCREEN HAS BEEN PROCESSED
*----------------------------------------------------------------------*
START-OF-SELECTION.

  PERFORM frm_auth_check.  "权限检查
  PERFORM frm_getdata .    "获取数据  --GETTING DATA
  PERFORM frm_display_data.  "展示ALV

END-OF-SELECTION.
*&---------------------------------------------------------------------*
*& Form frm_auth_check
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM frm_auth_check .

ENDFORM.
*&---------------------------------------------------------------------*
*& Form frm_getdata
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM frm_getdata .
  SELECT *
    FROM spfli
   WHERE spfli~carrid IN @s_carrid "航线
    AND  spfli~connid IN @s_connid"航班
    INTO CORRESPONDING FIELDS OF TABLE @gt_alv.
  IF sy-subrc = 0.
    SORT gt_alv BY carrid connid.
  ENDIF.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form frm_display_data
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM frm_display_data .
  DATA : lv_html_header TYPE slis_formname  .
*定义输出模式
  CLEAR:gs_layout,gt_fieldcat.
  gs_layout-cwidth_opt         = 'X'.
  gs_layout-zebra              = 'X'.
  gs_layout-box_fname              = 'SEL'.
  gv_repid = sy-repid.
  PERFORM frm_set_fieldcat.

  gt_event-name = 'CALLER_EXIT'.
  gt_event-form = 'FM_BUTTON'.
  APPEND gt_event.

*  TRY .
  CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC'
    EXPORTING
      i_callback_program       = gv_repid
      i_callback_pf_status_set = 'FRM_PF_STATUS'   "状态
      is_layout_lvc            = gs_layout     "布局
      it_events                = gt_event[]    "事件
      it_fieldcat_lvc          = gt_fieldcat   "字段显示
      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_set_fieldcat
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM frm_set_fieldcat .
  add_field:
          carrid   'SPFLI'  'CARRID'     '航线',
          connid   'SPFLI'  'CONNID '    '航班',
          cityfrom 'SPFLI'  'CITYFROM '  '起飞城市',
          airpfrom 'SPFLI'  'AIRPFROM'   '起飞机场',
          employee ''       ''           '人物自定义帮助'.

 LOOP AT gt_fieldcat INTO ls_fieldcat.
   IF ls_fieldcat-fieldname = 'EMPLOYEE'.
     ls_fieldcat-edit = 'X'.    "把这一列变为可修改
     ls_fieldcat-f4availabl = 'X'. "字段尾部,添加搜索帮助的的小按钮
   ENDIF.
   MODIFY gt_fieldcat FROM ls_fieldcat.
   CLEAR:ls_fieldcat.
 ENDLOOP.
ENDFORM.

FORM frm_pf_status USING extab TYPE slis_t_extab.
  DATA: fcode TYPE TABLE OF sy-ucomm.
  CLEAR:fcode[].

  SET PF-STATUS 'STANDARD' EXCLUDING fcode[] ."添加状态
ENDFORM.


FORM fm_button USING E_grid TYPE slis_data_caller_exit.
  DATA: lv_event_receiver TYPE REF TO lcl_event_receiver,
        lt_f4             TYPE lvc_t_f4,
        ls_f4             TYPE lvc_s_f4.

  IF g_grid IS INITIAL.
    CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'
      IMPORTING
        e_grid = g_grid.
  ENDIF.

* 设置enter事件
  CALL METHOD g_grid->register_edit_event
    EXPORTING
      i_event_id = cl_gui_alv_grid=>mc_evt_enter
    EXCEPTIONS
      error      = 1
      OTHERS     = 2.

  "注册事件,设置,触发F4的搜索帮助
  CREATE OBJECT lv_event_receiver.
  SET HANDLER lv_event_receiver->handle_f4 FOR g_grid.

  ls_f4-fieldname  = 'EMPLOYEE'.   "窗口时间参数(需要定义F4帮助按钮的字段)
  ls_f4-register   = 'X'.
  ls_f4-getbefore  = 'X'.
  ls_f4-chngeafter = 'X'.
  INSERT ls_f4 INTO TABLE lt_f4.

 CALL METHOD g_grid->register_f4_for_fields
   EXPORTING
     it_f4 = lt_f4[].
ENDFORM.

FORM f4_help_employee USING p_fieldname  TYPE lvc_fname
                            p_row_no     TYPE lvc_s_roid
                            er_event_data TYPE REF TO cl_alv_event_data.
  DATA: lt_return TYPE STANDARD TABLE OF ddshretval,
        ls_return TYPE ddshretval.
  DATA :lv_eqart TYPE eqart.

  CLEAR gs_alv.
  READ TABLE gt_alv INTO gs_alv INDEX p_row_no-row_id.

  IF p_fieldname = 'EMPLOYEE'.  "展示内表字段
    DATA:lt_VS TYPE TABLE OF ztemorg."收件人搜索帮助表
    CLEAR:lt_VS,lt_return.
    SELECT * FROM ztemorg  INTO TABLE @lt_VS .
    SORT lt_VS BY employee .
    CALL FUNCTION 'F4IF_INT_TABLE_VALUE_REQUEST'
      EXPORTING
*       DDIC_STRUCTURE   = ' '
        retfield         = 'EMPLOYEE'            "这个参数为帮助表中返回到选择屏幕的字段的参数
*       PVALKEY          = ' '
        dynpprog         = sy-repid           "当前程序,不写会有问题
        dynpnr           = sy-dynnr           "当前屏幕,不写会有问题
       " dynprofield      = 'P_PERSON'       "选择屏幕上需要加F4帮助的字段
        value_org        = 'S'                "默认为C但是此处不用S不行
        callback_program = sy-repid
    "   callback_form    = 'CB_FORM'
      TABLES
        value_tab        = lt_VS            "F4帮助值的表
        return_tab       = lt_return
      EXCEPTIONS
        parameter_error  = 1
        no_values_found  = 2
        OTHERS           = 3.
    IF sy-subrc = 0.
****将选的值填入ALV字段中
      READ TABLE gt_alv INTO gs_alv INDEX p_row_no-row_id.
      IF sy-subrc = 0.
        READ TABLE lt_return INTO ls_return  INDEX 1.
        IF ls_return-fieldval IS NOT INITIAL.
          gs_alv-employee = ls_return-fieldval.
        ENDIF.
        CLEAR:ls_return.
        MODIFY gt_alv FROM gs_alv INDEX p_row_no-row_id
        TRANSPORTING employee.
      ENDIF.
    "X表示事件已经处理,不会去调取系统标准搜索帮助,(不填写参考字段参考表,也可以忽略这个标识)
     er_event_data->m_event_handled = 'X'.
    ENDIF.
  ENDIF.
ENDFORM.

使用注意点:
1.事件的使用是OOALV中使用的,我的是functionalv转OOALV,它的好处就是可以兼顾functionalv的便利和OOalv的事件。
2.要把里面的自定义表换成你的搜索帮助表。

参考链接: 阿胖的阿多-OOALV实现

你可能感兴趣的:(ABAP,数据库,c++,linux)