原文地址:http://www.erp100.com/93236/viewspace-6764346.html
作SAP开发人员,写ALV报表是经常的事情,用的比较多的主要是直接用 系统提供的FM来处理,例如:
REUSE_ALV_LIST_DISPLAY
REUSE_ALV_FIELDCATALOG_MERGE
REUSE_ALV_LIST_DISPLAY
REUSE_ALV_HIERSEQ_LIST_DISPLAY
既然SAP提供了ALV Object Model 用面向对象技术对ALV进行封装,提供相应的工具和方式,当然从效率上和技术支持方面考虑,在做ALV开发时首先想到的是用这种技术处理所有的ALV报表,其主要有这三种类型以及对应的类:
· Simple, two-dimensional table CL_SALV_TABLE
· Hierarchical-sequential list CL_SALV_HIERSEQ_TABLE
· Tree structure CL_SALV_TREE
其中:CL_SALV_TABLE 又可以实现三种不同的显示模式(划线模式LIST,全屏模式FULL,UI模式GIRD)
ABAP的OO其主要借鉴C++,Java的面向象的思想,作为商业智能语言的OO初次看上去还是比较别扭.不过存在总有其理由,学会总是一门技能。
通过借鉴网上一些朋友的例子,我用了半天的时间把上面所有的实现集成到一个程序里了。以便好做收藏,下面是源程序(大部分地方都有注解,没有的地方,调试下也应该能明白功能):
*&---------------------------------------------------------------------*
*& Report ZMYTEST015
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*
REPORT ZMYTEST015.
*变量定义
TYPES ty_spfli TYPE spfli OCCURS 0.
DATA: gr_table TYPE REF TO cl_salv_table.
data: ok_code like sy-ucomm.
*FULL_ALV还用到下面的类
data: gr_functions type ref to cl_salv_functions."按钮函数类
data: gr_display type ref to cl_salv_display_settings."表头显示类
data: gr_columns type ref to cl_salv_columns_table. "列及颜色类
data: gr_column type ref to cl_salv_column_table.
data: color type lvc_s_colo.
data: gr_sorts type ref to cl_salv_sorts. "排序类
data: gr_agg type ref to cl_salv_aggregations."汇总类
data: gr_filter type ref to cl_salv_filters. "过滤类
data: gr_layout type ref to cl_salv_layout. "布局类
data: key type salv_s_layout_key.
******************************************************************
"层次ALV声明如下
types: begin of t_scarr.
TYPES: l_line TYPE int4.
include structure scarr.
types: expcol type c.
types: end of t_scarr.
data: gh_table type ref to cl_salv_hierseq_table.
data: gh_functions type ref to cl_salv_functions.
data: gh_columns type ref to cl_salv_columns_hierseq.
data: gh_column type ref to cl_salv_column_hierseq.
data: gh_level type ref to cl_salv_hierseq_level.
data: gh_sorts type ref to cl_salv_sorts.
DATA: gh_aggregations TYPE REF TO cl_salv_aggregations.
"使用内表
data: iscarr type table of t_scarr.
DATA: wscarr TYPE t_scarr.
data: isflight type table of sflight.
data: ibinding type salv_t_hierseq_binding.
data: xbinding type salv_s_hierseq_binding.
******************************************************************
*树形ALV声明如下
TYPES: BEGIN OF ty_player,
land TYPE landx,
* the term position means the position of a football player on the field
posi TYPE c LENGTH 10,
name TYPE emnam,
END OF ty_player.
TYPES: tty_player TYPE TABLE OF ty_player.
* variables for handling of data
DATA: gt_player TYPE tty_player,
gt_player2 TYPE tty_player,
gw_player TYPE ty_player.
* variables for handling of the tree
DATA: gr_tree TYPE REF TO cl_salv_tree, " ALV-tree
settings type ref to cl_salv_tree_settings, "basic settings
nodes TYPE REF TO cl_salv_nodes, " collection of nodes
node TYPE REF TO cl_salv_node, " a single nodes
rootkey TYPE salv_de_node_key, " key of root node
countrykey TYPE salv_de_node_key, " key of country node
positionkey TYPE salv_de_node_key. " key of position node
DATA: gv_text TYPE lvc_value.
******************************************************************
*选择屏幕设计
SELECTION-SCREEN BEGIN OF BLOCK blk WITH FRAME.
PARAMETERS: p_full RADIOBUTTON GROUP rg,"
p_list RADIOBUTTON GROUP rg,
p_grid RADIOBUTTON GROUP rg,
p_hier RADIOBUTTON GROUP rg,"层次结构
p_tree RADIOBUTTON GROUP rg."树结构
SELECTION-SCREEN END OF BLOCK blk.
*----------------------------------------------------------------------*
* CLASS lcl_alv DEFINITION
*----------------------------------------------------------------------*
* ALV操作类(定义)
*----------------------------------------------------------------------*
CLASS lcl_alv DEFINITION.
PUBLIC SECTION.
METHODS: getdata "取得要显示的数据
RETURNING value(lt_tab) TYPE ty_spfli,
alv_full "全屏Grid列表处理方法
IMPORTING value(lt_tab) TYPE ty_spfli,
alv_list "普通List处理方法
IMPORTING value(lt_tab) TYPE ty_spfli,
alv_grid "在自定义屏幕上显示的列表
IMPORTING value(lt_tab) TYPE ty_spfli,
alv_hier, “层次AVL的方法
alv_tree, “树状ALV的方法
main. "主方法
ENDCLASS. "lcl_alv DEFINITION
*---------------------------------------------------------------------*
* CLASS lcl_alv IMPLEMENTATION
*----------------------------------------------------------------------*
* ALV操作类(实现)
*----------------------------------------------------------------------*
CLASS lcl_alv IMPLEMENTATION.
*取得要显示的数据
METHOD getdata.
SELECT * INTO TABLE lt_tab FROM spfli.
ENDMETHOD. "getdata
*输出全屏网格列表的方法
METHOD alv_full.
"创建实例
TRY.
cl_salv_table=>factory(
IMPORTING
r_salv_table = gr_table
CHANGING
t_table = lt_tab
).
CATCH cx_salv_msg.
ENDTRY.
*full_alv一些参数的设置
gr_functions = gr_table->get_functions( ).
gr_functions->set_all( abap_true ). "显示按钮函数
gr_display = gr_table->get_display_settings( ).
gr_display->set_striped_pattern( cl_salv_display_settings=>true ).
gr_display->set_list_header( 'This is the heading' ). "设置表头文字
*列及颜色控制
gr_columns = gr_table->get_columns( ). "获得一个TABLE的列对象
gr_column ?= gr_columns->get_column( 'CITYTO' ).
gr_column->set_long_text( 'This is long text' ).
*CITYTO列头显示的是下面这个
gr_column->set_medium_text( 'This is med text' ).
gr_column->set_short_text( 'This is sh' ).
gr_column ?= gr_columns->get_column( 'CITYFROM' ).
color-col = '6'.
color-int = '1'.
color-inv = '0'.
gr_column->set_color( color )."给CITYFROM设置颜色
* CITYTO升序排列
gr_sorts = gr_table->get_sorts( ).
* gr_sorts->ADD_SORT( 'CITYTO' ). "要用下面的这个ADD_SORT则这个要注释掉
*按列CITYTO小计列DISTANCE
gr_sorts->add_sort( columnname = 'CITYTO' subtotal = abap_true ).
gr_agg = gr_table->get_aggregations( ).
gr_agg->add_aggregation( 'DISTANCE' ).
*过滤显示列:CARRID 中 为 LH的记录
gr_filter = gr_table->get_filters( ).
gr_filter->add_filter( columnname = 'CARRID' low = 'LH' ).
*布局设置
gr_layout = gr_table->get_layout( ).
key-report = sy-repid.
gr_layout->set_key( key ).
gr_layout->set_save_restriction( cl_salv_layout=>restrict_none ).
"显示列表
gr_table->display( ).
ENDMETHOD. "alv_full
*输出全屏普通列表的方法
METHOD alv_list.
"创建实例
TRY.
cl_salv_table=>factory(
EXPORTING
list_display = 'X'
IMPORTING
r_salv_table = gr_table
CHANGING
t_table = lt_tab
).
CATCH cx_salv_msg.
ENDTRY.
"显示列表
gr_table->display( ).
ENDMETHOD. "alv_list
*输出在自定义屏幕上的列表
METHOD alv_grid.
CALL SCREEN '0100'.
ENDMETHOD. "alv_grid
*层次ALV的输出
METHOD alv_hier.
select * into CORRESPONDING FIELDS OF TABLE iscarr from scarr.
LOOP AT iscarr INTO wscarr.
wscarr-l_line = 1.
MODIFY iscarr FROM wscarr.
ENDLOOP.
select * into CORRESPONDING FIELDS OF TABLE isflight from sflight.
xbinding-master = 'CARRID'.
xbinding-slave = 'CARRID'.
append xbinding to ibinding.
cl_salv_hierseq_table=>factory(
exporting
t_binding_level1_level2 = ibinding
importing
r_hierseq = gh_table
changing
t_table_level1 = iscarr
t_table_level2 = isflight ).
gh_functions = gh_table->get_functions( ).
gh_functions->set_all( abap_true ).
*增加下面的代码,在Header column行就会出现“+”或“ -”
gh_columns = gh_table->get_columns( level = 1 ).
gh_columns->set_expand_column( 'EXPCOL' ).
gh_level = gh_table->get_level( 1 ).
gh_level->set_items_expanded( 'X' ).
*通过个类可以对slave item的航班日期进行降序:
gh_sorts = gh_table->get_Sorts( level = '2' ).
gh_sorts->add_sort( columnname = 'FLDATE'
sequence = if_salv_c_sort=>sort_down ).
"Modify the name
gh_column ?= gh_columns->get_column( 'CARRID').
gh_column->set_medium_text( 'Air Code' ).
gh_column->set_output_length( '8' ).
gh_aggregations = gh_table->get_aggregations( 1 ).
" Total for header item
gh_aggregations->add_aggregation( columnname = 'L_LINE' ).
" Total for slave item
gh_aggregations = gh_table->get_aggregations( 2 ).
gh_aggregations->add_aggregation( columnname = 'SEATSMAX' ).
gh_aggregations->add_aggregation( columnname = 'SEATSOCC' ).
gh_table->display( ).
ENDMETHOD. "alv_grid
"TREE_ALV处理方法
METHOD alv_tree.
CALL METHOD cl_salv_tree=>factory
IMPORTING
r_salv_tree = gr_tree
CHANGING
t_table = gt_player2.
* define 1st column (to display the structure)
settings = gr_tree->get_tree_settings( ).
settings->SET_HIERARCHY_SIZE( 30 ).
* fill data table with values
PERFORM. fill_table CHANGING gt_player.
* create object for the complete structure
*(attributes common to all nodes)
nodes = gr_tree->get_nodes( ).
* create root node
node = nodes->add_node( related_node = rootkey
relationship =
cl_gui_column_tree=>relat_first_child
text = 'Football').
* nodes are identifies by key, create key for root node
rootkey = node->get_key( ).
* construct tree structure
LOOP AT gt_player INTO gw_player.
AT NEW land.
" append node for country to the root node
gv_text = gw_player-land.
node = nodes->add_node( related_node = rootkey
relationship =
cl_gui_column_tree=>relat_last_child
text = gv_text ).
countrykey = node->get_key( ).
ENDAT.
AT NEW posi.
" append node for position to the current country node
gv_text = gw_player-posi.
node = nodes->add_node( related_node = countrykey
relationship =
cl_gui_column_tree=>relat_last_child
text = gv_text ).
positionkey = node->get_key( ).
ENDAT.
" append node for player to the current position node
" the actual data are bound to this node
node = nodes->add_node( related_node = positionkey
data_row = gw_player " !
relationship =
cl_gui_column_tree=>relat_last_child ).
ENDLOOP.
* display tree
gr_tree->display( ).
endmethod. "alv_tree
*主方法,整合数据
METHOD main.
DATA: lt_tab TYPE TABLE OF spfli.
"判断选择屏幕的选择条件调用不同的方法
CASE 'X'.
WHEN p_full.
"取得要显示的数据
lt_tab = me->getdata( ).
me->alv_full( lt_tab ).
WHEN p_list.
"取得要显示的数据
lt_tab = me->getdata( ).
me->alv_list( lt_tab ).
WHEN p_grid.
"取得要显示的数据
lt_tab = me->getdata( ).
me->alv_grid( lt_tab ).
WHEN p_hier.
me->alv_hier( ).
WHEN p_tree.
me->alv_tree( ).
ENDCASE.
ENDMETHOD. "main
ENDCLASS. "lcl_alv IMPLEMENTATION
*----------------------------------------------------------------------*
* MODULE status_0100
*----------------------------------------------------------------------*
* PBO 屏幕输出前执行
*----------------------------------------------------------------------*
MODULE status_0100 OUTPUT.
set pf-status 'ZSTANDARD'.
"定义变量
DATA: lr_container TYPE REF TO cl_gui_custom_container,
lr_alv2 TYPE REF TO lcl_alv,
lt_tab TYPE TABLE OF spfli.
"创建容器实例
IF cl_salv_table=>is_offline( ) = ''.
CREATE OBJECT lr_container
EXPORTING
container_name = 'CONTAINER'.
ENDIF.
"创建类LCL_ALV实例
CREATE OBJECT lr_alv2.
"取得列表数据
lt_tab = lr_alv2->getdata( ).
"创建ALV实例
TRY.
cl_salv_table=>factory(
EXPORTING
r_container = lr_container
container_name = 'CONTAINER'
IMPORTING
r_salv_table = gr_table
CHANGING
t_table = lt_tab
).
CATCH cx_salv_msg.
ENDTRY.
"显示ALV列表
gr_table->display( ).
"释放内存
FREE lt_tab.
ENDMODULE. "status_0100
*----------------------------------------------------------------------*
* MODULE user_command_0100
*----------------------------------------------------------------------*
* PAI 屏幕输出后的动作
*----------------------------------------------------------------------*
MODULE user_command_0100 INPUT.
case ok_code.
when 'EXIT' or 'BACK' or 'UP' or 'CANCEL'.
leave to screen 0.
endcase.
ENDMODULE. "user_command_0100
*报表执行
START-OF-SELECTION.
DATA lr_alv TYPE REF TO lcl_alv.
CREATE OBJECT lr_alv.
lr_alv->main( ).
*&---------------------------------------------------------------------*
*& Form fill_table
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* <--P_GT_PLAYER text
*----------------------------------------------------------------------*
FORM. fill_table CHANGING pt_player TYPE tty_player.
DATA: lw_player TYPE ty_player.
SELECT SINGLE landx FROM t005t INTO lw_player-land
WHERE spras = sy-langu AND land1 = 'DE'.
lw_player-posi = 'Defender'.
lw_player-name = 'Philip Lahm'.
APPEND lw_player TO pt_player. CLEAR lw_player.
SELECT SINGLE landx FROM t005t INTO lw_player-land
WHERE spras = sy-langu AND land1 = 'DE'.
lw_player-posi = 'Defender'.
lw_player-name = 'Per Mertesacker'.
APPEND lw_player TO pt_player. CLEAR lw_player.
SELECT SINGLE landx FROM t005t INTO lw_player-land
WHERE spras = sy-langu AND land1 = 'FR'.
lw_player-posi = 'Midfielder'.
lw_player-name = 'Franck Ribery'.
APPEND lw_player TO pt_player. CLEAR lw_player.
SELECT SINGLE landx FROM t005t INTO lw_player-land
WHERE spras = sy-langu AND land1 = 'FR'.
lw_player-posi = 'Striker'.
lw_player-name = 'Thierry Henry'.
APPEND lw_player TO pt_player. CLEAR lw_player.
ENDFORM. " fill_table