前言
来了新入职的开发同事,因为之前双方都来自不同的乙方公司,所以开发习惯上有挺大的差异
我之前的公司是使用的LVC函数进行的报表开发,另一位同事是公司是使用的OO ALV进行开发,借此机会拓展一下知识面,再补补报表开发的基础
感觉Docking容器的应用应该比Custome Control来的多一些,毕竟不需要在屏幕上固定划出一块区域作为ALV展示的自定义容器,用户还能通过拖拽自定义容器的大小
开发步骤如下:
新建屏幕
开发Docking 容器的OO ALV只需要新建一个屏幕即可
OO ALV中常用的是ALV的tool bar,所以会把应用程序工具栏隐藏掉,勾选【无应用程序工具栏】即可
在屏幕流逻辑中新建module
新建GUI 状态 & GUI 标题
新建的GUI状态是空白的,标准工具栏的功能大多数都没有,至少把退出的几个功能先实现出来,否则用户进入ALV之后就无法退出
新建GUI标题,代码中可以用占位符&填充自定义文本
代码实现
********************************************************************
* 事务代码: *
* 程序名称: *
* 程序目的: *
* 设 计 人: *
* 开 发 人:Seele *
* 设计时间:2025-03-17 *
* 程序类型: ABAP/4 程序 ,报表程序 *
* 应用类型: *
* 描 述: *
*(修改日志)--------------------------------------------------------*
* *
* 日志号 修改人 修改时间 修改说明 传输号码 *
* ---- ---- ------ -----------
* 001 Seele 2025-02-24 创建报表程序 *
********************************************************************
REPORT zdemo_seele13.
TABLES: mara, makt.
*----------------------------------------------------------------------*
* 结构声明类型/Structure type declaration
*----------------------------------------------------------------------*
*&---主表数据/master table data
TYPES:BEGIN OF ty_output,
matnr TYPE makt-matnr , "
maktx TYPE makt-maktx , "
box TYPE c , "
style TYPE lvc_t_styl , "
color TYPE char4 , "
END OF ty_output.
*&---------------------------------------------------------------------*
*& CLASS
*&---------------------------------------------------------------------*
CLASS cl_events DEFINITION.
PUBLIC SECTION.
METHODS:
handle_toolbar FOR EVENT toolbar OF cl_gui_alv_grid IMPORTING e_object e_interactive,
handle_command FOR EVENT user_command OF cl_gui_alv_grid IMPORTING e_ucomm,
handle_data_changed FOR EVENT data_changed_finished OF cl_gui_alv_grid IMPORTING et_good_cells e_modified.
ENDCLASS.
CLASS cl_events IMPLEMENTATION.
METHOD handle_toolbar.
PERFORM frm_handle_toolbar CHANGING e_object.
ENDMETHOD.
METHOD handle_command.
PERFORM frm_handle_command USING e_ucomm.
ENDMETHOD.
METHOD handle_data_changed.
PERFORM frm_handle_data_changed USING et_good_cells e_modified.
ENDMETHOD.
ENDCLASS.
*----------------------------------------------------------------------*
* 全局变量定义/Global variable definition
*----------------------------------------------------------------------*
" OO ALV对象容器
DATA: gr_ctn_alv TYPE REF TO cl_gui_docking_container,
gr_grid TYPE REF TO cl_gui_alv_grid,
gr_events TYPE REF TO cl_events,
gt_output TYPE TABLE OF ty_output,
gt_delete TYPE TABLE OF ty_output,
gt_fieldcat TYPE TABLE OF lvc_s_fcat,
gv_variant TYPE disvariant,
gs_fieldcat TYPE lvc_s_fcat,
gs_output TYPE ty_output.
FIELD-SYMBOLS: <fs_output> TYPE ty_output.
*&---------------------------------------------------------------------*
*& Macro 宏定义
*&---------------------------------------------------------------------*
DEFINE mcr_set_catalog.
gs_fieldcat-fieldname = &1. " 字段技术名称
gs_fieldcat-coltext = &2. " 显示名称
gs_fieldcat-scrtext_s = &2. " 显示名称
gs_fieldcat-scrtext_m = &2. " 显示名称
gs_fieldcat-scrtext_l = &2. " 显示名称
gs_fieldcat-ref_table = &3. " 参照表
gs_fieldcat-ref_field = &4. " 参照表字段
gs_fieldcat-qfieldname = &5. " 参考计量单位的字段名称
gs_fieldcat-key = &6. " key 值
gs_fieldcat-edit = &7. " 可编辑
APPEND gs_fieldcat TO gt_fieldcat.
CLEAR gs_fieldcat.
END-OF-DEFINITION.
*&---------------------------------------------------------------------*
*& Selection Screen/选择屏幕
*&---------------------------------------------------------------------*
*&---选择屏幕块
SELECTION-SCREEN BEGIN OF BLOCK blk01 WITH FRAME TITLE TEXT-101.
*&---范围
SELECT-OPTIONS: s_matnr FOR mara-matnr .
SELECTION-SCREEN END OF BLOCK blk01.
*&---------------------------------------------------------------------*
*& Start-of-selection/开始选择屏幕 *
*&---------------------------------------------------------------------*
START-OF-SELECTION.
PERFORM frm_get_data.
*&---------------------------------------------------------------------*
*& End-of-selection/结束选择屏幕(程序结束处理,输出等) *
*&---------------------------------------------------------------------*
END-OF-SELECTION.
PERFORM frm_call_screen.
*&---------------------------------------------------------------------*
*& Form FRM_GET_DATA
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM frm_get_data .
CLEAR: gt_output.
SELECT
makt~matnr,
makt~maktx
FROM makt
WHERE
makt~matnr IN @s_matnr AND
spras = @sy-langu
INTO TABLE @DATA(lt_data).
LOOP AT lt_data INTO DATA(ls_data).
gs_output = CORRESPONDING #( ls_data ).
APPEND gs_output TO gt_output.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form frm_call_screen
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> GS_HEAD
*& --> GS_ITEM
*&---------------------------------------------------------------------*
FORM frm_call_screen .
CALL SCREEN '9000'.
ENDFORM.
*&---------------------------------------------------------------------*
*& Module STATUS_9000 OUTPUT
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
MODULE status_9000 OUTPUT.
PERFORM frm_set_status. " 菜单栏
PERFORM frm_set_fieldcat.
PERFORM frm_set_alv. " ALV
ENDMODULE.
*&---------------------------------------------------------------------*
*& Module USER_COMMAND_9001 INPUT
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
MODULE user_command_9000 INPUT.
*&-- 刷新ALV数据
IF gr_grid IS NOT INITIAL.
gr_grid->check_changed_data( ).
ENDIF.
DATA:lv_result TYPE c.
*&-- 菜单栏事件
CASE sy-ucomm.
WHEN 'ZEXIT'.
LEAVE PROGRAM.
WHEN 'ZBACK'.
LEAVE TO SCREEN '0'.
WHEN OTHERS.
ENDCASE.
ENDMODULE.
*&---------------------------------------------------------------------*
*& Form FRM_SET_FIELDCAT
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM frm_set_fieldcat .
mcr_set_catalog: 'MATNR' TEXT-a01 'MARA' 'MATNR' '' '' '' , " 行号
'MAKTX' TEXT-a02 'MAKT' 'MAKTX' '' '' 'X'. " 工厂
ENDFORM.
*&---------------------------------------------------------------------*
*& Form frm_set_status
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM frm_set_status .
DATA: lt_extab TYPE slis_t_extab.
SET TITLEBAR 'TITLE_9000' WITH TEXT-t01.
SET PF-STATUS 'STATUS_9000' EXCLUDING lt_extab.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form frm_set_alv
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM frm_set_alv .
DATA: ls_style TYPE lvc_s_styl.
IF gr_ctn_alv IS INITIAL.
" 初始化对象
gr_ctn_alv = NEW #( side = cl_gui_docking_container=>dock_at_top extension = 9999 ).
gr_grid = NEW #( i_parent = gr_ctn_alv ).
gr_events = NEW #( ).
" 绑定ALV菜单栏事件
SET HANDLER gr_events->handle_toolbar FOR gr_grid.
SET HANDLER gr_events->handle_command FOR gr_grid.
* SET HANDLER gr_events->handle_data_changed FOR gr_grid.
" 绑定回车事件
* gr_grid->register_edit_event( i_event_id = cl_gui_alv_grid=>mc_evt_enter ).
* gr_grid->register_edit_event( i_event_id = cl_gui_alv_grid=>mc_evt_modified ).
* gr_grid->set_ready_for_input( i_ready_for_input = 1 ).
" 调用ALV
gv_variant = sy-repid.
gr_grid->set_table_for_first_display(
EXPORTING
i_save = 'A'
i_default = 'X'
is_variant = gv_variant
is_layout = VALUE lvc_s_layo( zebra = 'X'
cwidth_opt = 'X'
sel_mode = 'A'
box_fname = 'BOX'
stylefname = 'STYLE'
info_fname = 'COLOR' )
CHANGING
it_outtab = gt_output[]
it_fieldcatalog = gt_fieldcat[] ).
ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form frm_handle_toolbar
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM frm_handle_toolbar CHANGING pr_object TYPE REF TO cl_alv_event_toolbar_set.
DATA: lr_func TYPE RANGE OF stb_button-function.
" OO ALV自带的标准按钮,不需要
lr_func[] = VALUE #( ( sign = 'I' option = 'EQ' low = '&DETAIL' )
( sign = 'I' option = 'EQ' low = '&&SEP2' )
( sign = 'I' option = 'EQ' low = '&CHECK' )
( sign = 'I' option = 'EQ' low = '&REFRESH' )
( sign = 'I' option = 'EQ' low = '&LOCAL&CUT' )
( sign = 'I' option = 'EQ' low = '&LOCAL©' )
( sign = 'I' option = 'EQ' low = '&LOCAL&PASTE' )
( sign = 'I' option = 'EQ' low = '&LOCAL&UNDO' )
( sign = 'I' option = 'EQ' low = '&LOCAL&APPEND' )
( sign = 'I' option = 'EQ' low = '&LOCAL&INSERT_ROW' )
( sign = 'I' option = 'EQ' low = '&LOCAL&DELETE_ROW' )
( sign = 'I' option = 'EQ' low = '&LOCAL©_ROW' )
( sign = 'I' option = 'EQ' low = '&&SEP19' ) ).
" 新增插入删除按钮
pr_object->mt_toolbar = VALUE #( BASE pr_object->mt_toolbar
( function = 'INSERT' icon = icon_insert_row )
( function = 'CHANGE' icon = icon_change text = TEXT-t05 )
( function = 'DELETE' icon = icon_delete_row text = TEXT-t06 ) ).
DELETE pr_object->mt_toolbar WHERE function IN lr_func[].
ENDFORM.
*&---------------------------------------------------------------------*
*& Form frm_handle_command
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM frm_handle_command USING pv_ucomm TYPE sy-ucomm.
DATA: lt_alv TYPE TABLE OF ty_output,
ls_alv TYPE ty_output,
lv_index TYPE i.
gr_grid->get_selected_rows(
IMPORTING
et_row_no = DATA(lt_row_no) ).
gr_grid->check_changed_data( ).
CASE pv_ucomm.
WHEN 'DELETE'.
LOOP AT lt_row_no INTO DATA(ls_row_no).
READ TABLE gt_output ASSIGNING <fs_output> INDEX ls_row_no-row_id.
IF sy-subrc = 0.
ENDIF.
ENDLOOP.
WHEN OTHERS.
RETURN.
ENDCASE.
gr_grid->refresh_table_display( is_stable = VALUE lvc_s_stbl( row = 'X' col = 'X' ) ).
gr_grid->set_selected_rows(
EXPORTING
it_row_no = lt_row_no ).
ENDFORM.
*&---------------------------------------------------------------------*
*& Form frm_handle_data_changed
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> ER_DATA_CHANGED
*&---------------------------------------------------------------------*
FORM frm_handle_data_changed USING pt_data TYPE lvc_t_modi
pv_modify TYPE c.
IF pv_modify IS INITIAL.
RETURN.
ENDIF.
* DATA: lt_modify TYPE lvc_t_modi.
* lt_modify = pt_data.
* DELETE lt_modify WHERE fieldname <> 'NETPR' AND fieldname <> 'MENGE'.
* SORT lt_modify BY row_id.
* DELETE ADJACENT DUPLICATES FROM lt_modify COMPARING row_id.
* LOOP AT lt_modify INTO DATA(ls_modify).
* READ TABLE gt_output ASSIGNING FIELD-SYMBOL(<fs_output>) INDEX ls_modify-row_id.
* IF sy-subrc = 0.
* <fs_output>-amout = <fs_output>-menge * <fs_output>-netpr.
* ENDIF.
* ENDLOOP.
gr_grid->refresh_table_display( is_stable = VALUE lvc_s_stbl( row = 'X' col = 'X' ) ).
ENDFORM.
效果图
参考文档:大佬夜猫君的博客