SAP FICO 表字段增强实战指南

FICO模块是SAP中最常需要做表字段增强的模块。财务业务的多样性导致标准字段无法完全满足需求,因此需要在BKPF、BSEG、ACDOCA等核心表上扩展自定义字段。本文从实战角度总结FICO表字段增强的完整方案。

一、增强方式概览

增强方式 适用场景 操作事务码
CI_ Include BKPF/BSEG 标准表加字段 SE11
Append Structure 任意透明表/结构加字段 SE11
BADI ACC_DOCUMENT BAPI_ACC_DOCUMENT_POST 扩展字段写入 SE18/SE19
替代 Substitution 凭证过账时自动填充字段值 GGB1/OBBH
校验 Validation 凭证过账时校验字段值 GGB0/OB28
BTE 增强 FI 凭证事件触发自定义逻辑 FIBF
S/4HANA ACDOCA 扩展 新总账表字段增强 SE11 + CDS View

二、CI_ Include 方式(最常用)

2.1 BKPF/BSEG 增强

SAP为BKPF和BSEG预留了CI_ Include结构,专门用于客户自定义字段扩展:

  • CI_COBL — 用于BSEG行项目级别的字段增强(科目分配相关)
  • CI_BKPF — 用于BKPF凭证抬头级别的字段增强

操作步骤:

  1. SE11进入CI_COBL结构
  2. 添加自定义字段(命名以ZZ或YY开头)
  3. 激活结构
  4. 字段自动出现在BSEG表中
" CI_COBL 结构增强示例
" 添加字段:
ZZFIELD1 TYPE CHAR20 "自定义字段1
ZZFIELD2 TYPE DATS "自定义日期
ZZAMOUNT TYPE BSEG-DMBTR "自定义金额

注意点:

  • CI_COBL的字段会自动出现在FB01/FB02/FB60/FB70等凭证录入屏幕
  • 如果字段不需要出现在标准屏幕,可以在屏幕增强中隐藏
  • 修改CI_ Include后需要用SE14调整数据库,否则可能报错

2.2 自定义表增强(Append Structure)

对于自定义Z表或其他标准表,使用Append Structure:

" 在SE11中创建 Append Structure ZAFI_BKPF
" 附加到 BKPF 表
ZZ_BUKRS_TYPE TYPE CHAR1 "公司类型标识
ZZ_AUDIT_NO TYPE CHAR30 "审计编号
ZZ_EXT_REF TYPE CHAR50 "外部参考号

操作步骤:

  1. SE11创建Append Structure
  2. 定义字段
  3. 将Append Structure附加到目标表
  4. 激活
  5. 如果表有数据,用SE14调整数据库

三、BADI ACC_DOCUMENT(BAPI凭证过账扩展)

当使用 BAPI_ACC_DOCUMENT_POST 过账凭证时,标准BAPI结构不包含自定义字段。需要通过BADI ACC_DOCUMENT的CHANGE方法,在过账时将扩展字段值写入BSEG。

3.1 实现步骤

  1. SE18查看BADI定义 ACC_DOCUMENT
  2. SE19创建实现 ZCL_IM_ACC_DOCUMENT
  3. 实现方法 IF_EX_ACC_DOCUMENT~CHANGE
  4. 激活

3.2 代码实现

METHOD if_ex_acc_document~change.
*" BAPI_ACC_DOCUMENT_POST 扩展字段写入
*" 通过 BAPIPAREX 扩展结构传递自定义数据

DATA: ls_accit TYPE accit,
ls_extension TYPE bapiparex,
ls_zsfiexten TYPE zsfiexten. "自定义扩展结构

" 从扩展参数中读取自定义数据
LOOP AT c_extension2 INTO ls_extension.
IF ls_extension-structure = 'ZSFIEXTEN'.
ls_zsfiexten = ls_extension-valuepart1.

