前言
在SAP官方社区上一同学发帖求助,SALV状态栏上的"ABC 分析"按钮点击之后程序报错,如何解决?本文将一探究竟,深入分析原因,并给出解决方案。
问题还原
程序代码如下:
*&---------------------------------------------------------------------**& Report zyxstest01*&---------------------------------------------------------------------**&*&---------------------------------------------------------------------*REPORT zyxstest01."Declared Table TypeTYPES: BEGIN OF ty_data, lifnr TYPE ekko-lifnr, bedat TYPE ekko-bedat, ebeln TYPE ekko-ebeln, netwr TYPE ekpo-netwr, name1 TYPE lfa1-name1, END OF ty_data.
"For ALVDATA: gt_data TYPE TABLE OF ty_data, gs_data TYPE ty_data.
START-OF-SELECTION. SELECT a~lifnr,a~bedat,a~ebeln,b~netwr,c~name1 FROM ekko AS a JOIN ekpo AS b ON b~ebeln = a~ebeln JOIN lfa1 AS c ON c~lifnr = a~lifnr UP TO 100 ROWS INTO CORRESPONDING FIELDS OF TABLE @gt_data.
PERFORM display.
*&---------------------------------------------------------------------**& Form display*&---------------------------------------------------------------------**& text*&---------------------------------------------------------------------**& --> p1 text*& <-- p2 text*&---------------------------------------------------------------------*FORM display . DATA: go_salv TYPE REF TO cl_salv_table, lo_gr_functions TYPE REF TO cl_salv_functions_list.
DATA: lo_column TYPE REF TO cl_salv_column_table.
*Create alv object. TRY. CALL METHOD cl_salv_table=>factory IMPORTING r_salv_table = go_salv CHANGING t_table = gt_data.
CATCH cx_salv_msg. ENDTRY.* Enabling the ABC Analysis go_salv->set_screen_status( pfstatus = 'STANDARD_FULLSCREEN' report = 'SAPLSLVC_FULLSCREEN' ).
* 显示SALV所有标准功能. DATA(lo_functions) = go_salv->get_functions( ). lo_functions->set_all( abap_true ).
* 获取所有列 DATA(lo_columns) = go_salv->get_columns( ).* 设置列宽自适应 lo_columns->set_optimize( abap_true ).*设置斑马线 DATA(lo_dspset) = go_salv->get_display_settings( ). lo_dspset->set_striped_pattern( abap_true ).DATA: lr_layout TYPE REF TO cl_salv_layout, ls_key TYPE salv_s_layout_key.
lr_layout = go_salv->get_layout( ). ls_key-report = sy-repid. ls_key-handle = '1000'. lr_layout->set_key( ls_key ). lr_layout->set_default( abap_true ). lr_layout->set_save_restriction( if_salv_c_layout=>restrict_none ).• Display alv go_salv->display( ).
ENDFORM.执行后选中"订单净值"这一列,然后点击"ABC 分析"按钮后程序报错如下
问题分析
对报错的消息号设置断点,然后DEBUG,点击"ABC 分析"按钮后,程序停在了如下 634行 位置。
l_message又是在622行动态生成报表时,产生了错误,点开lt_source后,很清楚的看出问题了。
数据定义时,"-"前没有数据库表名或结构名,导致动态生成报表时报错。继续往上分析,在381行最终发现了问题出现的端倪了。
ls_fieldcat的参考字段REF_FIELDNAME有值,但是参考表REF_TABNAME却是空的,所以最终就导致了最终的错误。
问题处理
因为该示例用了我们自定义的结构,导致SALV在处理时,没有取到对应的参考表。
TYPES: BEGIN OF ty_data, lifnr TYPE ekko-lifnr, bedat TYPE ekko-bedat, ebeln TYPE ekko-ebeln, netwr TYPE ekpo-netwr, name1 TYPE lfa1-name1, END OF ty_data.设置参考表的方法在类cl_salv_column_list的set_ddic_reference方法中。于是在程序display之前增加以下代码,最终问题解决
DATA: lo_column_list TYPE REF TO cl_salv_column_list. TRY. lo_column_list ?= lo_columns->get_column( 'LIFNR' ). lo_column_list->set_ddic_reference( value = VALUE #( table = 'EKKO' field = 'LIFNR' ) ). lo_column_list ?= lo_columns->get_column( 'EBELN' ). lo_column_list->set_ddic_reference( value = VALUE #( table = 'EKKO' field = 'EBELN' ) ). lo_column_list ?= lo_columns->get_column( 'BEDAT' ). lo_column_list->set_ddic_reference( value = VALUE #( table = 'EKKO' field = 'BEDAT' ) ). lo_column_list ?= lo_columns->get_column( 'NETWR' ). lo_column_list->set_ddic_reference( value = VALUE #( table = 'EKPO' field = 'NETWR' ) ). lo_column_list ?= lo_columns->get_column( 'NAME1' ). lo_column_list->set_ddic_reference( value = VALUE #( table = 'LFA1' field = 'NAME1' ) ). CATCH cx_salv_not_found. "#EC NO_HANDLER ENDTRY.问题延伸
为什么使用标准的 sflight表,对数据进行"ABC 分析"就不报错呢?
对两种定义内表方式的报表进行DEBUG发现,在类CL_SALV_DATA_DESCR的GET_TABLE_DESCRIPTOR_INFO方法中会获取内表的字段定义,如果内表是参照的数据库表或结构,满足r_structdescr->is_ddic_type(
) =
abap_true条件,字段的定义中ref_tabname就会自动的赋值为内表参考的数据库表或结构;如果内表参照的是程序中自定义的结构,并且没有显式的指定ref_tabname的话,这个字段就是空的,所以进行"ABC
分析"的时候就会报错。