ABAP ALV OO 自定义Toolbar 和Command及listmenu按钮

ALV OO 自定义Toolbar 和Command及listmenu按钮

  • 前言
    • OOALV容器
    • OOALV 工具栏
  • 1、定义OO 对象及字段
  • 2、OO ALV FIELDCAT 字段定义
  • 3、定义类
  • 4、类实现
    • 4.1 toolbar实现
    • 4.2 menu_button自定义菜单实现
    • 4.3 command 自定义命令实现
    • 4.4 单击事件
    • 4.5 数据发生变化实现
  • 5、OO ALV字段定义格式
  • 6、类中具体方法实现
  • 7、创建9001屏幕
    • 7.1 创建9001屏幕
    • 7.2 屏幕输出前
    • 7.3 9001屏幕自定义命令
  • 8、最终效果

前言

OOALV容器

主要通过CL_GUI_ALV_GRID这个类来控制alv的显示,ALV显示需要屏幕容器,容器对应类:
1、cl_gui_custom_container,默认容器alv自动占满整个容器;
2、cl_gui_docking_container,docking容器alv宽度可以直接调整;
3、cl_gui_splitter_contianer,splitter容器,可以将屏幕划分区域显示多个alv;

OOALV 工具栏

在ALV的工具条上增加一些按钮来增加我们自定义的功能,当然也可以在GUI状态中增加,2种的处理方式是不一样的.
这里通过toolbar事件来增加按钮,然后通过user_command事件来实现我们自定义的功能.
在TOOLBAR事件里,我们把自定义的按钮加到参数"e_object"的表属性"mt_toolbar"中可以了.

1、定义OO 对象及字段

*---------------------------------------------------------------------*
* 定义对象
*---------------------------------------------------------------------*
DATA: oo_field        TYPE lvc_t_fcat,                   "字段目录
      oo_layout       TYPE lvc_s_layo,                   "布局
      oo_toolbar      TYPE stb_button,
      oo_cont_on_9001 TYPE scrfname VALUE 'TOOLBAR_9001', "定义子屏幕区域
      oo_grid         TYPE REF TO cl_gui_alv_grid,
      oo_container    TYPE REF TO cl_gui_custom_container. "默认容器alv自动占满整个容器
 DATA: wa_stbl TYPE lvc_s_stbl.
wa_stbl-row = 'X'." 基于行的稳定刷新
wa_stbl-col = 'X'." 基于列稳定刷新

2、OO ALV FIELDCAT 字段定义

*---------------------------------------------------------------------*
* OO ALV FIELDCAT 字段定义
*---------------------------------------------------------------------*
CLASS lcl_event_receiver DEFINITION DEFERRED.
DATA: event_receiver TYPE REF TO lcl_event_receiver.

PERFORM frm_create_fieldcat TABLES oo_field USING 'CHECK'     '选择'           'L'  'X'  ''  '' ''   'IT_9001'  0 '' 'X'.
PERFORM frm_create_fieldcat TABLES oo_field USING 'KUNNR'     '客户号'           'L'  ''  ''  '' ''   'IT_9001'  0 '' ''.
PERFORM frm_create_fieldcat TABLES oo_field USING 'NAME1'     '客户名称'         'L'  ''  ''  '' ''   'IT_9001'  0 '' ''.
PERFORM frm_create_fieldcat TABLES oo_field USING 'VBELN_VF'  '发票号'           'L'  ''  ''  '' ''   'IT_9001'  0 'X' ''.
PERFORM frm_create_fieldcat TABLES oo_field USING 'POSNR_VF'  '行项目'           'L'  ''  ''  '' ''   'IT_9001'  0 '' ''.
PERFORM frm_create_fieldcat TABLES oo_field USING 'MATNR'     '物料号'           'L'  ''  ''  '' ''   'IT_9001'  0 '' ''.
PERFORM frm_create_fieldcat TABLES oo_field USING 'ARKTX'     '物料描述'         'L'  ''  ''  '' ''   'IT_9001'  0 '' ''.
PERFORM frm_create_fieldcat TABLES oo_field USING 'FKLMG'     '发票数量'         'L'  ''  ''  '' ''   'IT_9001'  0 '' ''.
PERFORM frm_create_fieldcat TABLES oo_field USING 'KBETR'     '含税发票单价'         'L'  ''  ''  '' ''   'IT_9001'  0 '' ''.
PERFORM frm_create_fieldcat TABLES oo_field USING 'VLB_FKLMG' '可数量'       'L'  ''  ''  '' ''   'IT_9001'  0 '' ''.
PERFORM frm_create_fieldcat TABLES oo_field USING 'KPEIN'     '单位'             'L'  ''  ''  '' ''   'IT_9001'  0 '' ''.
PERFORM frm_create_fieldcat TABLES oo_field USING 'FKLMG_JS'  '总数量'         'L'  'X'  'X'  '' ''   'IT_9001'  3 '' ''.

