ABAP实现动态列数周度汇总透视表及ALV报错排查
ABAP动态周维度金额透视实现及ALV参数冲突解决方案
问题根因
报错由字段目录类型混用、内表键定义不规范直接导致:
REUSE_ALV_GRID_DISPLAY函数的IT_FIELDCAT形参要求传入类型为SLIS_T_FIELDCAT_ALV的字段目录,你当前传入的LVC_T_FCAT是面向对象ALV(CL_GUI_ALV_GRID/CL_SALV_TABLE)专用的字段目录格式,二者虽然字段语义高度相似,但属于完全独立的类型定义,直接传递必然触发行类型不兼容错误。- 自定义字段目录内表如果未指定与标准类型一致的表键,会触发第二项表键不匹配报错。
动态列透视正确实现流程
1. 提取动态列标识
首先从源数据中提取去重后的6位周标识,作为动态金额列的生成依据,不需要提前预知周数量:
TYPES: BEGIN OF ty_source, bukrs TYPE bukrs, " 示例固定维度:公司代码 hkont TYPE hkont, " 示例固定维度:会计科目 weekid TYPE char6, " 6位周标识 amount TYPE wrbtr, " 汇总金额 END OF ty_source. DATA: lt_source TYPE STANDARD TABLE OF ty_source, lt_weeks TYPE STANDARD TABLE OF char6. " 此处省略源数据赋值逻辑,生产环境从数据字典表取数即可 " 提取去重周标识 LOOP AT lt_source INTO DATA(ls_source). COLLECT ls_source-weekid INTO lt_weeks. ENDLOOP. SORT lt_weeks.
2. 构建双格式字段目录
由于动态表创建方法和传统函数ALV要求的字段目录格式不同,需要分别构建对应格式的目录,避免类型混用:
DATA: lt_slis_fcat TYPE slis_t_fieldcat_alv, " 给REUSE_ALV_GRID_DISPLAY用 ls_slis_fcat TYPE slis_fieldcat_alv, lt_lvc_fcat TYPE lvc_t_fcat, " 给动态表创建方法用 ls_lvc_fcat TYPE lvc_s_fcat. " 先构建固定维度列 " 公司代码列 ls_slis_fcat-fieldname = 'BUKRS'. ls_slis_fcat-seltext_m = '公司代码'. ls_slis_fcat-ref_table = 'BSEG'. ls_slis_fcat-ref_field = 'BUKRS'. APPEND ls_slis_fcat TO lt_slis_fcat. MOVE-CORRESPONDING ls_slis_fcat TO ls_lvc_fcat. APPEND ls_lvc_fcat TO lt_lvc_fcat. CLEAR: ls_slis_fcat, ls_lvc_fcat. " 会计科目列 ls_slis_fcat-fieldname = 'HKONT'. ls_slis_fcat-seltext_m = '会计科目'. ls_slis_fcat-ref_table = 'BSEG'. ls_slis_fcat-ref_field = 'HKONT'. APPEND ls_slis_fcat TO lt_slis_fcat. MOVE-CORRESPONDING ls_slis_fcat TO ls_lvc_fcat. APPEND ls_lvc_fcat TO lt_lvc_fcat. CLEAR: ls_slis_fcat, ls_lvc_fcat. " 循环周标识构建动态金额列 LOOP AT lt_weeks INTO DATA(lv_week). DATA(lv_fieldname) = |WEEK_{ lv_week }|. " 字段名格式:WEEK_YYYYWW " SLIS格式目录 ls_slis_fcat-fieldname = lv_fieldname. ls_slis_fcat-seltext_m = |{ lv_week }周金额|. ls_slis_fcat-datatype = 'CURR'. ls_slis_fcat-intlen = 15. ls_slis_fcat-decimals = 2. APPEND ls_slis_fcat TO lt_slis_fcat. " LVC格式目录 MOVE-CORRESPONDING ls_slis_fcat TO ls_lvc_fcat. APPEND ls_lvc_fcat TO lt_lvc_fcat. CLEAR: ls_slis_fcat, ls_lvc_fcat. ENDLOOP.
注意:动态拼接的字段名必须为全大写,ABAP组件名称大小写敏感,小写会导致后续字段寻址失败。
3. 生成动态内表并完成汇总赋值
DATA: lo_dyn_table TYPE REF TO data, lo_dyn_wa TYPE REF TO data. FIELD-SYMBOLS: <ft_dyn> TYPE STANDARD TABLE, <fs_dyn> TYPE any, <fv_amt> TYPE wrbtr. " 调用方法生成动态内表 CALL METHOD cl_alv_table_create=>create_dynamic_table EXPORTING it_fieldcatalog = lt_lvc_fcat IMPORTING ep_table = lo_dyn_table. ASSIGN lo_dyn_table->* TO <ft_dyn>. CREATE DATA lo_dyn_wa LIKE LINE OF <ft_dyn>. ASSIGN lo_dyn_wa->* TO <fs_dyn>. " 按维度汇总金额 LOOP AT lt_source INTO ls_source. " 先匹配固定维度对应的动态表行,不存在则新增,可通过COLLECT语法自动汇总 ASSIGN COMPONENT 'BUKRS' OF STRUCTURE <fs_dyn> TO FIELD-SYMBOL(<fv_bukrs>). <fv_bukrs> = ls_source-bukrs. ASSIGN COMPONENT 'HKONT' OF STRUCTURE <fs_dyn> TO FIELD-SYMBOL(<fv_hkont>). <fv_hkont> = ls_source-hkont. " 给对应周的金额字段赋值累加 lv_fieldname = |WEEK_{ ls_source-weekid }|. ASSIGN COMPONENT lv_fieldname OF STRUCTURE <fs_dyn> TO <fv_amt>. IF <fv_amt> IS ASSIGNED. <fv_amt> = <fv_amt> + ls_source-amount. ENDIF. COLLECT <fs_dyn> INTO <ft_dyn>. CLEAR <fs_dyn>. ENDLOOP.
4. ALV展示
调用函数时传入SLIS格式的字段目录即可解决参数冲突问题:
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY' EXPORTING it_fieldcat = lt_slis_fcat " 必须传SLIS类型的字段目录,不能传LVC格式 TABLES t_outtab = <ft_dyn> EXCEPTIONS program_error = 1 OTHERS = 2.
优化建议:如果不需要兼容旧开发模式,可直接全程使用
CL_GUI_ALV_GRID类实现ALV展示,字段目录统一用LVC_T_FCAT格式,省去双目录转换的步骤,代码维护性更高。
内容的提问来源于stack exchange,提问作者user10149299
相关产品推荐
相关产品推荐

