首页 > 其他 > 详细

用RTTI实现动态可维护ALV表的DEMO - Intercalaryland

时间:2019-12-13 17:38:52      阅读:81      评论:0      收藏:0      [点我收藏+]

ABAP为动态编程提供了RTTI技术,我们可以通过一系列descriptor获取DDIC对象的属性,也能通过这些属性创建DDIC对象。根据这个特性,我们就可以根据输入的透明表名,动态地生成可编辑地ALV。

 

 技术分享图片

输入界面,动态地输入表名。

 

 技术分享图片

生成效果示例(这里用了一个自建表来展示效果)。

 

 技术分享图片

事务代码SE16可以看到数据已成功维护进了透明表(这里用了一个自建表来展示效果)。

 

代码如下:

(注意: 本程序使用了自定义的pf_status,如果其他人希望本程序运行,需要在自己的pf_status中增加&SAVE, &ADD, &DEL等按钮 )

*&---------------------------------------------------------------------*
*& Report ZYREPO1_PREPARE
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT zyrepo1_prepare.

TABLES:
  dd02l, "Table Names
  dd03l. "Table Fields

DATA:
  g_flag   TYPE i VALUE 0,
  lr_table TYPE REF TO data,
  lr_tab01 TYPE REF TO data,
  lr_str01 TYPE REF TO data,
  lo_table TYPE REF TO cl_abap_tabledescr, "Source table descr
  lo_tab01 TYPE REF TO cl_abap_tabledescr, "Target table descr
  lo_struc TYPE REF TO cl_abap_structdescr,"Source structure descr
  lo_str01 TYPE REF TO cl_abap_structdescr."Target Structure descr

DATA:
  lt_list TYPE ddfields,          "field list
  wa_list LIKE LINE OF lt_list,   "components
  lt_comp TYPE abap_component_tab.

FIELD-SYMBOLS:
  <ft_table> TYPE STANDARD TABLE,
  <ft_tab01> TYPE STANDARD TABLE,
  <fs_line>  TYPE any,
  <fs_field> TYPE any.

DATA:
  gt_fieldcat TYPE lvc_t_fcat,
  gs_fieldcat TYPE lvc_s_fcat,
  gs_layout   TYPE lvc_s_layo.

SELECTION-SCREEN BEGIN OF BLOCK b1.

PARAMETERS:
  p_tabnam TYPE dd02l-tabname OBLIGATORY.

SELECTION-SCREEN END OF BLOCK b1.

AT SELECTION-SCREEN.

  "Only customizing table are allowed to be modified for security
  IF p_tabnam IS NOT INITIAL AND p_tabnam+0(1) <> ‘Z‘.
    MESSAGE ‘只有自建表可供维护‘ TYPE ‘I‘ DISPLAY LIKE ‘E‘.
    LEAVE PROGRAM.
  ENDIF.

START-OF-SELECTION.
  PERFORM get_tab_info.
  PERFORM set_fieldcat.
  PERFORM show_alv.

FORM get_tab_info.

  "Create source table
  CREATE DATA lr_table TYPE TABLE OF (p_tabnam).
  ASSIGN lr_table->* TO <ft_table>.

  "Fill source table if value exist
  SELECT *
    FROM (p_tabnam)
    INTO CORRESPONDING FIELDS OF TABLE <ft_table>.

  "Get structure, field, component info from source table
  lo_table ?= cl_abap_typedescr=>describe_by_data( <ft_table> ).
  lo_struc ?= lo_table->get_table_line_type( ).
  lt_list = lo_struc->get_ddic_field_list( ).
  lt_comp = lo_struc->get_components( ).

  "Create target table
  lo_tab01 = cl_abap_tabledescr=>create( p_line_type = lo_struc ).
  CREATE DATA lr_tab01 TYPE HANDLE lo_tab01.
  ASSIGN lr_tab01->* TO <ft_tab01>.

  "Assign records from source table to target table
  IF lines( <ft_table> ) > 0.

    LOOP AT <ft_table> ASSIGNING <fs_line>.

      APPEND <fs_line> TO <ft_tab01>.

    ENDLOOP.

  ENDIF.

  "Give an extra void line to target table
  lo_str01 = cl_abap_structdescr=>create( lt_comp ).
  CREATE DATA lr_str01 TYPE HANDLE lo_str01.
  ASSIGN lr_str01->* TO <fs_line>.
  APPEND <fs_line> TO <ft_tab01>.

