ABAP Control Framework(4): ALV List

4.ALV Grid

          通过cl_gui_alv_grid类显示ALV List。

示例:

"cl_gui_alv_grid事件
CLASS c3_event_handler DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS:m_onf1 FOR EVENT onf1 OF cl_gui_alv_grid
       IMPORTING e_fieldname es_row_no er_event_data.
    CLASS-METHODS:m_onf4 FOR EVENT onf4 OF cl_gui_alv_grid
       IMPORTING e_fieldname es_row_no er_event_data.
    "生成toolbar
    CLASS-METHODS:m_toolbar FOR EVENT toolbar OF cl_gui_alv_grid
       IMPORTING e_object e_interactive.
    "生成menu
    CLASS-METHODS:m_menu_button FOR EVENT menu_button OF cl_gui_alv_grid
       IMPORTING e_object e_ucomm.
    "before user command
    CLASS-METHODS:m_before_user_command FOR EVENT before_user_command OF cl_gui_alv_grid
       IMPORTING e_ucomm.
    "user command
    CLASS-METHODS:m_user_command FOR EVENT user_command OF cl_gui_alv_grid
       IMPORTING e_ucomm.
    "右键menu
    CLASS-METHODS:m_context_menu_request FOR EVENT context_menu_request OF cl_gui_alv_grid
       IMPORTING e_object.
ENDCLASS.
CLASS c3_event_handler IMPLEMENTATION.
  METHOD m_onf1.
    DATA:lv_mes TYPE string.
    lv_mes = e_fieldname && '--' && es_row_no-row_id.
    MESSAGE lv_mes TYPE 'I'.
  ENDMETHOD.
  METHOD m_onf4.
    DATA:lv_mes TYPE string.
    lv_mes = e_fieldname && '--' && es_row_no-row_id.
    MESSAGE lv_mes TYPE 'I'.
  ENDMETHOD.
  METHOD m_before_user_command.
    DATA:lv_mes TYPE string.
    lv_mes = 'before function:' && e_ucomm.
    MESSAGE lv_mes TYPE 'I'.
  ENDMETHOD.
  METHOD m_toolbar.
    DATA:lv_mes TYPE string.
    DATA:ls_toolbar  TYPE stb_button.
    "按钮类型:0button;
    "1:menu and default button;
    "2menu;
    "3separator;
    "4radio button;5checkbox
    "添加间隔线
    ls_toolbar-butn_type = 3.
    APPEND ls_toolbar TO e_object->mt_toolbar.
    "添加button
    ls_toolbar-function = 'FUN1'.
    ls_toolbar-icon = icon_employee.
    ls_toolbar-quickinfo = 'funcion 1'.
    ls_toolbar-text = '自定义function'.
    ls_toolbar-butn_type = 0.
    APPEND ls_toolbar TO e_object->mt_toolbar.
    "添加menu
    ls_toolbar-function = 'MENU1'.
    ls_toolbar-icon = icon_employee.
    ls_toolbar-quickinfo = 'Menu 1'.
    ls_toolbar-text = '自定义menu1'.
    ls_toolbar-butn_type = 2.
    APPEND ls_toolbar TO e_object->mt_toolbar.
    ls_toolbar-function = 'MENU2'.
    ls_toolbar-icon = icon_employee.
    ls_toolbar-quickinfo = 'Menu default button'.
    ls_toolbar-text = '自定义menu2'.
    ls_toolbar-butn_type = 1.
    APPEND ls_toolbar TO e_object->mt_toolbar.
  ENDMETHOD.
  METHOD m_menu_button.
    IF e_ucomm = 'MENU1'.
      e_object->add_function( EXPORTING fcode = 'MFUNC1' text = 'menu1 func1' ).
      e_object->add_function( EXPORTING fcode = 'MFUNC2' text = 'menu1 func2' ).
    ELSEIF e_ucomm = 'MENU2'.
      e_object->add_function( EXPORTING fcode = 'MFUNC3' text = 'menu1 func3' ).
      e_object->add_function( EXPORTING fcode = 'MFUNC4' text = 'menu1 func4' ).
    ENDIF.
  ENDMETHOD.
  METHOD m_user_command.
    DATA:lv_mes TYPE string.
    lv_mes = 'function:' && e_ucomm.
    MESSAGE lv_mes TYPE 'I'.
  ENDMETHOD.
  METHOD m_context_menu_request.
    DATA:lt_std_fcodes type ui_functions.
    DATA:lt_own_fcodes type ui_functions.
    APPEND 'CFUNC1' TO lt_own_fcodes.
    APPEND 'CFUNC2' TO lt_own_fcodes.
    APPEND cl_gui_alv_grid=>mc_fc_detail TO lt_std_fcodes.
    APPEND cl_gui_alv_grid=>mc_fc_find TO lt_std_fcodes.
    e_object->add_function( EXPORTING fcode = 'CFUNC1' text = 'context func1').
    e_object->add_function( EXPORTING fcode = 'CFUNC2' text = 'context func2').
    "隐藏右键菜单function
    e_object->hide_functions( fcodes = lt_std_fcodes ).
    "反灰右键菜单function
    "e_object->disable_functions( fcodes = lt_std_fcodes ).
    "将隐藏菜单function显示
    "e_object->show_functions( fcodes = lt_std_fcodes ).
    "将反灰菜单function恢复
    "e_object->enable_functions( fcodes = lt_std_fcodes ).
  ENDMETHOD.