" 将自定义字段值写入对应凭证行
LOOP AT c_accit INTO ls_accit.
IF ls_accit-posnr = ls_zsfiexten-posnr.
ls_accit-zz_rstgr = ls_zsfiexten-rstgr. "原因代码
ls_accit-zz_sgtxt = ls_zsfiexten-sgtxt. "行项目文本
ls_accit-zz_xref1 = ls_zsfiexten-xref1. "参考码1
ls_accit-zz_prctr = ls_zsfiexten-prctr. "利润中心
MODIFY c_accit FROM ls_accit INDEX sy-tabix.
ENDIF.
ENDLOOP.
ENDIF.
ENDLOOP.
ENDMETHOD.

3.3 调用端代码

" 在调用 BAPI_ACC_DOCUMENT_POST 前填充扩展结构
DATA: ls_extension TYPE bapiparex,
ls_zsfiexten TYPE zsfiexten.

ls_zsfiexten-posnr = '000010'. "行项目号
ls_zsfiexten-rstgr = '01'. "原因代码
ls_zsfiexten-sgtxt = '外部系统凭证'. "行文本
ls_zsfiexten-prctr = '100001'. "利润中心

ls_extension-structure = 'ZSFIEXTEN'.
ls_extension-valuepart1 = ls_zsfiexten.
APPEND ls_extension TO lt_extension.

" 调用 BAPI
CALL FUNCTION 'BAPI_ACC_DOCUMENT_POST'
EXPORTING
documentheader = ls_header
TABLES
accountgl = lt_gl
accountpayable = lt_ap
currencyamount = lt_amt
extension2 = lt_extension " 扩展字段
return = lt_return.

关键点:

  • ACCIT结构中需要预先通过SE11增强添加ZZ_字段
  • 扩展结构ZSFIEXTEN需要自定义
  • c_extension2 是CHANGE方法的输入参数,包含BAPI传入的所有扩展数据

四、替代增强(Substitution)— 自动填充字段值

当需要在凭证过账时自动填充某些字段值(而非手动输入),使用替代增强。

4.1 配置步骤

  1. SE38复制 RGGBS000 → ZRGGBS000
  2. GCX2维护应用区域 GBLS → 退出程序 ZRGGBS000
  3. GGB1维护替代规则
  4. OBBH激活替代(按公司代码)

4.2 出口代码编写

" 在 ZRGGBS000 中定义出口
FORM zfi_substit_01.
" 场景:当凭证类型为SA时,自动填充利润中心
IF bseg-blart = 'SA'.
bseg-prctr = '100001'.
ENDIF.
ENDFORM.
" 完全凭证替代示例(同时使用抬头和行项目数据)
FORM zfi_substit_class USING bool_data TYPE gb002_015.
" 当公司代码2000且科目前4位为6001时,自动设置成本中心
IF bkpf-bukrs = '2000' AND bseg-hkont(4) = '6001'.
bseg-kostl = '20001000'.
ENDIF.
ENDFORM.

4.3 替代不起作用的排查

常见原因:

  1. 字段不在GB01允许范围内 — SE16查看GB01表,如果字段标记EXCLUDE则不允许替代。通过SM30维护视图VWTYGB01修改
  2. 替代程序未重新编译 — SE38运行RGUGBR00重新生成
  3. 出口参数类型不匹配 — c_exit_param_none用于单字段替代,c_exit_param_class用于完全凭证替代

五、校验增强(Validation)— 字段值校验

5.1 配置步骤

  1. SE38复制 RGGBR000 → ZRGGBR000
  2. GCX2维护应用区域 GBLR → 退出程序 ZRGGBR000
  3. GGB0维护校验规则
  4. OB28激活校验(按公司代码)

5.2 典型校验场景

" 凭证校验:原因代码不能为空
" 在 ZRGGBR000 中定义出口
FORM zfi_validate_01.
" 当科目为银行科目时,原因代码必填
IF bseg-hkont(4) = '1002'.
IF bseg-rstgr IS INITIAL.
message_id = 'ZFI'.
message_number = '001'.
EXIT.
ENDIF.
ENDIF.
ENDFORM.

校验消息类型:A(取消)、E(错误)、W(警告)、I(信息)

六、BTE增强(财务专用)

BTE是FI模块独有的增强方式,主要用于凭证事件触发时的附加处理。