ENDFORM.

FORM set_fieldcat.

  "Generate fieldcat dynamically
  IF lt_list IS NOT INITIAL.

    LOOP AT lt_list INTO wa_list.
      gs_fieldcat-fieldname = wa_list-fieldname.
      gs_fieldcat-seltext = wa_list-fieldtext.
      gs_fieldcat-coltext = gs_fieldcat-seltext.
      gs_fieldcat-col_opt = ‘X‘.
      gs_fieldcat-edit = ‘X‘.
      APPEND gs_fieldcat TO gt_fieldcat.
      CLEAR gs_fieldcat.
    ENDLOOP.

  ENDIF.

ENDFORM.

FORM show_alv.

  CALL FUNCTION ‘REUSE_ALV_GRID_DISPLAY_LVC‘
    EXPORTING
      i_callback_program       = sy-repid
      is_layout_lvc            = gs_layout
      it_fieldcat_lvc          = gt_fieldcat[]
      i_callback_user_command  = ‘ALV_COMMAND‘
      i_callback_pf_status_set = ‘ALV_PF_STATUS‘
      i_save                   = ‘A‘
      "i_grid_title             = g_title
      "it_sort_lvc              = gt_sort[]
      "it_events                = gt_events[]
    TABLES
      t_outtab                 = <ft_tab01>
    EXCEPTIONS
      program_error            = 1
      OTHERS                   = 2.


ENDFORM.

FORM alv_pf_status USING rt_extab TYPE slis_t_extab.

  DATA:
    fcode LIKE LINE OF rt_extab.

  "Customizing pf_status
  SET PF-STATUS ‘PF_STATUS1‘ EXCLUDING rt_extab.

ENDFORM.

FORM alv_command
    USING ucomm LIKE sy-ucomm
        selfield TYPE slis_selfield.

  DATA:
    ref_grid    TYPE REF TO cl_gui_alv_grid,
    lt_filtered TYPE lvc_t_fidx,
    stbl        TYPE lvc_s_stbl,
    l_index     LIKE LINE OF lt_filtered.

  "Get ALV grid
  CALL FUNCTION ‘GET_GLOBALS_FROM_SLVC_FULLSCR‘
    IMPORTING
      e_grid = ref_grid.

  CALL METHOD ref_grid->check_changed_data.

  "React to command
  CASE ucomm.
    WHEN ‘&SAVE‘.
      PERFORM save_data.
    WHEN ‘&ADD‘.
      PERFORM add_line.
    WHEN ‘&DEL‘.
      PERFORM del_line USING selfield-tabindex.
  ENDCASE.

  "Refresh
  IF ref_grid IS NOT INITIAL.

    CALL METHOD ref_grid->check_changed_data.

    stbl-row = ‘X‘.
    stbl-col = ‘X‘.
    CALL METHOD ref_grid->refresh_table_display
      EXPORTING
        is_stable = stbl.

  ENDIF.

ENDFORM.

FORM save_data.

  DATA:
    l_success TYPE i VALUE 0.

  LOOP AT <ft_tab01> ASSIGNING <fs_line>.

    IF <fs_line> IS NOT INITIAL.
      MODIFY (p_tabnam)
        FROM <fs_line>.
      IF sy-subrc = 0.

      ELSE.
        l_success = sy-subrc.
        EXIT.
      ENDIF.
    ENDIF.

  ENDLOOP.

  IF l_success = 0.
    COMMIT WORK AND WAIT.
    MESSAGE ‘更新数据成功‘ TYPE ‘S‘.
  ELSE.
    ROLLBACK WORK.
    MESSAGE ‘更新失败,已回滚‘ TYPE ‘S‘ DISPLAY LIKE ‘E‘.
  ENDIF.

ENDFORM.

FORM add_line.

  ASSIGN lr_str01->* TO <fs_line>.
  APPEND <fs_line> TO <ft_tab01>.

ENDFORM.

FORM del_line USING tab_index.

  READ TABLE <ft_tab01> ASSIGNING <fs_line> INDEX tab_index.
  DELETE (p_tabnam) FROM <fs_line>.
  DELETE <ft_tab01> INDEX tab_index.

ENDFORM.

用RTTI实现动态可维护ALV表的DEMO - Intercalaryland

原文:https://www.cnblogs.com/Intercalaryland/p/12036270.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!