ABAP学习(34):cl_gui_alv_grid实现Table Maintain

实现Table Maintain

通过类CL_GUI_ALV_GRID,实现Table Maintain功能。

实现效果:

 

1.创建Program;

2.创建空Screen 100;

3.创建GUI Status;

Program:实例代码

"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.
    "data changed
    CLASS-METHODS:m_data_changed FOR EVENT data_changed OF cl_gui_alv_grid
       IMPORTING er_data_changed
                 e_onf4
                 e_onf4_before
                 e_onf4_after
                 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.
  METHOD m_data_changed.
    DATA:lt_mod_data TYPE lvc_t_modi.
    DATA:ls_mod_data TYPE lvc_s_modi.

    lt_mod_data = er_data_changed->mt_mod_cells.

    "循環更改數據
    LOOP AT lt_mod_data INTO ls_mod_data.
*      "設置錯誤信息
*      er_data_changed->add_protocol_entry(
*        EXPORTING
*          i_msgid     = '00'
*          i_msgty     = 'E'
*          i_msgno     = '001'
*          i_msgv1     = '錯誤信息!'
*          i_fieldname = ls_mod_data-fieldname
*      ).
      "更新數據表
      er_data_changed->modify_cell(
        EXPORTING
          i_row_id    = ls_mod_data-row_id
          i_fieldname = ls_mod_data-fieldname
          i_value = ls_mod_data-value
      ).
    ENDLOOP.
  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 = ''. "是否隱藏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.
    SET HANDLER zcl_tabm_event_handler=>m_data_changed FOR lo_alv.

    "註冊enter事件
    lo_alv->register_edit_event(
      EXPORTING
        i_event_id = cl_gui_alv_grid=>mc_evt_enter
    ).
    "註冊修改單元格事件
    lo_alv->register_edit_event(
      EXPORTING
        i_event_id = cl_gui_alv_grid=>mc_evt_modified
    ).
  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.
      READ TABLE <f_table> INDEX ls_rows-index ASSIGNING <f_line>.
      APPEND <f_line> TO <f_del_table>.
    ENDLOOP.
    "刪除當前內表
    LOOP AT lt_rows INTO ls_rows.
      DELETE <f_table> INDEX ls_rows-index.
    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.

    "檢查邏輯
    "會調用data changed事件
    "會彈出檢查相關錯誤信息
    "lo_alv->check_changed_data( ).

    "獲取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 @ 2022-07-16 10:31  渔歌晚唱  阅读(511)  评论(0编辑  收藏  举报