PERFORM frm_create_fieldcat TABLES oo_field USING 'VBELN_SO'  '销售订单'         'L'  ''  ''  '' ''   'IT_9001'  0 'X' ''.
PERFORM frm_create_fieldcat TABLES oo_field USING 'POSNR_SO'  '行项目'           'L'  ''  ''  '' ''   'IT_9001'  0 '' ''.
PERFORM frm_create_fieldcat TABLES oo_field USING 'ZREMARK'   '行备注'           'L'  'X'  'X'  '' ''   'IT_9001'  0 '' ''.

oo_layout-smalltitle = 'X'.
oo_layout-zebra = 'X'.
oo_layout-sel_mode = '1'.
oo_layout-cwidth_opt = 'X'.

3、定义类

*---------------------------------------------------------------------*
* 定义 类
*---------------------------------------------------------------------*
CLASS lcl_event_receiver DEFINITION.

  PUBLIC SECTION.

    CLASS-METHODS:
      handle_toolbar           "自定义工具栏
                    FOR EVENT toolbar OF cl_gui_alv_grid
        IMPORTING e_object e_interactive,

      handle_menu_button        "自定义菜单
                    FOR EVENT menu_button OF cl_gui_alv_grid
        IMPORTING e_object e_ucomm,

      handle_user_command       "自定义按钮
                    FOR EVENT user_command OF cl_gui_alv_grid
        IMPORTING e_ucomm,
      handle_hotspot_click1     "单击事件
                    FOR EVENT hotspot_click OF cl_gui_alv_grid
        IMPORTING e_row_id e_column_id,
      handle_data_changed       "数据改变触发
                    FOR EVENT data_changed OF cl_gui_alv_grid
        IMPORTING er_data_changed.


  PRIVATE SECTION.

ENDCLASS.

4、类实现

4.1 toolbar实现

4.2 menu_button自定义菜单实现

4.3 command 自定义命令实现

4.4 单击事件

4.5 数据发生变化实现

*---------------------------------------------------------------------*
* 实现类
*---------------------------------------------------------------------*
CLASS lcl_event_receiver IMPLEMENTATION.

  METHOD handle_toolbar.
    DATA: ls_toolbar  TYPE stb_button.

    MOVE '' TO ls_toolbar-function.
    MOVE '' TO ls_toolbar-icon.
    MOVE '3' TO ls_toolbar-butn_type.
    APPEND ls_toolbar TO e_object->mt_toolbar.

    CLEAR ls_toolbar.
    MOVE 'SELA' TO ls_toolbar-function.
    MOVE icon_select_all TO ls_toolbar-icon.
    MOVE '全选' TO ls_toolbar-quickinfo.
    MOVE ''(112) TO ls_toolbar-text.
    APPEND ls_toolbar TO e_object->mt_toolbar.

    CLEAR ls_toolbar.
    MOVE 'DSEL' TO ls_toolbar-function.
    MOVE icon_deselect_all TO ls_toolbar-icon.
    MOVE '取消全选' TO ls_toolbar-quickinfo.
    MOVE ''(112) TO ls_toolbar-text.
    APPEND ls_toolbar TO e_object->mt_toolbar.
    CLEAR ls_toolbar.

    MOVE 'B_LIST' TO ls_toolbar-function.
    MOVE 1 TO ls_toolbar-butn_type.
    MOVE icon_calculation TO ls_toolbar-icon.
    MOVE '自定义下拉菜单按钮'(202) TO ls_toolbar-quickinfo.
    MOVE '下拉菜单按钮' TO ls_toolbar-text.
    "MOVE '' TO ls_toolbar-disabled.
    APPEND ls_toolbar TO e_object->mt_toolbar.

  ENDMETHOD.                    "handle_toolbar