ENDCLASS.
"cl_gui_alv_grid
CLASS c3 DEFINITION.
  PUBLIC SECTION.
    TYPES:BEGIN OF s_out.
      INCLUDE TYPE spfli.
      TYPES: sel TYPE C LENGTH 1. "行选择控制字段
      TYPES: handle_dd  TYPE lvc_s_drop-handle. "下拉控制字段
      TYPES: t_style TYPE lvc_t_styl.  "控制单元格编辑字段
      TYPES: lights TYPE C LENGTH 1. "display exception
      TYPES: line_color TYPE C LENGTH 4. "行颜色控制
      TYPES: t_scol TYPE lvc_t_scol. "单元格颜色控制
      TYPES: t_styl TYPE lvc_t_styl. "button样式
      TYPES: link TYPE C LENGTH 4. "链接字段
      TYPES: date TYPE D. "日期字段,edit mask
    TYPES:END OF s_out.
    "
    DATA:lt_out TYPE TABLE OF s_out.
    DATA:ls_out LIKE LINE OF lt_out.
    "字段
    DATA:lt_fcat TYPE lvc_t_fcat.
    DATA:ls_fcat TYPE lvc_s_fcat.
    "layout
    DATA:ls_layout TYPE lvc_s_layo.
    "exclude function
    DATA:lt_exclude TYPE ui_functions.
    DATA:ls_exclude TYPE ui_func.
    "link
    DATA:lt_link TYPE lvc_t_hype.
    DATA:ls_link TYPE lvc_s_hype.
    "group
    DATA:lt_group TYPE lvc_t_sgrp.
    DATA:ls_group TYPE lvc_s_sgrp.
    "sort
    DATA:lt_sort TYPE lvc_t_sort.
    DATA:ls_sort TYPE lvc_s_sort.
    DATA:lo_alv TYPE REF TO cl_gui_alv_grid.
    METHODS:m_alv_init.
    METHODS:m_alv_show.
  PRIVATE SECTION.
    METHODS:m_get_data.
    METHODS:m_build_fieldcat.
    METHODS:m_build_layout.
    METHODS:m_set_drop_down.
    METHODS:m_set_cell_edit.
    METHODS:m_set_events.
    METHODS:m_set_no_toolbar.
    METHODS:m_set_hyperlink.
    METHODS:m_set_group.
    METHODS:m_set_sort.
