abap报表中,ALV是使用最频繁的输出方式,过滤/合计/小计等功能强大,与excel比也不逊色.
但ALV有个缺点就是没有统计条目数的功能,有时用户在核对数据时想查看总条目数或查看过滤后的条目数等,苦于没有计数功能,只好先导出到excel再进行统计。虽然操作不复杂,但是alv如果数据量很大时,导出excel也会比较慢,而且这样的方式总归增加的操作的步骤。
于是考虑常用的计数功能,做了一个增强类,在标准OO ALV的基础上增加了一个“条目数统计”的功能,由于中间涉及动态内表,因此使用了之前做一个一个动态内表创建的类,见abap系列-动态创建内表或结构,最终效果如下图
计数内容如下:
总条目数:输出的所有条目数
选中行数:alv中被选中行的条目数
所选列不重复条目数:选中列的不重复条目数
筛选结果条目数:使用过滤器后显示的记录的条目数
使用很简单,可以直接将已经创建好的alv示例传入方法后,原alv即挂载了该功能。
测试主程序代码:
*&---------------------------------------------------------------------*
*& Report ZTEST
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
report ztest.
data: o_alv type ref to cl_gui_alv_grid.
parameters:
p_exp1 type c radiobutton group bt1 default 'X',
p_exp2 type c radiobutton group bt1.
start-of-selection.
write:''.
select * into table @data(lt_mard) from mard .
case abap_true.
when p_exp1.
perform alv_example1.
when p_exp2.
perform alv_example2.
endcase.
"使用已经存在的ALV对象
form alv_example1.
o_alv = new cl_gui_alv_grid( i_parent = cl_gui_custom_container=>screen0 ).
zcl_alv_ext_static=>util( io_alv = o_alv ).
o_alv->set_table_for_first_display(
exporting
i_structure_name = 'MARD'
changing
it_outtab = lt_mard ).
endform.
"使用扩展类自动创建alv对象
form alv_example2.
o_alv = zcl_alv_ext_static=>util( ).
o_alv->set_table_for_first_display(
exporting
i_structure_name = 'MARD'
changing
it_outtab = lt_mard ).
endform.
扩展类代码
class ZCL_ALV_EXT_STATIC definition
public
final
create public .
public section.
interfaces IF_ALV_RM_GRID_FRIEND .
types:
ty_fcode type table of string .
data MO_ALV type ref to CL_GUI_ALV_GRID .
data MO_DATA type ref to DATA .
constants MC_STATIC type CHAR40 value '&STATIC' ##NO_TEXT.
class-methods UTIL
importing
!I_PARENT type ref to CL_GUI_CONTAINER optional
value(I_NAME) type STRING optional
!IO_ALV type ref to CL_GUI_ALV_GRID optional
returning
value(RO_ALV) type ref to CL_GUI_ALV_GRID .
protected section.
private section.
methods ADD_BUTTON
for event TOOLBAR of CL_GUI_ALV_GRID
importing
!E_OBJECT
!E_INTERACTIVE .
methods AT_USER_COMMAND
for event USER_COMMAND of CL_GUI_ALV_GRID
importing
!E_UCOMM .
methods TOTAL_STATIC
importing
!IT_TAB type ANY TABLE
returning
value(R_COUNTS) type I .
methods SELECTED_COL_STATIC
importing
!IT_TAB type STANDARD TABLE
returning
value(R_COUNTS) type I .
methods FILTERD_STAIC
importing
!IT_TAB type ANY TABLE
returning
value(R_COUNTS) type I .
methods SEL_ROW_STATIC
importing
!IT_TAB type STANDARD TABLE
returning
value(R_COUNTS) type I .
ENDCLASS.
CLASS ZCL_ALV_EXT_STATIC IMPLEMENTATION.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Private Method ZCL_ALV_EXT_STATIC->ADD_BUTTON
* +-------------------------------------------------------------------------------------------------+
* | [--->] E_OBJECT LIKE
* | [--->] E_INTERACTIVE LIKE
* +--------------------------------------------------------------------------------------</SIGNATURE>
method add_button.
e_object->mt_toolbar = value #( base e_object->mt_toolbar
( function = mc_static icon = icon_calculation text = '条目数统计' butn_type = '0' )
).
endmethod.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Private Method ZCL_ALV_EXT_STATIC->AT_USER_COMMAND
* +-------------------------------------------------------------------------------------------------+
* | [--->] E_UCOMM LIKE
* +--------------------------------------------------------------------------------------</SIGNATURE>
method AT_USER_COMMAND.
field-symbols:<lt_otab> type any table.
data:lt_cols type lvc_t_col.
check e_ucomm = '&STATIC'.
assign mo_alv->mt_outtab->* to <lt_otab>.
data(lv_totals) = lines( <lt_otab> ).
data(total_static) = total_static( <lt_otab> ).
data(selected_col_static) = selected_col_static( <lt_otab> ).
data(filterd_staic) = filterd_staic( <lt_otab> ).
data(sel_row_static) = sel_row_static( <lt_otab> ).
cl_demo_output=>display_text( |总条目数:{ total_static }\n | &&
|选中行数:{ sel_row_static }\n | &&
|所选列不重复条目数:{ selected_col_static }\n | &&
|筛选结果条目数:{ filterd_staic }| ).
endmethod.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Private Method ZCL_ALV_EXT_STATIC->FILTERD_STAIC
* +-------------------------------------------------------------------------------------------------+
* | [--->] IT_TAB TYPE ANY TABLE
* | [<-()] R_COUNTS TYPE I
* +--------------------------------------------------------------------------------------</SIGNATURE>
method FILTERD_STAIC.
mo_alv->GET_FILTERED_ENTRIES( importing ET_FILTERED_ENTRIES = data(lt_filter_entries) ).
r_counts = lines( lt_filter_entries ).
endmethod.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Private Method ZCL_ALV_EXT_STATIC->SELECTED_COL_STATIC
* +-------------------------------------------------------------------------------------------------+
* | [--->] IT_TAB TYPE STANDARD TABLE
* | [<-()] R_COUNTS TYPE I
* +--------------------------------------------------------------------------------------</SIGNATURE>
method SELECTED_COL_STATIC.
if it_tab is not initial.
mo_alv->get_selected_columns( importing et_index_columns = data(lt_cols) ).
check lt_cols is not initial.
loop at it_tab assigning field-symbol(<lw_tab>).
exit.
endloop.
loop at lt_cols into data(ls_col).
assign component ls_col-fieldname of structure <lw_tab> to field-symbol(<lv_fn>).
zcl_dynamic_obj=>add_comp_by_data( p_data = <lv_fn> iv_name = ls_col-fieldname ).
endloop.
data(lt_com) = zcl_dynamic_obj=>t_comp.
data(ls_selected_data) = zcl_dynamic_obj=>create_struct( ) .
assign ls_selected_data->* to field-symbol(<ls_dyn_tab>).
zcl_dynamic_obj=>t_comp = lt_com.
data(lt_selected_data) = zcl_dynamic_obj=>create_table( ).
field-symbols:<lt_dyn_tab> type standard table.
assign lt_selected_data->* to <lt_dyn_tab>.
loop at it_tab assigning <lw_tab>.
move-corresponding <lw_tab> to <ls_dyn_tab>.
append <ls_dyn_tab> to <lt_dyn_tab>.
clear <ls_dyn_tab>.
endloop.
sort <lt_dyn_tab> .
delete adjacent duplicates from <lt_dyn_tab> comparing all fields.
r_counts = lines( <lt_dyn_tab> ).
else.
r_counts = 0.
endif.
endmethod.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Private Method ZCL_ALV_EXT_STATIC->SEL_ROW_STATIC
* +-------------------------------------------------------------------------------------------------+
* | [--->] IT_TAB TYPE STANDARD TABLE
* | [<-()] R_COUNTS TYPE I
* +--------------------------------------------------------------------------------------</SIGNATURE>
method SEL_ROW_STATIC.
mo_alv->get_selected_rows( importing et_row_no = data(lt_rows) ).
r_counts = lines( lt_rows ).
endmethod.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Private Method ZCL_ALV_EXT_STATIC->TOTAL_STATIC
* +-------------------------------------------------------------------------------------------------+
* | [--->] IT_TAB TYPE ANY TABLE
* | [<-()] R_COUNTS TYPE I
* +--------------------------------------------------------------------------------------</SIGNATURE>
method TOTAL_STATIC.
r_counts = lines( it_tab ).
endmethod.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Public Method ZCL_ALV_EXT_STATIC=>UTIL
* +-------------------------------------------------------------------------------------------------+
* | [--->] I_PARENT TYPE REF TO CL_GUI_CONTAINER(optional)
* | [--->] I_NAME TYPE STRING(optional)
* | [--->] IO_ALV TYPE REF TO CL_GUI_ALV_GRID(optional)
* | [<-()] RO_ALV TYPE REF TO CL_GUI_ALV_GRID
* +--------------------------------------------------------------------------------------</SIGNATURE>
method util.
* super->constructor( I_PARENT ).
data(lo_alv_util) = new zcl_alv_ext_static( ).
if io_alv is supplied.
lo_alv_util->mo_alv = io_alv.
else.
lo_alv_util->mo_alv = new cl_gui_alv_grid( i_parent = cl_gui_custom_container=>screen0 ).
endif.
ro_alv = lo_alv_util->mo_alv.
set handler: lo_alv_util->add_button for lo_alv_util->mo_alv,
lo_alv_util->at_user_command for lo_alv_util->mo_alv .
endmethod.
ENDCLASS.