SAP工具箱 行转列优化 单元格颜色及可编辑状态

本文介绍了如何在SAP ABAP中将行表转换为列表时,同时保留单元格的颜色和编辑状态。通过自定义类ZCL_REP_COMM_LINE_COL的方法CONVERT_LINE_TO_COL,实现了行转列并保持原ALV的样式信息。文章提供了示例程序代码,展示了行表的ALV呈现、转换为列表以及列表的ALV显示。
摘要由CSDN通过智能技术生成

点击蓝字 关注我们

前言

关于行表转列表的介绍,参考如下链接

详见链接

无峰,公众号:ABAP 技巧与实战SAP工具箱 行表转列表的通用类

本文主要介绍行表转列表时,保持单元格的颜色及编辑状态

示例程序

示例程序名: ZTS_COL_TO_LINE_EDIT_COL

源代码附在文末

01

内表定义

60b60130619fb1a08b4ee3203e967d7b.png

02

内表内容

构造内表内容,及单元格的编辑状态/颜色

cc507d355c230305c5c7324c2e7c1325.png

03

行表呈现

行表ALV呈现(部分单元格可编辑,数量字段有不同的颜色),使用了单元格的颜色设置及编辑状态设置

详情可参考标准示例程序

  • BCALV_TEST_COLORS  单元格颜色

  • BCALV_EDIT_02   单元格可标记状态

b9f5d114d299efc041d9b3b55ddbd6ff.png

04

转换列表

调用类ZCL_REP_COMM_LINE_COL 

方法CONVERT_LINE_TO_COL

转换成列表

f69b59e05412b5fc7e93cc96d1da3638.png

05

列表呈现

列表显示的ALV(保留了行表显示时的颜色及编辑状态)

d90ff76cbafe12a4be22fd42b37d9583.png

处理原理

行表转列表的类ZCL_REP_COMM_LINE_COL 方法 CONVERT_LINE_TO_COL 中补充了参数,

用来传递内表中记录颜色/编辑状态的字段(通过表类型LVC_T_SCOL / LVC_T_STYL 定义)

在类的处理中,根据行专列的规则,在新建的动态内表中同样补充这两个字段,并且按照行转列的规则,调整这两个内表中的内容.

原理说起来挺简单,实际调整时还是很费事的. 因为要用动态语法支持所有传入的内表,很多细节逻辑都需要反复验证.

1c7408cb08fd2200618b680596249f9b.png

待补充逻辑

因为只改进了方法 CONVERT_LINE_TO_COL . 另外的通用方法尚未调整. 这个会影响整合在ALV 中的通用行专列按钮. 通过该按钮转换的列表没有携带源ALV的颜色及编辑状态信息

  • CONVERT_LINE_TO_COL_FULL_ALV全屏ALV清单行表转为列表

  • CONVERT_LINE_TO_COL_ALV对象ALV清单行表转为列表

总结

通用行转列的类基本解决了行表转列表的所有需求

  • 字段命名

  • 关键字段

  • 附加字段

  • 汇总字段

  • 行选中标记

  • 单元格颜色

  • 单元格编辑状态

  • 列表修改的内容回写行表

  • ......

具体可以参考如下链接了解更多的行专列的信息

详见链接

无峰,公众号:ABAP 技巧与实战ABAP基础知识 行表与列表的转换

示例程序代码

*&---------------------------------------------------------------------*
*& Report ZTS_COL_TO_LINE_N
*&---------------------------------------------------------------------*
*&调用通用类实现行转列, 调整数量后回写到原内表.如果无需回写,可以去掉和ALV事件相关的代码
*&---------------------------------------------------------------------*
REPORT zts_col_to_line_edit_col.
PARAMETERS: p_line RADIOBUTTON GROUP ra1, "行表显示
            p_col  RADIOBUTTON GROUP ra1. "列表显示
PARAMETERS: p_width TYPE i DEFAULT 20.
DATA: gc_grid TYPE REF TO cl_gui_alv_grid.
DATA: gt_modi TYPE lvc_t_modi.


DATA: gt_fcat TYPE lvc_t_fcat,
      gt_fd   TYPE zsline_to_col_fields_tab.