ENDCLASS.
CLASS c3 IMPLEMENTATION.
  METHOD m_alv_init.
    IF lo_alv IS INITIAL.
      CREATE OBJECT lo_alv
        EXPORTING i_parent = cl_gui_container=>default_screen.
    ENDIF.
    "获取并设置数据
    me->m_get_data( ).
    "设置fieldcat
    me->m_build_fieldcat( ).
    "设置layout
    me->m_build_layout( ).
    "设置drop down
    me->m_set_drop_down( ).
    "设置单元格编辑
    me->m_set_cell_edit( ).
    "设置事件
    me->m_set_events( ).
    "设置隐藏toolbar上function
    me->m_set_no_toolbar( ).
    "设置超链接
    me->m_set_hyperlink( ).
    "设置分组
    me->m_set_group( ).
    "设置排序
    me->m_set_sort( ).
  ENDMETHOD.
  METHOD m_alv_show.
    "显示alv
    lo_alv->set_table_for_first_display(
      EXPORTING
            "layout
            is_layout             = ls_layout
            "exclude toolbar
            it_toolbar_excluding  = lt_exclude
            "超链接
            it_hyperlink = lt_link
            "分组
            it_special_groups = lt_group
      CHANGING
            it_fieldcatalog       = lt_fcat
            it_outtab             = lt_out
            "排序
            it_sort = lt_sort ).
  ENDMETHOD.
  "获取设置数据
  METHOD m_get_data.
    DATA:lv_index TYPE I.
    DATA:lt_scol TYPE lvc_t_scol.
    DATA:ls_scol TYPE lvc_s_scol.
    DATA:lt_styl TYPE lvc_t_styl.
    DATA:ls_styl TYPE lvc_s_styl.
    "获取数据
    SELECT * FROM spfli INTO CORRESPONDING FIELDS OF TABLE lt_out.

    LOOP AT lt_out INTO ls_out.
      "设置exception域值
      lv_index = sy-tabix MOD 3 + 1.
      ls_out-lights = lv_index.

      "设置行颜色值
      "第一位固定C,第二为主色调,第二位次色调,第三位:0字体色,1背景颜色
      "0 | COL_BACKGROUND } 0 GUI-dependent
      "1 | COL_HEADING } 1 Gray-blue
      "2 | COL_NORMAL } 2 Light gray
      "3 | COL_TOTAL } 3 Yellow
      "4 | COL_KEY } 4 Blue-green
      "5 | COL_POSITIVE } 5 Green
      "6 | COL_NEGATIVE } 6 Red
      "7 | COL_GROUP } 7 Purple
      IF sy-tabix = 3.
        ls_out-line_color = 'C310'.
      ENDIF.

      "设置单元格颜色值
      IF sy-tabix = 4.
        ls_scol-fname = 'CONNID'.
        ls_scol-color-col = '5'.
        APPEND ls_scol TO lt_scol.
        ls_out-t_scol = lt_scol.
      ENDIF.

      "设置日期
      ls_out-date = sy-datum + sy-tabix.

      MODIFY lt_out FROM ls_out TRANSPORTING lights line_color t_scol date.
    ENDLOOP.
  ENDMETHOD.
  "设置fieldcat
  "修改field catalog after output
  "GET_FRONTEND_FIELDCATALOG
  "SET_FRONTEND_FIELDCATALOG
  "function:LVC_FIELDCATALOG_MERGE
  "获取field catalog
  "当只是显示数据库表,没有其他字段
  "set_table_for_first_display指定I_STRUCTURE_NAME,表名;
  METHOD m_build_fieldcat.
    DATA:lv_index TYPE I.
    "获取fieldcatalog
    CALL FUNCTION 'LVC_FIELDCATALOG_MERGE'
      EXPORTING
        i_structure_name       = 'SPFLI'
      CHANGING
        ct_fieldcat            = lt_fcat
      EXCEPTIONS
        inconsistent_interface = 1
        program_error          = 2
        OTHERS                 = 3.
    IF sy-subrc <> 0.
      LEAVE PROGRAM.
    ENDIF.

    "fieldcatalog字段
    "col_id 列id,在get_selected_cells_id,set_selected_cells_id使用;
    "fieldname 字段名;
    "ref_table DDIC table;
    "ref_field DDIC field;
    "colddictxt space,'L':SCRTEXT_L,'M':SCRTEXT_M,,'S':SCRTEXT_S,'R':REPTEXT
    "selddictxt reference字段描述作为layout选择行列描述,space,L,M,S,R;
    "tipddictxt 提示tip,space,L,M,S,R;
    "coltext 列标题,当没有reference字段时必须设置;
    "seltext layout中选择列时的列描述;
    "tooltip 设置提示;
    "reptext 当有reference字段,字段描述;
    "scrtext_l 长描述;
    "scrtext_m 中长描述;
    "scrtext_s 短描述;
    "cfieldname reference currency字段;
    "currency 金额单位;
    "qfieldname reference quantity字段;
    "quantity 数量单位;
    "checkbox 是否CHECKBOX显示;
    "col_pos 列位置;
    "do_sum 是否合计;
    "emphasize 是否强调标记
    " SPACE, 'X':颜色值, or 'Cxyz' (x:'1'-'9' color number,
    " y(intensified),z(inverse): '0'=off '1'=on);
    "hotspot 是否热点;
    "href_hndl 超链接,set_table_for_first_display参数:it_hyperlink设置链接;
    "key 是否key字段,设置fixed或隐藏;
    "lowercase 是否小写;
    "no_out 是否显示,layout可以显示;
    "no_merging 是否合并;
    "no_sum 是否合计;
    "outputlen 列宽;
    "style 列样式,按钮CL_GUI_ALV_GRID=> MC_STYLE_BUTTON;
    "tech 是否tech字段,不会显示在layout;
    "web_field 超链接cell级别设置字段
    "decimals_o 小数位数
    "decmfield 逐行指定字段设置小数位数
    "edit_mask 格式转换,示例日期:__/__/____
    "exponent 数据类型为f,指定指数;
    "icon 是否显示icon;
    "just R:靠右,L:靠左,C:居中;
    "lzero 是否前置0;
    "no_sign 是否正负号;
    "no_zero 是否显示0;
    "round 十进制P类型值输出;
    "roundfield 逐行指定字段设置round;
    "symbol 显示symbol;
    "dd_outlen 设置eidt_mask,输出长度;
    "intlen 设置edit_mask,内部长度;
    "inttype ABAP类型,当没有reference必须设置;
    "rollname 设置f1帮助reference ddic字段;
    "dragdropid 设置drag drop;
    "reprep 是否打开report interface,method:activate_reprep_interface;
    "sp_group 分组;
    "txt_field subtotal字段描述;
    LOOP AT lt_fcat INTO ls_fcat.
      lv_index = sy-tabix.
      ls_fcat-col_pos = lv_index.
      ls_fcat-tabname = 'SPFLI'.
      "设置下拉
      IF ls_fcat-fieldname = 'CARRID'.
        ls_fcat-drdn_hndl = '1'.
        "输出长度
        ls_fcat-outputlen = 5.
        "不检查foreign key
        ls_fcat-checktable = '!'.
        "单列编辑控制
        ls_fcat-edit = 'X'.
      ENDIF.
      IF ls_fcat-fieldname = 'CITYFROM'.
        ls_fcat-drdn_hndl = '2'.
        "输出长度
        ls_fcat-outputlen = 10.
        "单列编辑控制
        ls_fcat-edit = 'X'.
      ENDIF.
      "直接设置下拉字段
      IF ls_fcat-fieldname = 'FLTYPE'.
        ls_fcat-drdn_field = 'HANDLE_DD'.
        "单列编辑控制
        ls_fcat-edit = 'X'.
      ENDIF.

      "设置f4可用
      IF ls_fcat-fieldname = 'AIRPFROM'.
        ls_fcat-f4availabl = 'X'.
      ENDIF.

      "设置所属分组
      ls_fcat-sp_group = '1'.

      MODIFY lt_fcat FROM ls_fcat.
    ENDLOOP.

    "添加sel选择列
    lv_index = lv_index + 1.
    CLEAR ls_fcat.
    ls_fcat-col_pos = lv_index.
    ls_fcat-fieldname = 'SEL'.
    ls_fcat-checkbox = 'X'."显示为checkbox
    ls_fcat-edit = 'X'.
    APPEND ls_fcat TO lt_fcat.

    "添加exception显示列
    lv_index = lv_index + 1.
    CLEAR ls_fcat.
    ls_fcat-col_pos = lv_index.
    ls_fcat-fieldname = 'LIGHTS'.
    APPEND ls_fcat TO lt_fcat.

    "添加链接列
    lv_index = lv_index + 1.
    CLEAR ls_fcat.
    ls_fcat-col_pos = lv_index.
    ls_fcat-fieldname = 'LINK'.
    ls_fcat-href_hndl = '1'.
    APPEND ls_fcat TO lt_fcat.

    "添加日期列
    lv_index = lv_index + 1.
    CLEAR ls_fcat.
    "字段有DDIC reference会自动edit mask
    "无DDIC,需要指定inlen,dd_outlen,edit_mask
    ls_fcat-col_pos = lv_index.
    ls_fcat-fieldname = 'DATE'.
    ls_fcat-intlen = 8.
    ls_fcat-dd_outlen = 10.
    ls_fcat-edit_mask = '__/__/____'.
    APPEND ls_fcat TO lt_fcat.
  ENDMETHOD.
  "设置layout
  METHOD m_build_layout.
    "color设置
    "ls_layout-zebra = 'X'. "是否斑马线显示
    ls_layout-ctab_fname = 'T_SCOL'. "单元格颜色控制字段
    ls_layout-info_fname = 'LINE_COLOR'. "行颜色控制字段
    "编辑设置
    ls_layout-edit = ''. "是否可编辑,整体控制
    ls_layout-edit_mode = ''. "编辑模式
    ls_layout-stylefname = 'T_STYLE'. "单元格编辑控制字段,显示button
    "显示设置
    ls_layout-cwidth_opt = ''. "是否自动列宽
    ls_layout-smalltitle = ''. "是否small title
    ls_layout-grid_title = ''.  "toolbar和alv之间title
    ls_layout-no_headers = ''. "是否显示列头
    ls_layout-no_hgridln = ''. "是否显示水平线
    ls_layout-no_vgridln = ''. "是否显示竖线
    ls_layout-no_keyfix = ''. "是否关键词固定
    ls_layout-no_merging = ''. "是否禁止单元格合并
    ls_layout-no_rowmark = ''. "是否禁止行选择
    ls_layout-no_toolbar = ''. "是否隐藏toolbar.
    "total设置
    ls_layout-no_totarr = ''. "是否total行箭头指示
    ls_layout-no_totexp = ''. "是否total行显示icon
    ls_layout-no_totline = ''. "是否显示汇总行
    ls_layout-numc_total = ''. "是否numc字段汇总
    ls_layout-totals_bef = ''. "汇总行显示首行
    "DETAILINIT
    ls_layout-detailinit = ''. "是否detail页显示初始值
    ls_layout-detailtitl = ''. "detail title
    "ls_layout-s_dragdrop = ''. "structure of drag drop
    ls_layout-keyhot = ''.  "是否key hotspot
    ls_layout-sgl_clk_hd = ''. "是否single click on header生效
    "选择模式,默认单选,A:行,列选择;B:单行选择;C:多行选择;D:单元格选择
    ls_layout-sel_mode = ''.
    ls_layout-box_fname = 'SEL'. "行选择标志字段
    "exceptions设置,1:yellow;2:green;3:red
    ls_layout-excp_fname = 'LIGHTS'. "exceptions字段
    ls_layout-excp_led = 'X'.  "是否LED显示
    ls_layout-excp_conds = 'X'. "是否total,subtotal显示exception
    ls_layout-excp_rolln = 'LIGHTS'. "exception,F1帮助文本
  ENDMETHOD.
  "设置下拉选择
  METHOD m_set_drop_down.
    DATA:lt_dropdown TYPE lvc_t_drop.
    DATA:ls_dropdown TYPE lvc_s_drop.

    ls_dropdown-handle = '1'.
    ls_dropdown-value = 'AZ'.
    APPEND ls_dropdown TO lt_dropdown.
    ls_dropdown-handle = '1'.
    ls_dropdown-value = 'ZZ'.
    APPEND ls_dropdown TO lt_dropdown.
    ls_dropdown-handle = '2'.
    ls_dropdown-value = 'xian'.
    APPEND ls_dropdown TO lt_dropdown.
    ls_dropdown-handle = '2'.
    ls_dropdown-value = 'beijing'.
    APPEND ls_dropdown TO lt_dropdown.

    LOOP AT lt_out INTO ls_out.
      "指定某个单元格下拉
      IF sy-tabix = 1.
        ls_out-handle_dd = 1.
        MODIFY lt_out FROM ls_out TRANSPORTING handle_dd.
      ENDIF.
      IF sy-tabix = 2.
        ls_out-handle_dd = 2.
        MODIFY lt_out FROM ls_out TRANSPORTING handle_dd.
      ENDIF.
    ENDLOOP.
    "设置下拉table
    lo_alv->set_drop_down_table(
      EXPORTING
        it_drop_down = lt_dropdown ).
  ENDMETHOD.
  "设置单元格编辑
  METHOD m_set_cell_edit.
    DATA:lt_style TYPE lvc_t_styl.
    DATA:ls_style TYPE lvc_s_styl.
    "设置单元格是否可编辑
    ls_style-fieldname = 'COUNTRYFR'.
    ls_style-style = cl_gui_alv_grid=>mc_style_enabled. "可编辑
    INSERT ls_style INTO TABLE lt_style.
    ls_style-fieldname = 'COUNTRYTO'.
    ls_style-style = cl_gui_alv_grid=>mc_style_enabled. "可编辑
    INSERT ls_style INTO TABLE lt_style.
    "设置单元格显示按钮
    ls_style-fieldname = 'LINK'.
    ls_style-style = cl_gui_alv_grid=>mc_style_button. "按钮
    INSERT ls_style INTO TABLE lt_style.
    LOOP AT lt_out INTO ls_out.
      IF sy-tabix = 1.
        ls_out-t_style = lt_style.
        MODIFY lt_out FROM ls_out TRANSPORTING t_style.
      ENDIF.
    ENDLOOP.
  ENDMETHOD.
  "设置事件
  METHOD m_set_events.
    DATA:lt_f4 TYPE lvc_t_f4.
    DATA:ls_f4 TYPE lvc_s_f4.
    ls_f4-fieldname = 'AIRPFROM'.
    ls_f4-register = 'X'.
    ls_f4-getbefore = 'X'.
    ls_f4-chngeafter = 'X'.
    ls_f4-internal = 'X'.
    APPEND ls_f4 TO lt_f4.
    "设置f1事件响应
    SET HANDLER c3_event_handler=>m_onf1 FOR lo_alv.
    "设置f4事件响应
    lo_alv->register_f4_for_fields( it_f4 = lt_f4 ).
    SET HANDLER c3_event_handler=>m_onf4 FOR lo_alv.

    "设置change standard function
    SET HANDLER c3_event_handler=>m_before_user_command FOR lo_alv.
    "将标准function关闭
    lo_alv->set_user_command( EXPORTING i_ucomm = space ).
    "设置toolbar function
    SET HANDLER c3_event_handler=>m_toolbar FOR lo_alv.
    "设置function相应事件
    SET HANDLER c3_event_handler=>m_user_command FOR lo_alv.
    "设置右键菜单
    SET HANDLER c3_event_handler=>m_context_menu_request FOR lo_alv.
    "设置menu function
    SET HANDLER c3_event_handler=>m_menu_button FOR lo_alv.
  ENDMETHOD.
  "设置隐藏toolbar
  METHOD m_set_no_toolbar.
    "方式1:在layout设置no_toolbar
    "方式2:设置set_table_for_first_display方法
    "参数it_toolbar_excluding  = lt_exclude
    ls_exclude = cl_gui_alv_grid=>mc_fc_detail.
    APPEND ls_exclude TO lt_exclude.
  ENDMETHOD.
  "设置超链接
  METHOD m_set_hyperlink.
    ls_link-handle = '1'.
    ls_link-href = 'https://www.baidu.com/'.
    APPEND ls_link TO lt_link.
    ls_link-handle = '2'.
    ls_link-href = 'https://www.runoob.com/'.
    APPEND ls_link TO lt_link.
    "方法set_table_for_first_display
    "参数:it_hyperlink
  ENDMETHOD.
  "设置字段分组
  METHOD m_set_group.
    ls_group-sp_group = '1'.
    ls_group-text = 'group1'.
    APPEND ls_group TO lt_group.
    ls_group-sp_group = '2'.
    ls_group-text = 'group2'.
    "方法set_table_for_first_display
    "参数:it_special_groups
  ENDMETHOD.
  "设置排序
  METHOD m_set_sort.
    ls_sort-spos = 1.
    ls_sort-fieldname = 'CARRID'.
    ls_sort-up = ''.
    ls_sort-down = 'X'.
    APPEND ls_sort TO lt_sort.
    ls_sort-spos = 2.
    ls_sort-fieldname = 'CONNID'.
    ls_sort-up = 'X'.
    ls_sort-down = ''.
    APPEND ls_sort TO lt_sort.
    "方法set_table_for_first_display
    "参数:it_sort
    "设置sort,在alv显示后更改排序使用
    "lo_alv->set_sort_criteria( it_sort = lt_sort ).
  ENDMETHOD.
