MM--关于MIRO的分析基于订单的发票校验的跟踪

本文分析了MIRO(发票校验)过程中涉及的订单数据计算、函数调用及数据表操作。从RM08RL82获取EKKO信息,继而读取EKPO和EKBE,计算开票金额。MIRO保存时调用多个函数,如CKMV_AC_DOCUMENT_POST等,并插入数据到CKMI1、BKPF等表。同时,更新供应商主数据和总帐科目业务额。

1)关于计算交货单的可能的输入到发票校验(MIRO)可以参见RM08RL82
计算的说明:
1)读取适合条件的EKKO
SELECT  * FROM  "EKKO"
WHERE
  "MANDT" = '800' AND "BSTYP" IN ('L' , 'F') AND "EBELN" = ''4500000005' AND "BUKRS" = '1002'
  AND "LIFRE" = '0011000843' AND "FRGRL" = ''  AND "LOEKZ" = ' '  AND ( "MEMORY" =' '  OR "MEMORY" IS NULL )
2)根据读取出的EKKO读取EKPO和EKBE
SELECT  * FROM  EKPO WHERE "MANDT" = '800' AND "EBELN" = '4500000005' AND "REPOS" = 'X' AND "LOEKZ" = ' '
SELECT * FROM EKBE WHERE "MANDT" = '800' AND "EBELN" = '4500000005' AND ( "VGABE" = '1' OR "VGABE" = '2' )
3)循环读取EKKO的内表,来计算EKBE的交货和发货的的数量和金额,来生成需要开票的金额。


2)MIRO的操作保存时用到的函数
CALL FUNCTION 'CKMV_AC_DOCUMENT_POST'
CALL FUNCTION 'POST_DOCUMENT' IN UPDATE TASK
CALL FUNCTION 'G_FI_POSTING' IN UPDATE TASK
CALL FUNCTION 'G_LC_POSTING' IN UPDATE TASK
CALL FUNCTION 'AC_DOCUMENT_MM_UPDATE' IN UPDATE TASK
call function 'MCE_STATISTICS_UPD_V2' in