DATA: gt_line_n TYPE TABLE OF zsline_to_col_demo_edit_col.


DATA: gt_fcat_x TYPE lvc_t_fcat.
DATA: grt_data_x TYPE REF TO data.
DATA: grt_data_xl  TYPE REF TO data,
      grw_data_key TYPE REF TO data.
DATA: gt_rel TYPE zsline_to_col_rel_tab.
DATA: gt_fd_rel TYPE zsline_to_col_field_rel_tab.
FIELD-SYMBOLS: <gt_data_x>  TYPE STANDARD TABLE,
               <gt_data_xl> TYPE HASHED TABLE,
               <lw_key>     TYPE any.


CLASS lcl_event_receiver DEFINITION.
  PUBLIC SECTION.
    METHODS handle_modify
      FOR EVENT data_changed_finished OF cl_gui_alv_grid
      IMPORTING e_modified et_good_cells.
ENDCLASS.                    "LCL_EVENT_RECEIVER DEFINITION


DATA gc_event_receiver TYPE REF TO lcl_event_receiver .


CLASS lcl_event_receiver IMPLEMENTATION.
  METHOD handle_modify.
    APPEND LINES OF et_good_cells TO gt_modi. "记录发生过修改的单元格.


  ENDMETHOD.                    "HANDLE_MODIFY
ENDCLASS.                    "LCL_EVENT_RECEIVER IMPLEMENTATION


START-OF-SELECTION.
  PERFORM frm_get_data.
*调用类方法行表专列表
  CASE 'X'.
    WHEN p_line.
      PERFORM frm_line_disp..
    WHEN p_col.
      PERFORM frm_col_disp.
  ENDCASE.




*&---------------------------------------------------------------------*
*& Form FRM_ALV_DATA
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM frm_alv_data .
  DATA: lv_repid LIKE sy-repid,
        lv_title TYPE lvc_title.
  DATA: ls_layout TYPE lvc_s_layo.
  ls_layout-cwidth_opt = 'X'.
  ls_layout-zebra = 'X'.
  ls_layout-edit = ''.
  ls_layout-edit_mode = ''.
  ls_layout-no_keyfix = 'X'.
  ls_layout-ctab_fname =  'COLTAB'. "颜色信息
  ls_layout-stylefname = 'CELLTAB'. "编辑信息
  ls_layout-box_fname = 'SEL'.


  lv_repid = sy-repid.
  lv_title = '显示转换后的列表'.
  DATA:  gt_events TYPE slis_t_event .
  gt_events = VALUE #( ( name = 'CALLER_EXIT' form = 'FRM_REGISTER' ) ).
*如果字段存在KEY 标记, 则颜色设置失效.
  LOOP AT gt_fcat_x ASSIGNING FIELD-SYMBOL(<fs_x>).
    <fs_x>-key = ''.
  ENDLOOP.
  CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC'
    EXPORTING
      i_callback_program       = lv_repid
      i_grid_title             = lv_title
      i_callback_pf_status_set = 'FRM_SET_STATUS'
      i_callback_user_command  = 'FRM_SET_USERCOMMAND'
      it_events                = gt_events
      is_layout_lvc            = ls_layout
*     i_structure_name         = 'ZTBAPI_ERROR'
      it_fieldcat_lvc          = gt_fcat_x
    TABLES
      t_outtab                 = <gt_data_x>.


ENDFORM.


FORM frm_set_status USING i_extab TYPE slis_t_extab.


  SET PF-STATUS 'LIST'.




ENDFORM.                    "frm_set_status


*&---------------------------------------------------------------------*
*&      Form  FRM_SET_USERCOMMAND
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->R_UCOMM      text
*      -->RS_SELFIELD  text
*----------------------------------------------------------------------*
FORM frm_set_usercommand USING r_ucomm LIKE sy-ucomm
                               rs_selfield TYPE slis_selfield.




  CASE r_ucomm.
    WHEN  '&DATA_SAVE'.
      PERFORM frm_save.
    WHEN 'L2C'.
      CALL METHOD zcl_rep_comm_line_col=>convert_line_to_col_full_alv CHANGING ct_data = gt_line_n .
  ENDCASE.


  rs_selfield-refresh = 'X'.