ENDCLASS.

 示例2:模拟SM30,Table Maintain功能

定义class:zcl_tabm_event_handler处理事件;

定义class:axl_tab_maintain,实现table maintain功能;

创建GUI STATUS,设定Table Maintain编辑,新增,删除,保存功能Function Code;

创建Screen 100,用来显示Table Maintain页面;

"cl_gui_alv_grid事件
CLASS zcl_tabm_event_handler DEFINITION.
  PUBLIC SECTION.
    "user command
    CLASS-METHODS:m_user_command FOR EVENT user_command OF cl_gui_alv_grid
       IMPORTING e_ucomm.
ENDCLASS.
CLASS zcl_tabm_event_handler IMPLEMENTATION.
  METHOD m_user_command.
    DATA:lv_mes TYPE string.
    lv_mes = 'function:' && e_ucomm.
    MESSAGE lv_mes TYPE 'I'.
  ENDMETHOD.
ENDCLASS.

CLASS zcl_tab_maintain DEFINITION.
  PUBLIC SECTION.
    "table name
    DATA:lv_tabname TYPE ddobjname.
    DATA:lo_container TYPE REF TO cl_gui_docking_container.
    DATA:lo_alv TYPE REF TO cl_gui_alv_grid.
    "table data
    DATA:lo_table TYPE REF TO DATA.
    "alv field字段
    DATA:lt_fcat TYPE lvc_t_fcat.
    DATA:ls_fcat TYPE lvc_s_fcat.
    "alv layout
    DATA:ls_layout TYPE lvc_s_layo.
    "table status
    DATA:lv_tab_status TYPE C LENGTH 1. "C為修改,空為顯示,A為添加
    "保存table結構類型,line結構體類型
    DATA:lo_tabledescr TYPE REF TO cl_abap_tabledescr.
    DATA:lo_structdescr TYPE REF TO cl_abap_structdescr.

    METHODS:constructor IMPORTING iv_tabname TYPE ddobjname.
    METHODS:m_init_alv.
    METHODS:m_show_alv.
    METHODS:m_get_fcat RETURNING VALUE(et_fcat) TYPE lvc_t_fcat.
    METHODS:m_set_fcat IMPORTING it_fcat TYPE lvc_t_fcat.
    METHODS:m_get_layout RETURNING VALUE(es_layout) TYPE lvc_s_layo.
    METHODS:m_set_layout IMPORTING is_layout TYPE lvc_s_layo.
    METHODS:m_set_status IMPORTING iv_status TYPE char1.
    METHODS:m_get_status RETURNING VALUE(ev_status) TYPE char1.
    METHODS:m_refresh_alv.
    "some action
    METHODS:m_edit_action.
    METHODS:m_add_action.
    METHODS:m_del_action.
    METHODS:m_save_action.
  PRIVATE SECTION.
    METHODS:m_get_data IMPORTING iv_tab_name TYPE ddobjname.
    METHODS:m_build_filedcat IMPORTING iv_structure_name TYPE ddobjname.
    METHODS:m_build_layout.
    METHODS:m_set_events.
