执行顺序:先行项目替代后完全凭证替代然后执行校验。
区别 :F-02回车即执行行项目替代,保存凭证触发完全凭证替代 。
VF01/MIRO/AFAB BADI AC_DOCUMENT VF01/MIRO/HR 不经过GGB1的替代,所以可能需要对BADI: AC_DOCUMENT , BTE 或者POST_DOCUMENT 进行增强。
一、替代和校验的作用
校验( validation ) :在凭证保存前根据设置条件判断此凭证是否有效,其中可以按抬头、行项目或者完全凭证来判断,后再根据valication 设置的消息消息类型决定凭证是否允许保存。
SAP 校验是对在系统输入的 数据按照规则设定检验是否正确,可以按抬头、行项目或完全凭证来判断,然后根据validation 设置的消息类型决定凭证是否允许保存,(取消、错误、警告、信息 ),通过事物代码OB28和GGB0实现。
事务步骤:
1、SE38 将RGGBR000复制为ZRGGBR000,
2、事务GCX2,维护应用区域GBLR推出程序ZRGGBR000,
3、GGB0维护有效性校验
4、GGB4/OB28 激活有效性验证,分配公司代码
替代( substitution ) : 在凭证保存前根据设置条件判断此凭证是否生效,然后根据替代规则将原有的字段替换成当前的字段。
SAP 替代是对某个字段或者内容根据一定的条件判断后替换设定的值,该替代量可以是一个常量值,也可以是变量,还可以通过出口form来完成替换,通过OBBH和GGB1实现。
事务步骤:
1、SE38 将RGGBS000复制为ZRGGBS000,
2、事务GCX2,维护应用区域GBLR推出程序ZRGGBS000,
3、GGB0维护有效性校验
4、GGB4/OBBH 激活替代,分配公司代码
校验和替代的区别: 确认是在按条件判断的时候直接做校验,举个例子说,如果一个凭证不符合确认的校验规则,那么就出现提示。而替代,是直接替换成新值。
二、总结:
SAP标准并不是所有字段都可以完成替代和校验的
SE11 ( GB01 ) 可以查看哪些字段可以完成凭证抬头、行项目、完全凭证替代或校验;
如果SAP标准不能用于替代或验证字段可以通过SM30(V_GB01C)修改该字段,使其可以用于替代或验证;
FI自动替代(substitution)时怎样把BESG表里的某个字段放出来:SM30->VWTYGB01,SE16N GB01 编辑可替代字段 EXCLUDE= 'X'改为GB01-BEXCLUDE = ' '(把X去掉),
验证或替代**后,SE38运行程序RGUGBR00生成替代和验证程序代码;
三、替代和校验怎么调试:
替代:GGB1;单击创建的替换,输入 =SHCB , 回车
校验:GGB0,单击创建的校验,输入 =SHCD , 回车
[原创]SAP方丈-SAP的确认与替代 - SAP财务管控:财务总监背后的管理大师 - 畅享博客
替代和校验出口:
添加替代出口form的search help
在复制出来的 ZRGGBS000中添加title。
在 get_exit_titles 中添加如下代码。
然后如果替换的是单个字段
多个字段
FORM us902 .
DATA:lv_zzassacc01 TYPE bseg-zzassacc01,
ls_xbseg TYPE bseg,
BEGIN OF gt_invoice OCCURS 0,
bukrs TYPE epic_s_ebr_claim_invc-bukrs,
belnr TYPE epic_s_ebr_claim_invc-belnr,
gjahr TYPE epic_s_ebr_claim_invc-gjahr,
buzei TYPE epic_s_ebr_claim_invc-buzei,
END OF gt_invoice,
* BEGIN OF gs_prl_item ,
* bukrs TYPE fprl_item-zbukr,
* belnr TYPE fprl_item-inv_no,
* gjahr TYPE fprl_item-inv_year,
* buzei TYPE fprl_item-inv_item,
* END OF gs_prl_item,
* gt_prl_item LIKE TABLE OF gs_prl_item.
gt_0028 TYPE TABLE OF zfit0028,
gs_0028 LIKE LINE OF gt_0028.
DATA: ls_postab TYPE rfops,
ls_rsgtab TYPE irsgtab,
ls_postab2 TYPE rfops.
DATA lt_postab2 TYPE TABLE OF rfops WITH HEADER LINE.
DATA: BEGIN OF lt_bseg OCCURS 0,
blart TYPE bkpf-blart.
INCLUDE STRUCTURE bseg.
DATA: END OF lt_bseg.
CONSTANTS: c_xbseg(85) VALUE '(SAPMF05A)XBSEG[]'.
FIELD-SYMBOLS:<xbseg> TYPE STANDARD TABLE.
CONSTANTS: c_postab(85) VALUE '(SAPMF05A)POSTAB[]'.
FIELD-SYMBOLS:<postab> TYPE STANDARD TABLE.
CONSTANTS: c_rsgtab(85) VALUE '(SAPMF05A)RSGTAB[]'.
FIELD-SYMBOLS:<rsgtab> TYPE STANDARD TABLE.
CONSTANTS: c_postab2(85) VALUE '(SAPMF05B)POSTAB[]'.
FIELD-SYMBOLS:<postab2> TYPE STANDARD TABLE.
ASSIGN (c_postab2) TO <postab2>[].
ASSIGN (c_postab) TO <postab>[].
ASSIGN (c_rsgtab) TO <rsgtab>[].
ASSIGN (c_xbseg) TO <xbseg>[].
IF <xbseg> IS ASSIGNED.
IF bkpf-tcode = 'FB05' AND bseg-bschl NE '40' AND bseg-bschl NE '50' AND bseg-zzassacc01 IS INITIAL.
CLEAR lv_zzassacc01.
* SELECT SINGLE zzassacc01 FROM bseg INTO lv_zzassacc01 WHERE bukrs = bseg-bukrs
* AND belnr = bseg-belnr
* AND gjahr = bseg-gjahr
* AND zzassacc01 NE ''
LOOP AT <xbseg> INTO ls_xbseg .
IF ls_xbseg-zzassacc01 IS NOT INITIAL.
lv_zzassacc01 = ls_xbseg-zzassacc01.
EXIT.
ENDIF.
ENDLOOP.
.
IF lv_zzassacc01 IS NOT INITIAL.
bseg-zzassacc01 = lv_zzassacc01.
ELSE.
IF <postab> IS ASSIGNED.
LOOP AT <postab> INTO ls_postab.
SELECT SINGLE zzassacc01 FROM bseg INTO lv_zzassacc01 WHERE bukrs = ls_postab-bukrs AND belnr = ls_postab-belnr AND gjahr = ls_postab-gjahr AND buzei = ls_postab-buzei.
IF lv_zzassacc01 IS NOT INITIAL.
bseg-zzassacc01 = lv_zzassacc01.
EXIT.
ENDIF.
ENDLOOP.
ENDIF.
ENDIF.
*ADD 20210312 增加预收款
* 记录:SAPLZEPIC_EBR程序 INCLUDE LZEPIC_EBRI04中106行 内存变量 GT_INVOICE
ELSEIF bkpf-tcode = 'FBA1' AND bseg-bschl NE '40' AND bseg-bschl NE '50' AND bseg-zzassacc01 IS INITIAL.
CLEAR lv_zzassacc01.
LOOP AT <xbseg> INTO ls_xbseg .
IF ls_xbseg-zzassacc01 IS NOT INITIAL.
lv_zzassacc01 = ls_xbseg-zzassacc01.
EXIT.
ENDIF.
ENDLOOP.
.
IF lv_zzassacc01 IS NOT INITIAL.
bseg-zzassacc01 = lv_zzassacc01.
ELSE.
IMPORT gt_invoice FROM MEMORY ID 'GT_INVOICE' .
IF gt_invoice[] IS NOT INITIAL.
LOOP AT gt_invoice .
SELECT SINGLE zzassacc01 FROM bseg INTO lv_zzassacc01 WHERE bukrs = gt_invoice-bukrs AND belnr = gt_invoice-belnr AND gjahr = gt_invoice-gjahr AND buzei = gt_invoice-buzei.
IF lv_zzassacc01 IS NOT INITIAL.
bseg-zzassacc01 = lv_zzassacc01.
EXIT.
ENDIF.
ENDLOOP.
ENDIF.
ENDIF.
*ADD 20210203 增加AB款项性质
ELSEIF ( bkpf-tcode = 'FB1K' OR bkpf-tcode = 'FB1D' ) AND bseg-zzassacc01 IS INITIAL.
* IF <rsgtab> IS ASSIGNED.
IF <postab2> IS ASSIGNED.
REFRESH lt_postab2.
LOOP AT <postab2> INTO ls_postab2 .
CASE bkpf-tcode.
WHEN 'FB1D'.
IF ls_postab2-xragl = 'X'.
CLEAR lt_postab2.
MOVE-CORRESPONDING ls_postab2 TO lt_postab2.
APPEND lt_postab2.
ENDIF.
WHEN 'FB1K'.
IF ls_postab2-xaktp = 'X'.
CLEAR lt_postab2.
MOVE-CORRESPONDING ls_postab2 TO lt_postab2.
APPEND lt_postab2.
ENDIF.
ENDCASE.
ENDLOOP.
LOOP AT lt_postab2 INTO ls_postab2.
* IF ls_postab2-belnr EQ bseg-rebzg.
SELECT * FROM bkpf
INNER JOIN bseg ON bkpf~belnr EQ bseg~belnr
INTO CORRESPONDING FIELDS OF TABLE @lt_bseg WHERE bseg~bukrs = @ls_postab2-bukrs AND
bseg~belnr = @ls_postab2-belnr AND
bseg~gjahr = @ls_postab2-gjahr AND
bseg~buzei = @ls_postab2-buzei
* bkpf~blart EQ 'AB'
.
IF lt_bseg[] IS INITIAL.
SELECT * FROM bkpf
INNER JOIN bseg ON bkpf~belnr EQ bseg~belnr
INTO CORRESPONDING FIELDS OF TABLE @lt_bseg WHERE bseg~bukrs = @ls_postab2-bukrs AND
bseg~belnr = @ls_postab2-belnr AND
bseg~gjahr = @ls_postab2-gjahr
* bkpf~blart EQ 'AB'
.
ENDIF.
IF lt_bseg[] IS NOT INITIAL.
LOOP AT lt_bseg INTO DATA(ls_bseg) WHERE zzassacc01 IS NOT INITIAL .
bseg-zzassacc01 = ls_bseg-zzassacc01.
EXIT.
ENDLOOP.
ENDIF.
* ENDIF.
ENDLOOP.
*凭证对应的清账凭证不为空且不相等的,则给清账凭证带入对应凭证的款项性质
IF bseg-zzassacc01 IS INITIAL.
SELECT * FROM bkpf
INNER JOIN bseg ON bkpf~belnr EQ bseg~belnr
INTO CORRESPONDING FIELDS OF TABLE @lt_bseg WHERE bseg~bukrs = @ls_rsgtab-bukrs AND
bseg~belnr = @ls_rsgtab-belnr AND
bseg~gjahr = @ls_rsgtab-gjahr
* bkpf~blart EQ 'AB'
.
IF lt_bseg[] IS NOT INITIAL.
LOOP AT lt_bseg INTO ls_bseg WHERE zzassacc01 IS NOT INITIAL .
bseg-zzassacc01 = ls_bseg-zzassacc01.
EXIT.
ENDLOOP.
ENDIF.
ENDIF.
ENDIF.
ENDIF.
ENDIF.
IF bkpf-blart = 'ZP' AND ( bseg-bschl = '25' OR bseg-bschl = '29') AND bseg-zzassacc01 = ''.
*ADD BY DC_ABAP01 20210311 银行直连付款存在合并付款,需要轮询查找行上的款项性质:
*记录: 隐式增强ZEXIT_EPIC_DOWNLOAD cl_epic_pi_uil=>_action_pay_and_send_file( ) 中存表zfit0028
* IMPORT gt_prl_item FROM MEMORY ID 'GT_PRL_ITEM' .
SELECT * INTO CORRESPONDING FIELDS OF TABLE gt_0028
FROM zfit0028.
LOOP AT gt_0028 INTO gs_0028.
SELECT SINGLE zzassacc01 FROM bseg INTO bseg-zzassacc01 WHERE bukrs = gs_0028-bukrs
AND belnr = gs_0028-belnr
AND gjahr = gs_0028-gjahr
AND buzei = gs_0028-buzei.
IF bseg-zzassacc01 IS NOT INITIAL.
EXIT.
ENDIF.
ENDLOOP.
IF bseg-zzassacc01 IS INITIAL.
LOOP AT gt_0028 INTO gs_0028.
SELECT SINGLE zzassacc01 FROM bseg INTO bseg-zzassacc01 WHERE bukrs = gs_0028-bukrs
AND belnr = gs_0028-belnr
AND gjahr = gs_0028-gjahr.
IF bseg-zzassacc01 IS NOT INITIAL.
EXIT.
ENDIF.
ENDLOOP.
ENDIF.
ENDIF.
ENDFORM.
四、补充
1、替代的三种方法
1)、常量
是指满足条件时,指定这个字段的内容为定值
2)、退出
是指留出出口,ABAPer对这个字段进行处理
3)、字段-字段分配
是指将一个已经有的字段内容,赋给需要替代的内容。
2、c_exit_param_none,c_exit_param_field,c_exit_param_class 区别
c_exit_param_field -- 只能用于此字段的修改,只能用于替代,并且是以字段为返回
c_exit_param_field,c_exit_param_class 都是可以用于规则,确认,和替代,而且是以内表,结构的形式进行替代。
但是c_exit_param_field,c_exit_param_class 是以形式参数的替代,
必须使用 PERFORM us901 USING p_budat / t_bseg 等。
c_exit_param_none 则不用。
3、新增替代的时候选择字段还是出口
唯一退出只可以选择c_exit_param_class,同时这部分只能用于完全凭证的替代,不能使用FI和LC凭证
表+字段的只可以选择c_exit_param_field 或c_exit_param_none
如果选错了,会报如下错误