ENDFORM.                    "FRM_SET_USERCOMMAND
*&---------------------------------------------------------------------*
*& Form FRM_SAVE
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM frm_save .
  DATA: lv_save(1).
  lv_save = 'X'.


*  DATA: lc_grid TYPE REF TO cl_gui_alv_grid.
  CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'
*   EXPORTING
**     IR_SALV_FULLSCREEN_ADAPTER       =
    IMPORTING
*     ET_EXCLUDING                     =
*     E_REPID                          =
*     E_CALLBACK_PROGRAM               =
*     E_CALLBACK_ROUTINE               =
      e_grid = gc_grid
*     ET_FIELDCAT_LVC                  =
*     ER_TRACE                         =
*     E_FLls_NO_HTML                    =
*     ES_LAYOUT_KKBLO                  =
*     ES_SEL_HIDE                      =
*     ET_EVENT_EXIT                    =
*     ER_FORM_TOL                      =
*     ER_FORM_EOL                      =
    .
  "---Get data changed from ALV to internal table-----------
  CALL METHOD gc_grid->check_changed_data.
  "补充选择字段的变化
  DATA: lt_rows  TYPE lvc_t_row.
  CALL METHOD gc_grid->get_selected_rows
    IMPORTING
      et_index_rows = lt_rows
*     et_row_no     =
    .
  "设置选择字段修改标记.同时需要清空原内表的所有选择.
  DATA: ls_line_n LIKE LINE OF gt_line_n.
  ls_line_n-sel = ''.
  MODIFY gt_line_n FROM ls_line_n TRANSPORTING sel WHERE sel <> 'Z'.
  LOOP AT lt_rows INTO DATA(lw_rows).
    APPEND VALUE #( row_id = lw_rows-index fieldname = 'SEL' value = 'X' ) TO gt_modi.
*    read table <gt_data_x> ASSIGNING FIELD-SYMBOL(<ls_x>) index lw_rows-index. "选中标记可能没有带到内表中. 补充一下.
*    if sy-subrc = 0.
*      assign COMPONENT 'SEL' OF STRUCTURE <LS_X> TO FIELD-SYMBOL(<LV_SEL>).
*      IF SY-SUBRC = 0.
*        <LV_SEL> = 'X'.
*      ENDIF.
*    endif.
  ENDLOOP.


  SORT gt_modi BY row_id fieldname.
  DELETE ADJACENT DUPLICATES FROM gt_modi COMPARING row_id fieldname.
  EXPORT lv_save = lv_save gt_modi = gt_modi TO MEMORY ID 'ZCOL_TO_LINE_SAVE'.
  DATA: gt_line_rel TYPE zsline_to_col_line_rel_tab,
        lw_line_rel TYPE zsline_to_col_line_rel.


*修改的数据回写到源内表中.
  CALL METHOD zcl_rep_comm_line_col=>update_ori_alv
    EXPORTING
      it_line_rel  = gt_line_rel
      it_data_x    = <gt_data_x>
      it_data_xl   = <gt_data_xl>
      it_fd_rel    = gt_fd_rel
      iv_box_fname = 'SEL'
    CHANGING
      lw_key       = <lw_key>
      ct_data      = gt_line_n.
ENDFORM.


FORM frm_register USING e_grid TYPE slis_data_caller_exit.
  DATA: lc_grid TYPE REF TO cl_gui_alv_grid.
  CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'
    IMPORTING
      e_grid = lc_grid.
  "---Get data changed from ALV to internal table-----------
  CALL METHOD lc_grid->check_changed_data.
* 设置enter事件
  CALL METHOD lc_grid->register_edit_event
    EXPORTING
      i_event_id = cl_gui_alv_grid=>mc_evt_enter
    EXCEPTIONS
      error      = 1
      OTHERS     = 2.
**得到光标
  DATA: lo_cntrl TYPE REF TO cl_gui_control,
        ls_row   TYPE lvc_s_row,
        ls_col   TYPE lvc_s_col.
  CALL METHOD cl_gui_control=>get_focus
    IMPORTING
      control           = lo_cntrl
    EXCEPTIONS
      cntl_error        = 1
      cntl_system_error = 2.