ENDCLASS.

CLASS zcl_tab_maintain IMPLEMENTATION.
  METHOD:constructor.
    DATA:lv_msg TYPE string.
    DATA:lo_struct_type TYPE REF TO cl_abap_structdescr.
    DATA:lo_table_type TYPE REF TO cl_abap_tabledescr.
    "自定義字段component
    DATA:lt_comp_tab TYPE cl_abap_structdescr=>component_table.
    DATA:ls_comp_tab LIKE LINE OF lt_comp_tab.
    DATA:lo_exception TYPE REF TO cx_root.
    DATA:lv_gotstate TYPE ddgotstate.
    TRY.
      "創建表名
      lv_tabname = iv_tabname.
      "檢查table是否存在
      CALL FUNCTION 'DDIF_TABL_GET'
        EXPORTING
          NAME = lv_tabname
        IMPORTING
          GOTSTATE = lv_gotstate.
      IF SY-SUBRC <> 0 OR lv_gotstate IS INITIAL.
        lv_msg = 'Table:' && lv_tabname && ` do not exist!`.
        MESSAGE lv_msg TYPE 'E'.
      ENDIF.

      "創建table
      lo_struct_type ?= cl_abap_typedescr=>describe_by_name( lv_tabname ).
      lt_comp_tab = lo_struct_type->get_components( ).

      "最終結構創建table
      lo_structdescr = cl_abap_structdescr=>create( lt_comp_tab ).
      lo_tabledescr = cl_abap_tabledescr=>create( lo_structdescr ).

      "創建table
      CREATE DATA lo_table TYPE HANDLE lo_tabledescr.

    CATCH cx_root INTO lo_exception.
      lv_msg = lo_exception->get_text( ).
      MESSAGE lv_msg TYPE 'E'.
    ENDTRY.
  ENDMETHOD.
  METHOD:m_init_alv.
    "創建容器
    CREATE OBJECT lo_container
      EXPORTING
        dynnr = '100'
        repid = sy-repid
        extension = 1000.
    "創建alv
    IF lo_alv IS INITIAL.
      CREATE OBJECT lo_alv
          EXPORTING i_parent = lo_container.
    ENDIF.
    "獲取數據
    me->m_get_data( lv_tabname ).
    "fieldcat設置
    me->m_build_filedcat( lv_tabname ).
    "layout設置
    me->m_build_layout( ).
    "設置event
    me->m_set_events( ).
  ENDMETHOD.
  METHOD:m_show_alv.
    FIELD-SYMBOLS:<f_table> TYPE STANDARD TABLE.
    ASSIGN lo_table->* TO <f_table>.
    "顯示alv
    lo_alv->set_table_for_first_display(
      EXPORTING
        "layout
        is_layout             = ls_layout
      CHANGING
        it_fieldcatalog       = lt_fcat
        it_outtab             = <f_table> ).
  ENDMETHOD.
  "獲取,設置fieldcat
  METHOD:m_get_fcat.
    et_fcat = lt_fcat.
  ENDMETHOD.
  METHOD:m_set_fcat.
    lt_fcat = it_fcat.
  ENDMETHOD.
  "獲取,設置layout
  METHOD:m_get_layout.
    es_layout = ls_layout.
  ENDMETHOD.
  METHOD:m_set_layout.
    ls_layout = is_layout.
  ENDMETHOD.
  "獲取table status
  METHOD:m_set_status.
    lv_tab_status = iv_status.
  ENDMETHOD.
  METHOD:m_get_status.
    ev_status = lv_tab_status.
  ENDMETHOD.

  "獲取table數據
  METHOD:m_get_data.
    FIELD-SYMBOLS:<f_table> TYPE STANDARD TABLE.
    ASSIGN lo_table->* TO <f_table>.
    "查詢數據
    SELECT * INTO CORRESPONDING FIELDS OF TABLE <f_table> FROM (iv_tab_name).
  ENDMETHOD.
  "自動生成fieldcat
  METHOD:m_build_filedcat.
    DATA:lv_index TYPE I.
    FIELD-SYMBOLS:<f_fcat> TYPE lvc_s_fcat.
    "fieldcat使用用戶設置
    IF lt_fcat IS NOT INITIAL.
      RETURN.
    ENDIF.

    "獲取fieldcatalog
    CALL FUNCTION 'LVC_FIELDCATALOG_MERGE'
      EXPORTING
        i_structure_name       = iv_structure_name
      CHANGING
        ct_fieldcat            = lt_fcat
      EXCEPTIONS
        inconsistent_interface = 1
        program_error          = 2
        OTHERS                 = 3.
    IF sy-subrc <> 0.
      MESSAGE 'Get fieldcatlog failed!' TYPE 'E'.
      RETURN.
    ENDIF.
    LOOP AT lt_fcat ASSIGNING <f_fcat>.
      lv_index = sy-tabix.
      <f_fcat>-col_pos = lv_index.
      <f_fcat>-tabname = iv_structure_name.
    ENDLOOP.

  ENDMETHOD.
  "自動生成layout
  METHOD:m_build_layout.
    "編輯設置
    ls_layout-edit = ''. "是否可編輯,整體控制
    "顯示設置
    ls_layout-cwidth_opt = 'X'. "是否自動列寬
    ls_layout-no_toolbar = 'X'. "是否隱藏toolbar.
    "選擇模式,默認單選,A:行,列選擇;B:單行選擇;C:多行選擇;D:單元格選擇
    ls_layout-sel_mode = 'A'.
  ENDMETHOD.
  METHOD:m_set_events.
    "設置function相應事件
    SET HANDLER zcl_tabm_event_handler=>m_user_command FOR lo_alv.
  ENDMETHOD.
  METHOD:m_refresh_alv.
    lo_alv->refresh_table_display( ).
  ENDMETHOD.
  "edit action
  METHOD:m_edit_action.
    "alv field字段
    FIELD-SYMBOLS:<f_fcat> TYPE lvc_s_fcat.
    "修改edit狀態
    LOOP AT lt_fcat ASSIGNING <f_fcat>.
      "特定欄位控制
