ABAP 如何调试SAP的校验(validation)

SAP FI凭证校验(Validation)调试指南
本文详细介绍了如何调试SAP财务模块(FI)中的凭证校验(Validation)规则,包括两种调试方法:一是通过Activate trace激活跟踪,二是直接查看并调试由validation生成的程序代码。通过实例展示了如何定位和理解代码,以便于理解和优化验证逻辑。

校验 (validation) 是 SAP FI 模块常用的凭证检查技术,这个术语在国内也常被称作确认,但确认似乎辨识度太低,不适合作为术语来用。

本文详细说明 validation 的调试方法。SAP 提供的 validation,本质上也是基于规则生成的程序,只不过将规则抽象为 prerequisite、check 和 message 三个方面,提供了更加友好的界面而已。

假设我们需要这样一个凭证的校验规则:如果公司代码为 Z900 并且凭证类型为 SA,则凭证的抬头文本不能为空。因为是对凭证抬头校验,所以使用 1 作为 calling point。

用 OB28 ( 或者 GGB0 ) 设置校验规则如下:

因为校验需要提示消息,使用 SE91 维护消息号 ZSTONE-001: Document header cannot be blank!

调试方法 1

在左边的导航区,定位到 validation (Z900-1),然后通过菜单 Extras -> Activate trace 激活跟踪。

录入一张会计凭证,故意将 Document header text 留空。


回车后触发了 trace,进入如下界面:


在这个界面中,condition 就是我们设置的 prerequisite (前提)。条件为 True,Check 为 False (意思是检查没过),所以触发了错误消息。但这种跟踪还是比较粗略。

调试方法 2

鉴于上面的方法没有看到细节,我们推荐第二种方法,直接查看 validation 生成的程序的源代码,然后可以在代码中设置断点等方法来调试,关键是 validation 后 SAP 系统生成的程序名称。对于 validation (也适用于替代 substituion), SAP 自动生成的程序名为 GBTmmaa0 (GBT 和末尾的 0 是固定的,中间 mm 和 aa 是变化的)

  • mm: 两位数的 client 代码,需要使用函数 G_CLIENT_ENCODE 获取。比如我的系统 client 为 001。通过 SE37 测试运行,得到两位数的 client 为 01.

  • aa: 表示 application area,对于 FI 来说,就是 FI

由此我们知道,刚才创建的 validation,系统生成的程序名为:GBT01FI0。通过代码后面的注释,我们知道 Validation 的代码在 include GBT01FID 中,如下图。

双击进入代码,不难找到下面的代码,对步骤 001 进行校验的子程序。


G_STEP 对应 validation 中的 step, 校验的代码在子程序 VALCOND_1Z900_#001 中,感兴趣的话,继续查看代码,还是比较直观的:


刚才的截图我们已经设置了断点。F-02 录入凭证即可进入断点来调试代码了。

以上方法很管用,但稍嫌麻烦,因为程序名称不太好记住。其实, SAP 提供了一种快速定位代码的方法。在 OB28 界面中,导航菜单中选择 validation (Z900-1),在 command window 中输入 =shcd,回车后即可进入程序 GBT01FID

回车,系统直接进入程序,可以在这里设置断点。这种方法不需要记程序名称。