<think>我们正在讨论MIRO发票校验增强,特别是如何写入BSEG表的SGTXT字段(行项目文本)。由于用户提到没有FIEB_CHANGE BAdI,我们将使用替代方法。 根据之前的回答,我们有几种替代方案。这里我们重点关注使用BADI `INVOICE_UPDATE`和用户出口`MRM00001`(包含文件`ZXM08U16`)的方法,因为这两种方法可以直接修改行项目数据(类似于BSEG结构)。 注意:BSEG-SGTXT是标准字段,因此我们可以直接修改它,而不需要像自定义字段那样通过CI_COBL附加。但是,我们仍然需要确保在正确的增强点修改。 我们分两种方案详细说明: 方案1:使用BADI `INVOICE_UPDATE` 这个BAdI有两个方法可以修改行项目数据:`CHANGE_AT_SAVE`和`CHANGE_BEFORE_UPDATE`。其中,`CHANGE_AT_SAVE`方法中有一个内表`CHANGE_T_DRSEG`,它包含了行项目数据,其结构与BSEG类似(但不完全一样)。实际上,`DRSEG`结构中包含SGTXT字段。因此,我们可以在这里修改SGTXT。 步骤: 1. 通过SE18创建BADI `INVOICE_UPDATE`的实施。 2. 在实施中,实现方法`IF_EX_INVOICE_UPDATE~CHANGE_AT_SAVE`。 3. 在该方法中,循环内表`CHANGE_T_DRSEG`,然后修改SGTXT字段。 示例代码: ```abap METHOD if_ex_invoice_update~change_at_save. " 修改行项目文本 LOOP AT change_t_drseg ASSIGNING FIELD-SYMBOL(<ls_drseg>). " 可以根据条件修改,例如供应商行项目(供应商行项目的KOART='K') IF <ls_drseg>-koart = 'K'. " 供应商行项目 <ls_drseg>-sgtxt = '自定义行项目文本'. ENDIF. ENDLOOP. ENDMETHOD. ``` 注意:`change_t_drseg`是一个内表,其行类型是`DRSEG`(结构)。在DRSEG结构中,SGTXT字段是存在的。 方案2:使用用户出口`MRM00001`(包含文件`ZXM08U16`) 在用户出口中,有一个子例程`USER_EXIT_MODIFY_BSEG`,它直接传递一个BSEG结构的内表。因此,我们可以在这里修改SGTXT字段。 步骤: 1. 使用SE38打开程序`SAPLMRM1`。 2. 找到包含文件`ZXM08U16`(如果不存在,则创建)。 3. 在包含文件中编写子例程`USER_EXIT_MODIFY_BSEG`。 示例代码: ```abap *&---------------------------------------------------------------------* *& 包含 ZXM08U16 *&---------------------------------------------------------------------* FORM user_exit_modify_bseg TABLES ct_bseg STRUCTURE bseg. LOOP AT ct_bseg ASSIGNING FIELD-SYMBOL(<ls_bseg>). " 示例:根据条件修改SGTXT IF <ls_bseg>-koart = 'K' AND <ls_bseg>-lifnr = 'V10001'. <ls_bseg>-sgtxt = '供应商V10001的发票文本'. ENDIF. ENDLOOP. ENDFORM. ``` 注意:这个出口直接操作BSEG结构的内表,所以可以修改所有BSEG字段,包括SGTXT。 两种方案的比较: - `INVOICE_UPDATE` BAdI是更现代和推荐的方式,特别是在新版本中。 - 用户出口`MRM00001`是传统的增强方式,但依然有效。 选择建议: 如果系统支持`INVOICE_UPDATE` BAdI(通常SAP系统都有),则优先使用BAdI。否则,使用用户出口。 注意事项: 1. 修改SGTXT字段时,注意文本长度(最大50个字符)。 2. 确保修改的条件准确,避免影响其他行项目。 3. 在增强中避免复杂的逻辑,以免影响性能或导致过账错误。 相关问题: 1. 如何确定在MIRO中修改的是哪一行?因为可能有多个行项目。 2. 在BAdI `INVOICE_UPDATE`中,除了SGTXT,还可以修改哪些字段? 3. 用户出口`MRM00001`在SAP S/4HANA中是否仍然可用? 4. 修改SGTXT字段是否会影响后续的财务凭证显示? 5. 如何测试这个增强? 现在,我们根据上述内容组织回答。</think>### ABAP MIRO发票校验增强:写入BSEG-SGTXT字段的解决方案 在MIRO发票校验中修改BSEG-SGTXT(行项目文本)字段,可通过以下方法实现: --- ### 1. **使用BADI `INVOICE_UPDATE`(推荐方案)** 在`CHANGE_AT_SAVE`方法中直接修改DRSEG内表的SGTXT字段: ```abap METHOD if_ex_invoice_update~change_at_save. LOOP AT change_t_drseg ASSIGNING FIELD-SYMBOL(<ls_drseg>). " 根据条件修改行项目文本 IF <ls_drseg>-lifnr = 'V10001' AND <ls_drseg>-koart = 'K'. " 供应商行项目 <ls_drseg>-sgtxt = '紧急付款-2024Q3'. " 直接修改SGTXT字段 ENDIF. ENDLOOP. ENDMETHOD. ``` **原理**: DRSEG内表与BSEG结构映射关系为: $$ \text{DRSEG} \xrightarrow{\text{过账}} \text{BSEG} $$ 修改的SGTXT值将在过账时自动写入BSEG表[^1]。 --- ### 2. **用户出口 `MRM00001`(传统方案)** 在包含文件`ZXM08U16`中修改BSEG内表: ```abap FORM user_exit_modify_bseg TABLES ct_bseg STRUCTURE bseg. LOOP AT ct_bseg ASSIGNING FIELD-SYMBOL(<ls_bseg>). " 根据凭证类型和公司代码修改 IF <ls_bseg>-bstat = ' ' AND " 未清项 <ls_bseg>-blart = 'RE' AND " 发票凭证类型 <ls_bseg>-bukrs = '1000'. " 公司代码 <ls_bseg>-sgtxt = |{ sy-datum } 批次处理|. ENDIF. ENDLOOP. ENDFORM. ``` --- ### 3. **关键注意事项** 1. **字段长度限制** SGTXT字段最大长度50字符,需添加校验: ```abap IF strlen( lv_text ) > 50. MESSAGE e001(zfi) WITH '文本超长'. ENDIF. ``` 2. **行项目识别** 使用组合键精确定位行项目: $$ \text{定位键} = \{\text{BUKRS}, \text{GJAHR}, \text{BELNR}, \text{BUZEI}\} $$ 3. **增强冲突避免** 通过条件判断避免与其他增强冲突: ```abap IF <ls_drseg>-sgtxt IS INITIAL. " 仅当原文本为空时修改 <ls_drseg>-sgtxt = lv_custom_text. ENDIF. ``` 4. **性能优化** 使用`FIELD-SYMBOL`替代`WORK AREA`提升性能: ```abap ASSIGN ct_bseg[ bukrs = '1000' buzei = 1 ] TO FIELD-SYMBOL(<fs_line>). IF sy-subrc = 0. <fs_line>-sgtxt = '首行文本'. ENDIF. ``` --- ### 调试技巧 1. **断点设置位置**: - BAdI实施:`CL_EXM_IM_INVOICE_UPDATE` - 用户出口:`SAPLMRM1` → `ZXM08U16` 2. **日志记录**: ```abap DATA(lt_log) = VALUE bal_t_msg( ( msgty = 'I' msgid = 'ZFI' msgno = '001' msgv1 = |SGTXT修改: { <ls_drseg>-sgtxt }| ) ). CALL FUNCTION 'BAL_LOG_MSG_ADD' EXPORTING i_s_msg = lt_log. ``` --- ### 方案对比 | 方法 | 适用版本 | 修改实时性 | 复杂度 | |--------------------|--------------|------------|--------| | `INVOICE_UPDATE` | ECC 6.0+ | 过账前修改 | ★★☆ | | `MRM00001` | 所有SAP版本 | 过账前修改 | ★★★ | --- ### 相关问题 1. 如何通过MIRO屏幕字段值动态生成SGTXT文本? 2. 修改SGTXT字段是否影响财务凭证的校验规则? 3. 在S/4HANA中ACDOCA表是否需要同步更新SGTXT? 4. 如何批量修改历史发票凭证的SGTXT字段? 5. 用户出口`MRM00001`和BADI `INVOICE_UPDATE`能否同时使用? [^1]: INVOICE_UPDATE BAdI的DRSEG-BSEG映射机制
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值