*      IF <f_fcat>-fieldname = ''.
*        <f_fcat>-edit = 'X'.
*      ENDIF.
      IF lv_tab_status = ''.
        <f_fcat>-edit = 'X'.
      ELSEIF lv_tab_status = 'C'.
        <f_fcat>-edit = ''.
      ENDIF.
    ENDLOOP.
    "設置status
    IF lv_tab_status = ''.
      lv_tab_status = 'C'.
    ELSEIF lv_tab_status = 'C'.
      lv_tab_status = ''.
    ENDIF.

    "刷新
    me->m_show_alv( ).
  ENDMETHOD.
  "添加空行
  METHOD:m_add_action.
    DATA:lo_line TYPE REF TO DATA.
    FIELD-SYMBOLS:<f_table> TYPE STANDARD TABLE.
    FIELD-SYMBOLS:<f_line> TYPE ANY.
    "alv field字段
    FIELD-SYMBOLS:<f_fcat> TYPE lvc_s_fcat.

    ASSIGN lo_table->* TO <f_table>.
    CREATE DATA lo_line LIKE LINE OF <f_table>.
    ASSIGN lo_line->* TO <f_line>.
    INSERT <f_line> INTO <f_table> INDEX 1.

    "設置編輯狀態
    lv_tab_status = 'A'.
    "修改edit狀態
    LOOP AT lt_fcat ASSIGNING <f_fcat>.
      "特定欄位控制