*--------------------------------------------------------------------
  METHOD handle_menu_button .  "自定义菜单实现方法
    IF e_ucomm = 'B_LIST'."给下拉菜单按钮增加选项,可以多次调用该方法以增加多行
      CALL METHOD e_object->add_function
        EXPORTING
          icon  = ICON_OKAY
          fcode = 'B_SUM' "字菜单按钮的FunCode
          text  = '显示ALV总行数'.
      CALL METHOD e_object->add_function
        EXPORTING
          icon  = ICON_CANCEL
          fcode = 'C_SUM' "字菜单按钮的FunCode
          text  = '测试'.
    ENDIF.

  ENDMETHOD.                    "handle_menu_button
*---------------------------------------------------------------------
  METHOD handle_user_command.  "自定义按钮实现方法
    DATA: sum TYPE i .
    CASE e_ucomm.
      WHEN 'SELA'.
        LOOP AT it_9001 INTO wa_9001.
          wa_9001-check = 'X'.
          MODIFY it_9001 INDEX sy-tabix FROM wa_9001 TRANSPORTING check.
        ENDLOOP.
        CALL METHOD oo_grid->refresh_table_display"这句话一定要写,否则界面没刷新,不生效
          EXPORTING
            is_stable = wa_stbl.
      WHEN 'DSEL'.
        LOOP AT it_9001 INTO wa_9001.
          wa_9001-check = ''.
          MODIFY it_9001 INDEX sy-tabix FROM wa_9001 TRANSPORTING check.
        ENDLOOP.
        CALL METHOD oo_grid->refresh_table_display
          EXPORTING
            is_stable = wa_stbl.
      WHEN 'B_SUM'.
        DESCRIBE TABLE it_9001[] LINES sum.
        MESSAGE i001(00) WITH '当前ALV表格中的数据总行数为:' sum.

       WHEN 'C_SUM'.

        MESSAGE i001(00) WITH '测试为:' sum.

    ENDCASE.

  ENDMETHOD.

  METHOD handle_data_changed.  "数据变化实现方法
    PERFORM handle_data_changed USING er_data_changed.
  ENDMETHOD.

  METHOD handle_hotspot_click1. "单击事件实现方法
    READ TABLE it_9001 INTO wa_9001 INDEX e_row_id-index.
    CASE e_column_id-fieldname.
      WHEN 'VBELN_VF'.
        SET PARAMETER ID 'VF' FIELD wa_9001-vbeln_vf.
        CALL TRANSACTION 'VF03' AND SKIP FIRST SCREEN.
      WHEN 'VBELN_SO'.
        SET PARAMETER ID 'AUN' FIELD wa_9001-vbeln_so.
        CALL TRANSACTION 'VA03' AND SKIP FIRST SCREEN.
    ENDCASE.
  ENDMETHOD.                  "HANDLE_HOTSPOT_CLICK1

ENDCLASS.

5、OO ALV字段定义格式