*触发事件,修改描述
  CREATE OBJECT gc_event_receiver.
  SET HANDLER gc_event_receiver->handle_modify FOR lc_grid.
*   SET HANDLER gc_event_receiver->handle_data_changed FOR lc_grid.
*  SET HANDLER gt_event_receiver->GET_CHANGED_DATA FOR tem_grid.
** 设置 单光标焦点移开被修改单元格后既触发事件
*  CALL METHOD tem_grid->register_edit_event
*    EXPORTING
*      i_event_id = cl_gui_alv_grid=>mc_evt_modified
*    EXCEPTIONS
*      error      = 1
*      OTHERS     = 2.


ENDFORM.                    "fm_button
*&---------------------------------------------------------------------*
*& Form frm_get_data
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM frm_get_data .
  gt_line_n = VALUE #(
  ( name = '张三' cat = '电视' nf = '2020' sl = 10  je = 50   cat_name = 'TV' )
  ( name = '张三' cat = '手机' nf = '2020' sl = 20  je = 100  cat_name = 'PH' )
  ( name = '张三' cat = '冰箱' nf = '2020' sl = 30  je = 150  cat_name = 'TL' )
  ( name = '李四' cat = '电视' nf = '2020' sl = 40  je = 200  cat_name = 'TV' )
  ( name = '李四' cat = '电视' nf = '2020' sl = 5   je = 25   cat_name = 'TV' )
  ( name = '李四' cat = '手机' nf = '2020' sl = 50  je = 250  cat_name = 'PH' )
  ( name = '王五' cat = '冰箱' nf = '2020' sl = 60  je = 300  cat_name = 'TL' )


  ( name = '张三' cat = '电视' nf = '2021' sl = 110 je = 550  cat_name = 'TV' )
  ( name = '张三' cat = '手机' nf = '2021' sl = 120 je = 600  cat_name = 'PH' )
  ( name = '张三' cat = '冰箱' nf = '2021' sl = 130 je = 650  cat_name = 'TL' )
  ( name = '李四' cat = '电视' nf = '2021' sl = 140 je = 700  cat_name = 'TV' )
  ( name = '李四' cat = '电视' nf = '2021' sl = 15  je = 75   cat_name = 'TV' )
  ( name = '李四' cat = '手机' nf = '2021' sl = 150 je = 750  cat_name = 'PH' )
  ( name = '王五' cat = '冰箱' nf = '2021' sl = 160 je = 800  cat_name = 'TL' )
  ).
  "设置编辑状态和颜色
  DATA: lv_edit  TYPE i,
        lv_col   TYPE i,
        lv_tabix TYPE i.
  DATA: ls_col TYPE lvc_s_colo.
  DATA: lv_style TYPE lvc_s_styl-style.
  LOOP AT gt_line_n ASSIGNING FIELD-SYMBOL(<ls_n>).
    lv_tabix = lv_tabix + 1.
    lv_edit = lv_tabix MOD 2. "编辑状态间隔
    lv_col = lv_tabix MOD 8.  "颜色顺序
    CASE lv_edit.
      WHEN 1. lv_style = cl_gui_alv_grid=>mc_style_disabled.
      WHEN 0. lv_style = cl_gui_alv_grid=>mc_style_enabled.
    ENDCASE.
    ls_col-col = lv_col.
    ls_col-int = lv_edit.
    ls_col-inv = lv_edit.
    INSERT VALUE #( fieldname = 'SL'  style = lv_style ) INTO TABLE <ls_n>-celltab.
    INSERT VALUE #( fieldname = 'JE'  style = lv_style ) INTO TABLE <ls_n>-celltab.


    APPEND VALUE #( fname = 'SL' color = ls_col nokeycol = 'X' ) TO <ls_n>-coltab.