6.1 配置步骤

  1. FIBF进入BTE配置
  2. 查找合适的事件号(如1120凭证过账前、1030凭证过账后)
  3. 创建自定义函数模块
  4. 将函数模块分配给事件号

6.2 典型应用

" BTE事件1120:凭证过账前的数据校验
FUNCTION zfi_bte_1120.
*" 凭证过账前检查
IMPORTING
i_bkpf TYPE bkpf
i_bseg TYPE bseg.

" 校验逻辑
IF i_bseg-hkont(4) = '6601' AND i_bseg-prctr IS INITIAL.
MESSAGE e001(zfi) WITH '损益科目利润中心不能为空'.
ENDIF.
ENDFUNCTION.

七、S/4HANA ACDOCA 扩展

在S/4HANA中,ACDOCA(Universal Journal)取代了BSEG/FAGLFLEXT等表。字段增强方式:

7.1 Append Structure 方式

" SE11创建 Append Structure ZACDOCA_EXT
" 附加到 ACDOCA 表
ZZ_BUS_TYPE TYPE CHAR2 "业务类型
ZZ_PROJECT TYPE CHAR20 "项目编号
ZZ_COST_CENTER_TYPE TYPE CHAR1 "成本中心类型

7.2 CDS View 扩展

" 通过 CDS View 扩展将自定义字段暴露给前端
@AbapCatalog.sqlViewAppendName: 'ZACDOCAEXT'
@EndUserText.label: 'ACDOCA Extension'
extend view I_JournalEntryItem with Z_I_JournalEntryItem_Ext
{
_Extension.ZZ_BUS_TYPE as ZZBusinessType,
_Extension.ZZ_PROJECT as ZZProjectNumber,
_Extension.ZZ_COST_CENTER_TYPE as ZZCostCenterType
}

7.3 S/4HANA 注意事项

  • ACDOCA是宽表,一个行项目只有一条记录(不再区分BSEG各视图)
  • 自定义字段需要通过Extend添加到CDS View才能在Fiori应用中可见
  • 如果从ECC升级到S/4HANA,原有BSEG增强字段需要迁移到ACDOCA

八、凭证打印/SmartForms字段增强

增强字段在打印表单中的使用:

  1. 确保增强字段已写入BKPF/BSEG
  2. 在SmartForms中通过全局变量读取增强字段
  3. 或者在打印程序中直接从数据库读取
" 在打印程序中读取增强字段
SELECT SINGLE zz_audit_no, zz_ext_ref
FROM bkpf
INTO (lv_audit_no, lv_ext_ref)
WHERE bukrs = p_bukrs
AND belnr = p_belnr
AND gjahr = p_gjahr.

九、完整增强实施清单

一个典型的FICO字段增强项目需要操作的步骤:

1. SE11  CI_COBL / CI_BKPF 添加字段        ← 数据库层
2. SE11 ACCIT 结构添加ZZ_字段 ← BADI写入目标
3. SE18 BADI ACC_DOCUMENT 实现 ← BAPI过账写入
4. SE38 ZRGGBS000 替代出口 ← 自动填充
5. SE38 ZRGGBR000 校验出口 ← 数据校验
6. GGB1 维护替代规则 + OBBH 激活
7. GGB0 维护校验规则 + OB28 激活
8. GCX2 维护应用区域
9. RGUGBR00 重新生成替代/校验程序
10. SE14 调整数据库(如有表结构变更)

十、常见问题与解决方案

问题 原因 解决方案
替代字段不可用 GB01表中字段标记EXCLUDE SM30维护VWTYGB01去掉EXCLUDE
替代不起作用 替代程序未重新编译 SE38运行RGUGBR00
BAPI过账不写入自定义字段 未实现BADI ACC_DOCUMENT SE19创建BADI实现
CI_ Include激活失败 数据库需要调整 SE14调整数据库
替代出口报错未生成 出口未在RGGBS000中注册 在get_exit_titles中添加出口定义
S/4HANA字段迁移 BSEG字段不在ACDOCA中 创建Append Structure附加到ACDOCA