*---------------------------------------------------------------------*
* FRM_CREATE_FIELDCAT
* 9001 ALV 定义
*---------------------------------------------------------------------*
FORM frm_create_fieldcat TABLES t_fcat TYPE lvc_t_fcat
                          USING  u_fieldname TYPE lvc_fname
                                 u_scrtext   TYPE any
                                 u_just      TYPE lvc_just
                                 u_edit      TYPE lvc_edit
                                 u_no_zero   TYPE lvc_nozero
                                 u_dosum     TYPE lvc_dosum
                                 u_outputlen TYPE any
                                 u_table     TYPE string
                                 u_decimals  TYPE decimals
                                 u_hotspot   TYPE lvc_hotspt
                                 u_checkbox   TYPE lvc_checkb
                                 .

  DATA:lwa_fcat   TYPE lvc_s_fcat.

  lwa_fcat-fieldname   = u_fieldname.
  lwa_fcat-scrtext_s   = u_scrtext.
  lwa_fcat-just        = u_just.
  lwa_fcat-edit        = u_edit.
  lwa_fcat-no_zero      = u_no_zero.
  lwa_fcat-do_sum      = u_dosum.
  lwa_fcat-outputlen   = u_outputlen.
  lwa_fcat-tabname       =  u_table.
  lwa_fcat-decimals      = u_decimals.
  lwa_fcat-hotspot      = u_hotspot.
  lwa_fcat-checkbox      = u_checkbox.
  APPEND lwa_fcat TO t_fcat.
  CLEAR lwa_fcat.

ENDFORM.

6、类中具体方法实现

按理说,实现类中方法,应该统一调用函数PERFORM来实现,这样程序维护起来很容易。前面类实现中,部分方法已经实现,这里是数据发生变化方法的实现。具体业务场景根据自己需要更改代码

*---------------------------------------------------------------------*
* 处理数据的函数
* 当界面的数据发生变化
*---------------------------------------------------------------------*
FORM handle_data_changed USING data_changed TYPE REF TO cl_alv_changed_data_protocol.

  DATA: x_change TYPE lvc_s_modi.

  LOOP AT data_changed->mt_good_cells INTO x_change.

    "结算数量发生变化
    IF x_change-fieldname  = 'FKLMG_JS'.

      READ TABLE it_9001 INTO wa_9001 INDEX x_change-row_id.

      wa_9001-fklmg_js = x_change-value.
      wa_9001-kbetr_tmp = wa_9001-kbetr_js * wa_9001-fklmg_js / wa_9001-kpein / '1.13'.

      MODIFY it_9001 FROM wa_9001 INDEX x_change-row_id.

    ENDIF.

    "行备注内容发生变化
    IF x_change-fieldname  = 'ZREMARK'.

      READ TABLE it_9001 INTO wa_9001 INDEX x_change-row_id.

      wa_9001-zremark = x_change-value.

      MODIFY it_9001 FROM wa_9001 INDEX x_change-row_id.

    ENDIF.

    CALL METHOD oo_grid->refresh_table_display
      EXCEPTIONS
        finished = 1
        OTHERS   = 2.

  ENDLOOP.

ENDFORM.

7、创建9001屏幕

这里我创建屏幕是9001,当然你可以是100,1001。

7.1 创建9001屏幕

"调用9001屏幕前,需要把显示的数据拼接好,这里就不演示了
CALL SCREEN 9001.
"这里是9001屏幕
PROCESS BEFORE OUTPUT.

  MODULE STATUS_9001.

PROCESS AFTER INPUT.

  MODULE USER_COMMAND_9001.

ABAP ALV OO 自定义Toolbar 和Command及listmenu按钮_第1张图片
ABAP ALV OO 自定义Toolbar 和Command及listmenu按钮_第2张图片

7.2 屏幕输出前

"屏幕输出前
MODULE status_9001 OUTPUT.

  "设置GUI状态
  SET PF-STATUS '9001_PF'.
  "设置界面标题
  SET TITLEBAR '9001_BAR'.

  "控制结算单字段显示
*  IF check_js = 'X'.
*    LOOP AT SCREEN.
*      IF screen-group1 = 'ZC1'.
*        screen-input     = 0.
*        screen-output    = 1.
*        screen-active    = 1.
*        MODIFY SCREEN.
*      ENDIF.
*    ENDLOOP.
*  ENDIF.


  IF oo_container IS INITIAL.


*   建立一个容器控件作为ALV的容器
    CREATE OBJECT oo_container
      EXPORTING
        container_name = oo_cont_on_9001.

*   建立一个ALV的实例
    CREATE OBJECT oo_grid
      EXPORTING
        i_parent = oo_container.

*   显示表格
    CALL METHOD oo_grid->set_table_for_first_display
      EXPORTING
        is_layout       = oo_layout
      CHANGING
        it_outtab       = it_9001[]
        it_fieldcatalog = oo_field.