*      IF <f_fcat>-fieldname = ''.
*        <f_fcat>-edit = 'X'.
*      ENDIF.

      IF <f_fcat>-edit = 'X'.
        EXIT.
      ENDIF.
      <f_fcat>-edit = 'X'.
    ENDLOOP.
    "刷新
    me->m_show_alv( ).
  ENDMETHOD.
  "刪除操作
  METHOD:m_del_action.
    FIELD-SYMBOLS:<f_table> TYPE STANDARD TABLE.
    FIELD-SYMBOLS:<f_del_table> TYPE STANDARD TABLE.
    FIELD-SYMBOLS:<f_line> TYPE ANY.
    DATA:lt_rows TYPE lvc_t_row.
    DATA:ls_rows TYPE lvc_s_row.
    DATA:lo_del_table TYPE REF TO DATA.
    "創建table
    CREATE DATA lo_del_table TYPE HANDLE lo_tabledescr.

    "獲取選擇行
    lo_alv->get_selected_rows(
      IMPORTING
        et_index_rows = lt_rows
    ).
    "獲取table,刪除選擇行
    ASSIGN lo_table->* TO <f_table>.
    ASSIGN lo_del_table->* TO <f_del_table>.
    LOOP AT lt_rows INTO ls_rows.
      DELETE <f_table> INDEX ls_rows-index.
      READ TABLE <f_table> INDEX ls_rows-index ASSIGNING <f_line>.
      APPEND <f_line> TO <f_del_table>.
    ENDLOOP.
    DELETE (lv_tabname) FROM TABLE <f_del_table>.
    "刷新
    me->m_show_alv( ).
  ENDMETHOD.
  "保存操作
  METHOD:m_save_action.
    FIELD-SYMBOLS:<f_table> TYPE STANDARD TABLE.
    "alv field字段
    FIELD-SYMBOLS:<f_fcat> TYPE lvc_s_fcat.

    "獲取table
    ASSIGN lo_table->* TO <f_table>.

    "檢查邏輯

    "更新數據表
    MODIFY (lv_tabname) FROM TABLE <f_table>.
    IF sy-subrc = 0.
      MESSAGE 'Save success!' TYPE 'S'.
    ENDIF.

    "設置編輯狀態
    lv_tab_status = ''.
    "修改edit狀態
    LOOP AT lt_fcat ASSIGNING <f_fcat>.
      "特定欄位控制