<think>我们正在处理一个ABAP增强问题,具体是在MIRO(发票校验)过程中将数据写入BSEG表。根据SAP标准,BSEG表是财务凭证的段表,通常在过账时由系统自动写入。用户希望通过增强在MIRO过程中写入自定义数据到BSEG。 注意:直接修改BSEG表是不被SAP推荐的,因为财务凭证的完整性很重要。通常,我们会使用替代(Substitution)或校验Validation)等标准增强技术,或者使用BAdI(Business Add-In)来在凭证保存前修改凭证数据。 在MIRO过程中,我们可以使用以下增强点: 1. BAdI: MB_DOCUMENT_BADI 这个BAdI用于在发票校验过账前修改凭证数据。它有一个方法IF_EX_MB_DOCUMENT_BADI~CHANGE_DOCUMENT,可以在其中修改凭证的抬头和行项目数据。但是,请注意,这个BAdI修改的是发票校验的凭证数据,最终会生成财务凭证(会计凭证)。因此,我们可以在这里设置一些字段的值,这些值会传递到财务凭证中。 2. 替代(Substitution): 可以使用事务码GGB1配置替代,在过账前根据条件替换某些字段的值。替代可以修改BSEG中的字段,但需要在配置中设置。 3. 用户出口(User Exit): 在MIRO中,可能有一些用户出口,例如:RM06E005(过账前修改行项目数据)等。 然而,根据用户需求,他们希望将数据写入BSEG表。在标准MIRO流程中,发票校验会生成财务凭证,而财务凭证的行项目就存储在BSEG中。因此,我们可以在凭证保存前,通过BAdI来设置BSEG中的字段。 使用BAdI MB_DOCUMENT_BADI的步骤: 1. 创建BAdI的实现:通过SE18或SE19创建MB_DOCUMENT_BADI的实现。 2. 在方法IF_EX_MB_DOCUMENT_BADI~CHANGE_DOCUMENT中,我们可以修改行项目数据。该方法的参数C_DOCUMENT包含了发票校验的凭证数据,我们可以修改行项目(ITEM)的字段。 但是,需要注意的是,BSEG表中的字段并不是都可以直接修改的。有些字段是系统自动设置的,有些字段可以通过这个BAdI修改。通常,我们可以修改的字段包括成本中心、订单号、资产号等。在修改前,需要确认该字段是否在BAdI中可修改。 另外,如果用户希望写入自定义字段(比如在BSEG中附加了自定义字段),那么需要确保: - 该字段已经被追加到标准表中(通过CI_BSEG等结构) - 在BAdI中,可以通过扩展结构来设置自定义字段的值。 由于BAdI MB_DOCUMENT_BADI的C_DOCUMENT参数是一个结构,其中行项目是T_ITEM,而T_ITEM本身是一个包含多个字段的结构,包括扩展结构(EXTENSION)。我们可以通过EXTENSION来设置自定义字段。 具体步骤(假设我们要设置一个自定义字段ZZFIELD): 1. 在CI_BSEG中追加字段ZZFIELD(通过SE11追加)。 2. 在BAdI实现中,循环处理C_DOCUMENT-ITEM,为每个行项目设置扩展字段: DATA: ls_extension TYPE bape_bset. ls_extension-fieldname = 'ZZFIELD'. ls_extension-value = '要设置的值'. APPEND ls_extension TO c_document-item[i]-extension. 3. 这样,在过账时,系统会将这个值传递到BSEG-ZZFIELD。 但是,请注意:这种方法只适用于已经追加到CI_BSEG中的字段。另外,使用BAdI MB_DOCUMENT_BADI需要谨慎,因为它会影响所有的发票校验。 如果用户出口RM06E005可用,也可以考虑使用。在RM06E005中,有一个include ZXR06E05,我们可以在这里编写代码。在用户出口中,我们可以修改表T_BSEG,该表就是财务凭证行项目表。因此,可以直接修改T_BSEG中的字段(包括自定义字段)。 用户出口RM06E005的使用步骤: 1. 使用事务码SMOD,找到出口RM06E005。 2. 创建增强项目,在包含ZXR06E05中编写代码。 3. 在ZXR06E05中,我们可以循环修改T_BSEG表(该表是行项目表,对应BSEG结构)。 示例代码(在ZXR06E05中): LOOP AT T_BSEG. " 根据条件修改T_BSEG的字段,例如: T_BSEG-ZZFIELD = '值'. MODIFY T_BSEG. ENDLOOP. 比较两种方法: - BAdI MB_DOCUMENT_BADI是面向对象的增强,更推荐使用。 - 用户出口RM06E005是传统的增强,但也可以实现。 然而,需要注意的是,在MIRO过程中,用户出口RM06E005是否被调用?根据SAP标准,在发票校验过账时,会调用财务凭证的保存,而财务凭证保存时会调用一些用户出口,包括RM06E005(在凭证保存前修改行项目)。因此,在MIRO中,当发票校验生成财务凭证时,也会调用这个出口。 因此,两种方法都可以实现。但建议使用BAdI,因为它是SAP推荐的方式,并且更易于管理。 总结: 用户可以通过实现BAdI MB_DOCUMENT_BADI,在方法CHANGE_DOCUMENT中通过扩展结构设置BSEG的自定义字段。或者使用用户出口RM06E005直接修改T_BSEG表。 注意:在修改财务凭证行项目时,必须确保符合财务规则,避免数据不一致。 根据用户提供的引用,引用[3]提到了通过替代实现根据在MIRO中录入的分配来确定成本中心。替代也是一种方法,但替代是通过配置实现的,不需要编写代码。如果用户的需求是简单的字段替换,也可以考虑使用替代(事务码GGB1)。但是,如果逻辑复杂,则使用BAdI或用户出口更灵活。 因此,我们提供两种方法供用户选择: 方法1(推荐):使用BAdI MB_DOCUMENT_BADI。 方法2:使用用户出口RM06E005。 下面分别给出两种方法的代码示例: 方法1:BAdI MB_DOCUMENT_BADI 步骤: 1. SE19 -> 创建MB_DOCUMENT_BADI的实现(例如:ZBADI_MIRO)。 2. 在方法IF_EX_MB_DOCUMENT_BADI~CHANGE_DOCUMENT中编写代码。 示例代码: METHOD if_ex_mb_document_badi~change_document. " 假设我们有一个自定义字段ZZKOSTL(成本中心),并且已经在CI_BSEG中追加 DATA: ls_extension TYPE bape_bset. FIELD-SYMBOLS: <ls_item> LIKE LINE OF c_document-item. LOOP AT c_document-item ASSIGNING <ls_item>. " 这里可以根据条件设置,例如根据采购订单等 " 清除已有的扩展(可选) CLEAR ls_extension. ls_extension-fieldname = 'ZZKOSTL'. " 自定义字段名 ls_extension-value = '成本中心值'. " 这里设置具体的值 APPEND ls_extension TO <ls_item>-extension. ENDLOOP. ENDMETHOD. 方法2:用户出口RM06E005 步骤: 1. 使用SMOD,创建增强项目(例如:ZMIRO_ENHANCE)。 2. 在增强中包含ZXR06E05。 3. 在ZXR06E05中编写代码。 示例代码: INCLUDE ZXR06E05. * 在ZXR06E05中 LOOP AT T_BSEG. " 设置自定义字段的值,注意:这里T_BSEG是工作区,不是表 " 所以应该使用:T_BSEG-ZZFIELD = '值' " 然后MODIFY T_BSEG INDEX sy-tabix. " 但注意:在用户出口中,T_BSEG是一个内表,因此应该循环修改 " 实际上,在用户出口中,T_BSEG是作为内表传递的,所以应该这样: " 假设我们有一个自定义字段ZZKOSTL T_BSEG-ZZKOSTL = '成本中心值'. MODIFY T_BSEG INDEX sy-tabix. ENDLOOP. 注意:在用户出口中,T_BSEG是内表,因此循环中使用MODIFY ... INDEX sy-tabix是修改当前行。 用户需要根据实际情况选择合适的方法,并确保在修改财务凭证字段时,符合业务逻辑和财务规范。 相关问题: 1. 如何确定在MIRO增强中应该修改哪个行项目? 2. 在BAdI MB_DOCUMENT_BADI中,如何根据采购订单或发票条件来设置不同的值? 3. 使用用户出口RM06E005修改BSEG字段时,需要注意哪些财务规则? 4. 如何确保自定义字段已经正确追加到BSEG表中?</think>### ABAP MIRO发票校验增强:写入BSEG表的方法 在ABAP中实现MIRO发票校验时向BSEG表写入数据,需通过**增强财务凭证的保存过程**来实现。以下是两种核心方法: --- #### 方法1:使用BAdI `MB_DOCUMENT_BADI`(推荐) **原理**:通过发票校验的BAdI在凭证保存前修改行项目数据,系统会自动将数据写入BSEG表。 **步骤**: 1. **创建BAdI实现**(事务码`SE19`) - BAdI名称:`MB_DOCUMENT_BADI` - 实现类:例如`ZCL_IM_MB_DOCUMENT_BADI` 2. **在方法`IF_EX_MB_DOCUMENT_BADI~CHANGE_DOCUMENT`中编码**: ```abap METHOD if_ex_mb_document_badi~change_document. LOOP AT c_document-item ASSIGNING FIELD-SYMBOL(<ls_item>). " 示例:根据条件设置BSEG的自定义字段 IF <ls_item>-zuonr = '特定分配号'. " 通过扩展结构写入BSEG字段 APPEND VALUE bape_bset( fieldname = 'ZZKOSTL' " BSEG的自定义字段 value = '成本中心值' ) TO <ls_item>-extension. ENDIF. ENDLOOP. ENDMETHOD. ``` **关键点**: - 通过`extension`内表传递BSEG字段值(需字段已追加到CI_BSEG) - 支持标准字段(如`KOSTL`)或自定义字段[^3] --- #### 方法2:使用用户出口`RM06E005` **原理**:在财务凭证保存前,通过传统出口修改行项目表`T_BSEG`。 **步骤**: 1. **激活出口**(事务码`SMOD`) - 增强点:`RM06E005` - 函数组:`XR06E005` 2. **在包含文件`ZXR06E05`中编码**: ```abap LOOP AT t_bseg ASSIGNING FIELD-SYMBOL(<ls_bseg>). " 直接修改BSEG行项目数据 IF <ls_bseg>-zuonr = '特定分配号'. <ls_bseg>-zzfield = '自定义值'. " 需确保字段已追加到BSEG ENDIF. ENDLOOP. ``` --- #### ⚠️ 关键注意事项 1. **字段追加**: - 自定义字段需通过`CI_BSEG`结构追加到BSEG表(事务码`SE11`) - 标准字段(如`KOSTL`)可直接修改 2. **数据一致性**: - 仅修改与业务相关的字段(如成本中心、分配号) - 禁止修改核心字段(如金额、科目) 3. **调试建议**: - 使用事务码`F-02`模拟过账测试 - 检查财务凭证行项目(事务码`FB03`) --- #### 性能与安全 - **BAdI优于用户出口**:支持面向对象设计,兼容性更好 - **避免直接更新BSEG**:财务表需严格通过凭证保存更新,否则可能导致数据不一致[^1][^2] - **权限控制**:通过权限对象`F_BKPF_BES`限制字段修改权限 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值