点击蓝字 关注我们
一
前言
关于行表转列表的介绍,参考如下链接
详见链接
无峰,公众号:ABAP 技巧与实战SAP工具箱 行表转列表的通用类
本文主要介绍行表转列表时,保持单元格的颜色及编辑状态
二
示例程序
示例程序名: ZTS_COL_TO_LINE_EDIT_COL
源代码附在文末
01
内表定义
02
内表内容
构造内表内容,及单元格的编辑状态/颜色
03
行表呈现
行表ALV呈现(部分单元格可编辑,数量字段有不同的颜色),使用了单元格的颜色设置及编辑状态设置
详情可参考标准示例程序
BCALV_TEST_COLORS 单元格颜色
BCALV_EDIT_02 单元格可标记状态
04
转换列表
调用类ZCL_REP_COMM_LINE_COL
方法CONVERT_LINE_TO_COL
转换成列表
05
列表呈现
列表显示的ALV(保留了行表显示时的颜色及编辑状态)
三
处理原理
行表转列表的类ZCL_REP_COMM_LINE_COL 方法 CONVERT_LINE_TO_COL 中补充了参数,
用来传递内表中记录颜色/编辑状态的字段(通过表类型LVC_T_SCOL / LVC_T_STYL 定义)
在类的处理中,根据行专列的规则,在新建的动态内表中同样补充这两个字段,并且按照行转列的规则,调整这两个内表中的内容.
原理说起来挺简单,实际调整时还是很费事的. 因为要用动态语法支持所有传入的内表,很多细节逻辑都需要反复验证.
四
待补充逻辑
因为只改进了方法 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.