*      IF <f_fcat>-fieldname = ''.
*        <f_fcat>-edit = 'X'.
*      ENDIF.
      <f_fcat>-edit = ''.
    ENDLOOP.
    "刷新
    me->m_show_alv( ).
  ENDMETHOD.
ENDCLASS.


"table maintain類對象
DATA:lo_tab_maintain TYPE REF TO zcl_tab_maintain.

SELECTION-SCREEN BEGIN OF BLOCK blk1 WITH FRAME TITLE text-001.
  PARAMETERS:p_tab TYPE ddobjname. "maintain table name
SELECTION-SCREEN END OF BLOCK blk1.


START-OF-SELECTION.
  PERFORM f_show_alv.

FORM f_show_alv.
  CREATE OBJECT lo_tab_maintain
    EXPORTING
      iv_tabname = p_tab.
  lo_tab_maintain->m_init_alv( ).
  lo_tab_maintain->m_show_alv( ).
  CALL SCREEN 100.
ENDFORM.

*&---------------------------------------------------------------------*
*&      Module  STATUS_0100  OUTPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
MODULE STATUS_0100 OUTPUT.
   SET PF-STATUS 'STATUS_100'.
*  SET TITLEBAR 'xxx'.
ENDMODULE.                 " STATUS_0100  OUTPUT
*&---------------------------------------------------------------------*
*&      Module  USER_COMMAND_0100  INPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
MODULE USER_COMMAND_0100 INPUT.
  DATA:g_ok_code TYPE sy-ucomm.
  CASE g_ok_code.
    WHEN 'BACK' OR 'EXIT' OR 'CANCEL'.
      LEAVE PROGRAM.
    WHEN 'EDIT'.
      PERFORM f_edit_action.
    WHEN 'ADD'.
      PERFORM f_add_action.
    WHEN 'DELETE'.
      PERFORM f_delete_action.
    WHEN 'SAVE'.
      PERFORM f_save_action.
    WHEN OTHERS.
  ENDCASE.
ENDMODULE.                 " USER_COMMAND_0100  INPUT

"edit action
FORM f_edit_action.
  lo_tab_maintain->m_edit_action( ).
ENDFORM.

"add action
FORM f_add_action.
  lo_tab_maintain->m_add_action( ).
ENDFORM.

"delete action
FORM f_delete_action.
  lo_tab_maintain->m_del_action( ).
ENDFORM.

"save action
FORM f_save_action.
  lo_tab_maintain->m_save_action( ).
ENDFORM.

 

 

posted @ 2021-05-08 13:54  渔歌晚唱  阅读(264)  评论(0编辑  收藏  举报