*    APPEND VALUE #( fname = 'JE' color = ls_col nokeycol = 'X' ) TO <ls_n>-coltab.


  ENDLOOP.
  "获取字段信息:标准获取字段的函数LVC_FIELDCATALOG_MERGE无法获取嵌套定义的内表  CELLTAB  COLTAB 都是嵌套定义的内表, 无法获取.
  CALL FUNCTION 'LVC_FIELDCATALOG_MERGE'
    EXPORTING
      i_structure_name       = 'ZSLINE_TO_COL_DEMO_EDIT_COL'
    CHANGING
      ct_fieldcat            = gt_fcat
    EXCEPTIONS
      inconsistent_interface = 1
      program_error          = 2
      OTHERS                 = 3.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form frm_line_disp
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM frm_line_disp .
  DATA: lv_repid LIKE sy-repid,
        lv_title TYPE lvc_title.
  DATA: ls_layout TYPE lvc_s_layo.
  ls_layout-cwidth_opt = 'X'.
  ls_layout-zebra = 'X'.
*  ls_layout-edit = 'X'.
  ls_layout-edit_mode = ''.
  ls_layout-no_keyfix = 'X'.
  ls_layout-ctab_fname =  'COLTAB'. "颜色信息
  ls_layout-stylefname = 'CELLTAB'. "编辑信息
  ls_layout-box_fname = 'SEL'.


  lv_repid = sy-repid.
  lv_title = '显示转换后的列表'.
  DATA:  gt_events TYPE slis_t_event .
  gt_events = VALUE #( ( name = 'CALLER_EXIT' form = 'FRM_REGISTER' ) ).
*如果字段存在KEY 标记, 则颜色设置失效.
  LOOP AT gt_fcat ASSIGNING FIELD-SYMBOL(<fs_fcat>).
    CASE <fs_fcat>-fieldname.
      WHEN 'SL' OR 'JE'.
        <fs_fcat>-edit = 'X'.
    ENDCASE.
  ENDLOOP.
  CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC'
    EXPORTING
      i_callback_program       = lv_repid
      i_grid_title             = lv_title
      i_callback_pf_status_set = 'FRM_SET_STATUS'
      i_callback_user_command  = 'FRM_SET_USERCOMMAND'
      it_events                = gt_events
      is_layout_lvc            = ls_layout
*     i_structure_name         = 'ZTBAPI_ERROR'
      it_fieldcat_lvc          = gt_fcat
    TABLES
      t_outtab                 = gt_line_n.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form frm_col_disp
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM frm_col_disp .
  FIELD-SYMBOLS <fs_data_x> TYPE ANY TABLE.
*赋值行转列所需的字段
  gt_fd = VALUE #(
    ( lc_func = 'K' lc_field = 'NAME' )
*    ( lc_func = 'K' lc_field = 'NF' )
    ( lc_func = 'C' lc_field = 'CAT' )
    ( lc_func = 'C' lc_field = 'NF' )
    ( lc_func = 'M' lc_field = 'SL' )
    ( lc_func = 'M' lc_field = 'JE' )
    ).


*调用通用方法转换成列表








  CALL METHOD zcl_rep_comm_line_col=>convert_line_to_col
    EXPORTING
      it_fcat      = gt_fcat
      it_data      = gt_line_n
      it_fd        = gt_fd
      iv_edit      = 'X'
      iv_text_s    = 'A'   "'A' 字段值 'B' 字段序号 'C' 字段值描述 'D'
      iv_coltab    = 'COLTAB'   "单元格颜色 字段
      iv_celltab   = 'CELLTAB'  "单元格编辑标记 字段
      iv_box_fname = 'SEL'       "设置行选中字段
    IMPORTING
      et_fcat_x    = gt_fcat_x
      er_data_x    = grt_data_x
      er_data_xl   = grt_data_xl
      er_data_key  = grw_data_key
      et_rel       = gt_rel
      et_fd_rel    = gt_fd_rel.
*    ev_edit     = lv_edit.
  ASSIGN grt_data_x->* TO <gt_data_x>.
  ASSIGN grt_data_xl->* TO <gt_data_xl>.
  ASSIGN grw_data_key->* TO <lw_key>.
*显示转换后的列表
*CALL METHOD cl_demo_output=>write( <gt_data_x> ).
*CALL METHOD cl_demo_output=>display( ).


  PERFORM frm_alv_data.
ENDFORM.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值