ABAP常规报表开发模板
时间: 2025-07-14 10:47:30 浏览: 8
# ABAP常规报表开发模板
以下是一个完整的ABAP常规报表开发模板,包含标准的选择屏幕、数据获取、数据处理和ALV展示等核心组件,适用于大多数业务报表开发场景。
## 1. 报表基本结构
```ABAP
REPORT z_standard_report MESSAGE-ID zm.
* 定义数据结构
TYPES: BEGIN OF ty_report_data,
bukrs TYPE bukrs, "公司代码
gjahr TYPE gjahr, "会计年度
belnr TYPE belnr_d, "凭证号
budat TYPE budat, "凭证日期
blart TYPE blart, "凭证类型
bldat TYPE bldat, "过账日期
monat TYPE monat, "会计期间
waers TYPE waers, "货币
dmbtr TYPE dmbtr, "金额
shkzg TYPE shkzg, "借贷标识
hkont TYPE hkont, "科目号
txt50 TYPE txt50, "科目描述
kostl TYPE kostl, "成本中心
prctr TYPE prctr, "利润中心
aufnr TYPE aufnr, "生产订单
username TYPE sy-uname, "创建人
erdat TYPE erdat, "创建日期
erzet TYPE erzet, "创建时间
END OF ty_report_data.
* 定义内表和工作区
DATA: gt_report_data TYPE TABLE OF ty_report_data,
gs_report_data TYPE ty_report_data.
* 定义选择屏幕参数
SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE TEXT-001.
SELECT-OPTIONS: s_bukrs FOR gs_report_data-bukrs OBLIGATORY,
s_gjahr FOR gs_report_data-gjahr OBLIGATORY,
s_monat FOR gs_report_data-monat,
s_blart FOR gs_report_data-blart,
s_hkont FOR gs_report_data-hkont.
PARAMETERS: p_date TYPE budat OBLIGATORY DEFAULT sy-datum.
SELECTION-SCREEN END OF BLOCK b1.
SELECTION-SCREEN BEGIN OF BLOCK b2 WITH FRAME TITLE TEXT-002.
PARAMETERS: p_sum TYPE c AS CHECKBOX DEFAULT 'X', "汇总显示
p_det TYPE c AS CHECKBOX, "明细显示
p_excel TYPE c AS CHECKBOX DEFAULT 'X'. "导出Excel
SELECTION-SCREEN END OF BLOCK b2.
INITIALIZATION.
TEXT-001 = '筛选条件'.
TEXT-002 = '显示选项'.
p_date = sy-datum.
```
## 2. 数据获取逻辑
```ABAP
START-OF-SELECTION.
PERFORM get_data.
PERFORM process_data.
IF p_excel = 'X'.
PERFORM export_to_excel.
ELSE.
PERFORM display_alv.
ENDIF.
* 获取数据
FORM get_data.
" 清空内表
CLEAR gt_report_data.
" 从BKPF获取凭证头信息
SELECT a~bukrs a~gjahr a~belnr a~budat a~blart a~bldat a~monat a~waers
b~dmbtr b~shkzg b~hkont c~txt50
FROM bkpf AS a
INNER JOIN bseg AS b ON a~bukrs = b~bukrs AND a~gjahr = b~gjahr AND a~belnr = b~belnr
LEFT OUTER JOIN skat AS c ON b~hkont = c~saknr AND c~ktopl = '1000' AND c~spras = '1'
INTO CORRESPONDING FIELDS OF TABLE @gt_report_data
WHERE a~bukrs IN @s_bukrs
AND a~gjahr IN @s_gjahr
AND a~monat IN @s_monat
AND a~blart IN @s_blart
AND b~hkont IN @s_hkont
AND a~budat = @p_date.
" 获取成本中心信息
IF gt_report_data IS NOT INITIAL.
SELECT kostl, belnr, gjahr, bukrs
FROM coss
INTO TABLE @DATA(lt_coss)
FOR ALL ENTRIES IN @gt_report_data
WHERE belnr = @gt_report_data-belnr
AND gjahr = @gt_report_data-gjahr
AND bukrs = @gt_report_data-bukrs.
LOOP AT gt_report_data INTO gs_report_data.
READ TABLE lt_coss INTO DATA(ls_coss) WITH KEY
belnr = gs_report_data-belnr
gjahr = gs_report_data-gjahr
bukrs = gs_report_data-bukrs.
IF sy-subrc = 0.
gs_report_data-kostl = ls_coss-kostl.
ENDIF.
MODIFY gt_report_data FROM gs_report_data.
ENDLOOP.
ENDIF.
" 获取创建人信息
IF gt_report_data IS NOT INITIAL.
SELECT bukrs, gjahr, belnr, username, erdat, erzet
FROM bkpf
INTO TABLE @DATA(lt_bkpf_user)
FOR ALL ENTRIES IN @gt_report_data
WHERE belnr = @gt_report_data-belnr
AND gjahr = @gt_report_data-gjahr
AND bukrs = @gt_report_data-bukrs.
LOOP AT gt_report_data INTO gs_report_data.
READ TABLE lt_bkpf_user INTO DATA(ls_user) WITH KEY
belnr = gs_report_data-belnr
gjahr = gs_report_data-gjahr
bukrs = gs_report_data-bukrs.
IF sy-subrc = 0.
gs_report_data-username = ls_user-username.
gs_report_data-erdat = ls_user-erdat.
gs_report_data-erzet = ls_user-erzet.
ENDIF.
MODIFY gt_report_data FROM gs_report_data.
ENDLOOP.
ENDIF.
ENDFORM.
```
## 3. 数据处理逻辑
```ABAP
* 数据处理
FORM process_data.
" 金额符号处理
LOOP AT gt_report_data INTO gs_report_data.
IF gs_report_data-shkzg = 'H'. "贷方
gs_report_data-dmbtr = gs_report_data-dmbtr * -1.
ENDIF.
MODIFY gt_report_data FROM gs_report_data.
ENDLOOP.
" 汇总处理
IF p_sum = 'X'.
DATA: lt_sum TYPE TABLE OF ty_report_data,
ls_sum TYPE ty_report_data.
LOOP AT gt_report_data INTO gs_report_data
GROUP BY ( bukrs = gs_report_data-bukrs
gjahr = gs_report_data-gjahr
hkont = gs_report_data-hkont
txt50 = gs_report_data-txt50
waers = gs_report_data-waers )
ASCENDING
ASSIGNING FIELD-SYMBOL(<fs_group>).
CLEAR ls_sum.
ls_sum-bukrs = <fs_group>-bukrs.
ls_sum-gjahr = <fs_group>-gjahr.
ls_sum-hkont = <fs_group>-hkont.
ls_sum-txt50 = <fs_group>-txt50.
ls_sum-waers = <fs_group>-waers.
ls_sum-txt50 = '小计'.
LOOP AT GROUP <fs_group> ASSIGNING FIELD-SYMBOL(<fs_member>).
ls_sum-dmbtr = ls_sum-dmbtr + <fs_member>-dmbtr.
ENDLOOP.
APPEND ls_sum TO lt_sum.
ENDLOOP.
" 添加总计行
IF lt_sum IS NOT INITIAL.
CLEAR ls_sum.
ls_sum-txt50 = '总计'.
LOOP AT lt_sum INTO DATA(ls_group_sum).
ls_sum-dmbtr = ls_sum-dmbtr + ls_group_sum-dmbtr.
ENDLOOP.
APPEND ls_sum TO lt_sum.
ENDIF.
" 替换原始数据为汇总数据
CLEAR gt_report_data.
gt_report_data = lt_sum.
ENDIF.
ENDFORM.
```
## 4. ALV展示
```ABAP
* ALV展示
FORM display_alv.
DATA: lr_alv TYPE REF TO cl_salv_table,
lr_columns TYPE REF TO cl_salv_columns_table,
lr_column TYPE REF TO cl_salv_column_table,
lr_functions TYPE REF TO cl_salv_functions_list,
lr_layout TYPE REF TO cl_salv_layout,
ls_layout TYPE salv_s_layout,
lr_aggregations TYPE REF TO cl_salv_aggregations,
lr_aggregation TYPE REF TO cl_salv_aggregation.
TRY.
cl_salv_table=>factory(
IMPORTING
r_salv_table = lr_alv
CHANGING
t_table = gt_report_data ).
" 设置布局
lr_layout = lr_alv->get_layout( ).
ls_layout-key = 'STANDARD_REPORT_LAYOUT'.
ls_layout-report = sy-repid.
lr_layout->set_key( ls_layout ).
lr_layout->set_save_restriction( if_salv_c_layout=>restrict_none ).
lr_layout->set_default( abap_true ).
" 设置功能
lr_functions = lr_alv->get_functions( ).
lr_functions->set_all( abap_true ).
" 设置列属性
lr_columns = lr_alv->get_columns( ).
lr_columns->set_optimize( abap_true ).
" 设置关键列
PERFORM set_column_properties USING lr_columns.
" 设置汇总(如果启用)
IF p_sum = 'X'.
lr_aggregations = lr_alv->get_aggregations( ).
" 对金额列设置汇总
TRY.
lr_aggregation = lr_aggregations->get_aggregation( 'DMBTR' ).
lr_aggregation->set_aggregation( if_salv_c_aggregation=>total ).
CATCH cx_salv_not_found.
ENDTRY.
ENDIF.
" 显示ALV
lr_alv->display( ).
CATCH cx_salv_msg INTO DATA(lx_error).
MESSAGE lx_error TYPE 'I' DISPLAY LIKE 'E'.
ENDTRY.
ENDFORM.
* 设置列属性
FORM set_column_properties USING ir_columns TYPE REF TO cl_salv_columns_table.
DATA: lr_column TYPE REF TO cl_salv_column_table.
" 公司代码
lr_column ?= ir_columns->get_column( 'BUKRS' ).
lr_column->set_short_text( '公司代码' ).
lr_column->set_medium_text( '公司代码' ).
lr_column->set_long_text( '公司代码' ).
" 会计年度
lr_column ?= ir_columns->get_column( 'GJAHR' ).
lr_column->set_short_text( '年度' ).
" 凭证号
lr_column ?= ir_columns->get_column( 'BELNR' ).
lr_column->set_short_text( '凭证号' ).
lr_column->set_output_length( 10 ).
" 凭证日期
lr_column ?= ir_columns->get_column( 'BUDAT' ).
lr_column->set_short_text( '凭证日期' ).
lr_column->set_medium_text( '凭证日期' ).
" 凭证类型
lr_column ?= ir_columns->get_column( 'BLART' ).
lr_column->set_short_text( '凭证类型' ).
" 科目号
lr_column ?= ir_columns->get_column( 'HKONT' ).
lr_column->set_short_text( '科目' ).
" 科目描述
lr_column ?= ir_columns->get_column( 'TXT50' ).
lr_column->set_short_text( '科目描述' ).
lr_column->set_output_length( 30 ).
" 金额
lr_column ?= ir_columns->get_column( 'DMBTR' ).
lr_column->set_short_text( '金额' ).
lr_column->set_alignment( if_salv_c_alignment=>right ).
lr_column->set_currency_column( 'WAERS' ).
" 货币
lr_column ?= ir_columns->get_column( 'WAERS' ).
lr_column->set_short_text( '货币' ).
" 成本中心
lr_column ?= ir_columns->get_column( 'KOSTL' ).
lr_column->set_short_text( '成本中心' ).
ENDFORM.
```
## 5. Excel导出功能
```ABAP
* Excel导出
FORM export_to_excel.
DATA: lt_export TYPE TABLE OF zstandard_report_export, "自定义导出结构
ls_export TYPE zstandard_report_export.
" 转换数据格式
LOOP AT gt_report_data INTO gs_report_data.
MOVE-CORRESPONDING gs_report_data TO ls_export.
APPEND ls_export TO lt_export.
ENDLOOP.
" 调用导出函数
CALL FUNCTION 'SAP_CONVERT_TO_XLSX_FORMAT'
EXPORTING
i_filename = '标准报表.xlsx'
i_append_filename = space
i_filename_only = space
i_line_header = 'X' "包含列标题
TABLES
it_tab_sap_data = lt_export
EXCEPTIONS
conversion_failed = 1
OTHERS = 2.
IF sy-subrc = 0.
MESSAGE '导出成功' TYPE 'S'.
ELSE.
MESSAGE '导出失败' TYPE 'E'.
ENDIF.
ENDFORM.
```
## 6. 报表增强功能
```ABAP
* 添加权限检查
FORM check_authority.
AUTHORITY-CHECK OBJECT 'F_BKPF_BUK'
ID 'ACTVT' FIELD '03'
ID 'BUKRS' FIELD gs_report_data-bukrs.
IF sy-subrc <> 0.
MESSAGE e001(zm) WITH '无公司代码' gs_report_data-bukrs '的显示权限'.
ENDIF.
ENDFORM.
* 添加日志记录
FORM write_log CHANGING pv_message TYPE string.
DATA: lv_timestamp TYPE timestamp.
GET TIME STAMP FIELD lv_timestamp.
INSERT zreport_log FROM @VALUE #(
mandt = sy-mandt
report = sy-repid
uname = sy-uname
erdat = sy-datum
erzet = sy-uzeit
timestamp = lv_timestamp
message = pv_message ).
COMMIT WORK.
ENDFORM.
```
## 7. 完整报表流程总结
1. **初始化**:
- 设置选择屏幕标题和默认值
- 定义数据结构和内表
2. **选择屏幕处理**:
- 接收用户输入的筛选条件
- 提供显示选项(汇总/明细)
3. **数据获取**:
- 从主表(如BKPF、BSEG)获取基础数据
- 通过FOR ALL ENTRIES优化关联表查询
- 获取相关描述信息(如科目描述)
4. **数据处理**:
- 金额符号处理(借贷方向)
- 数据汇总处理
- 权限检查
5. **结果展示**:
- ALV展示(支持排序、过滤、汇总)
- Excel导出功能
- 日志记录
## 8. 性能优化建议
1. **查询优化**:
- 使用索引优化大表查询
- 限制查询日期范围
- 避免在循环中执行数据库查询
2. **内存管理**:
- 分批处理大数据量
- 及时释放不再使用的内表
- 使用共享内存对象缓存常用数据
3. **ALV优化**:
- 只加载必要的数据列
- 使用延迟加载技术
- 避免在ALV事件中执行耗时操作
## 9. 模板使用说明
1. **复制模板**:
- 创建新报表时复制此模板
- 修改报表名称(REPORT语句)
- 更新消息类(MESSAGE-ID)
2. **自定义部分**:
- 修改ty_report_data结构以适应业务需求
- 更新get_data表单中的数据获取逻辑
- 调整process_data表单中的业务逻辑
3. **增强功能**:
- 根据需要添加权限检查
- 扩展日志记录功能
- 添加自定义事件处理
## 10. 完整报表结构图
```
Z_STANDARD_REPORT
├── 数据结构定义
│ ├── 主数据结构
│ └── 导出结构
├── 选择屏幕
│ ├── 筛选条件
│ └── 显示选项
├── 数据获取
│ ├── 主表查询
│ ├── 关联表查询
│ └── 描述信息获取
├── 数据处理
│ ├── 金额处理
│ ├── 汇总处理
│ └── 权限检查
├── 结果展示
│ ├── ALV展示
│ └── Excel导出
└── 增强功能
├── 日志记录
└── 错误处理
```
阅读全文
相关推荐



