*   注册ALV的事件
    CREATE OBJECT event_receiver.

    SET HANDLER event_receiver->handle_toolbar FOR oo_grid.       "注册工具栏
    SET HANDLER event_receiver->handle_menu_button FOR oo_grid.   "注册工具栏菜单
    SET HANDLER event_receiver->handle_user_command FOR oo_grid.  "注册用户自定义命令
    SET HANDLER event_receiver->handle_data_changed FOR oo_grid."单元格数据更改时触发
    SET HANDLER event_receiver->handle_hotspot_click1 FOR oo_grid."单击事件



    "调用此方法才能激活工具栏上增加的自定义按钮
    CALL METHOD oo_grid->set_toolbar_interactive.

    CALL METHOD oo_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. "单元格更改触发

  ENDIF.

  CALL METHOD oo_grid->refresh_table_display.


ENDMODULE.

7.3 9001屏幕自定义命令

MODULE user_command_9001 INPUT.

  DATA: tmp_code LIKE sy-ucomm.
  DATA wl_answer TYPE char01.

  tmp_code = ok_code.

  CLEAR: ok_code.

  CASE tmp_code.

    WHEN 'EXIT'.
      LEAVE TO SCREEN 0.
    WHEN 'BACK'.
      LEAVE TO SCREEN 0.
    WHEN 'BTN_CREAT'.

      CALL METHOD cl_gui_cfw=>flush.

      CALL FUNCTION 'POPUP_TO_CONFIRM'
        EXPORTING
          text_question         = '是否保存单据!!'
          icon_button_1         = '是'
          icon_button_2         = '否'
          default_button        = '2'
          display_cancel_button = 'X'
          start_column          = 25
          start_row             = 6
        IMPORTING
          answer                = wl_answer
        EXCEPTIONS
          text_not_found        = 1
          OTHERS                = 2.
      IF wl_answer = '1'.

        "结算单界面数据的校验
*        PERFORM data_chaeck.
*
*        IF check_flag = 'Y'.
*          "结算单按钮
*          PERFORM command_btn_creat.
*          "刷新界面
*          CALL METHOD oo_grid->refresh_table_display.
*        ELSE.
*
*          MESSAGE check_msg TYPE 'S' DISPLAY LIKE 'E'.
*
*        ENDIF.
      ENDIF.

      "打印
    WHEN 'PRINT'.
      "PERFORM check_print.

      "作废
    WHEN 'BTN_DEL'.

      CALL METHOD cl_gui_cfw=>flush.

      CALL FUNCTION 'POPUP_TO_CONFIRM'
        EXPORTING
          text_question         = '是否作废结算单!!'
          icon_button_1         = '是'
          icon_button_2         = '否'
          default_button        = '2'
          display_cancel_button = 'X'
          start_column          = 25
          start_row             = 6
        IMPORTING
          answer                = wl_answer
        EXCEPTIONS
          text_not_found        = 1
          OTHERS                = 2.
      IF wl_answer = '1'.

        "结算单界面数据的校验
*        PERFORM check_jsdata.
*
*        IF check_flag = 'Y'.
*          "作废按钮
*          PERFORM command_btn_del.
*
*        ELSE.
*
*          MESSAGE check_msg TYPE 'S' DISPLAY LIKE 'E'.
*
*        ENDIF.
        "刷新界面
        CALL METHOD oo_grid->refresh_table_display.
      ENDIF.
    WHEN OTHERS.

  ENDCASE.

  CLEAR ok_code.

ENDMODULE.

8、最终效果

查询界面
ABAP ALV OO 自定义Toolbar 和Command及listmenu按钮_第3张图片
1000屏幕界面
ABAP ALV OO 自定义Toolbar 和Command及listmenu按钮_第4张图片
OO ALV 界面
ABAP ALV OO 自定义Toolbar 和Command及listmenu按钮_第5张图片
ABAP ALV OO 自定义Toolbar 和Command及listmenu按钮_第6张图片
ABAP ALV OO 自定义Toolbar 和Command及listmenu按钮_第7张图片

你可能感兴趣的:(ABAP,sap,abap)