在标准SAP业务应用中常会修改标准程序和增加一些自己的功能代码来满足特定化的需求,SAP提供了一些出口对特定的程序、屏幕、MENU以及Document进行扩展与修改,他们并不包含任何功能,并被分离存在特定的package里所以他既不会影响标准SAP源代码也不会妨碍升级。除了通过后台配置客户化,我们常用主要有三种用户出口来进行Enhancement和Modification:
1. User Exit
最早的出口嵌写在标准程序里,修改起来也最为复杂。如VA01/VA02 Sales Order处理上使用的SAPMV45A中就包含大量ZZ或YY结尾的user exit程序MV45AFZZ/MV45AIZZ。
2. Customer Exit
主要有三种类型Menu Exit/Screen Exit/FM Exit,
首先通过CMOD来创建一个Project然后指定所需要的Enhancement,然后指定Component并激活。最后则需要加些所需代码在自动创建一个Z程序里。
3. BADI增强
SE18/SE19,正如引入了OO的技术,在定义与实现在与Customer Exit两层是一样的,能客户化用户想用的标准解决方案的逻辑,对于开发者主要是通过一些方法来找到合适的BADI。
用户接口(user exit)就是SAP提供的一些Form, 这些Form会在特定的时候被标准程序Call到。标准系统里面这些Form是空的,用户可以根据自己的业务要求添加程序进去,不过这些程序需要用户自己承担风险,因为User exit其实也属于Modification的一种。那么对各个User exit越了解,出错的可能性就越小,所以在这篇日志中我们来谈谈SD sales这个流程中用到的User exit的用途,应用以及信息输出。
FORM routine USEREXIT_REFRESH_DOCUMENT (Include MV45AFZA)
用途:FORM routine USEREXIT_REFRESH_DOCUMENT可以在创建或者处理新订单之前,对用户自定义的数据进行初始化。
Call:此接口被BELEG_INITIALISIEREN(SAPMV45A) call。通常这个程序会在订单被保存之后或者是用户选择’Back’ 或’Cancel’ 回到初始画面之前运行。
数据读取:不建议在这个User exit里面进行订单数据的读取,后果不祥。
信息输出:在这个User exit里面输出错误信息没有意义。
FORM routine USEREXIT_DELETE_DOCUMENT (Include MV45AFZZ)
用途:当一个销售订单被删除的时候,您可以通过这个接口来删除您自己定义的一些独立数据。
Call:此接口实在销售订单能够被完全删除的时候在BELEG_LOESCHEN (SAPMV45A) 中被call到。它紧接着FORM
routine USEREXIT_DELETE_DOCUMENT。
数据读取:可以在此接口中读取到理论上已经被删除(数据库还未更新)的销售订单数据。构造VBAK中储存了抬头信息。
内表XVBAP中储存了将要被删除的项目信息,包括删除前用户对项目进行的最后修改,每个项目的变更指示(UPDKZ)都是“D”.
内表YVBAP中包含了所有项目的信息。
内表XVBUP,XVBPA中已经不包含任何当前订单的信息。存在数据库上的数据可以在YVBUP和YVBPA中查到。
内标XVBUK仍然存在,YVBUK不存在。
在此接口中对内表进行操作会引发数据不一致,因此不推荐。
信息输出:错误信息的输出在USEREXIT_DELETE_DOCUMENT中应被限制。在此接口中不可以输出E或者W信息。可能会引发Dump DYNPRO_MSG_IN_HELP .
附加信息:当此接口被Call到的时候,删除销售订单的这个操作已经无法被避免,因为理论上数据都已经删除了。如果必须要求停止删除的操作,那么可以用信息类型A来强制中止运行。
FORM routine USEREXIT_READ_DOCUMENT (Include MV45AFZZ)
用途:这个接口用来读取您自己的数据以便于后续进行订单处理。
Call:此接口会在变更或者显示订单的时候被Call到。
数据读取:在此接口中可以读取到当前订单所有已经被读取的信息。理论上在此接口中也可以对已经读取的数据进行更改,不过请先阅读在
USEREXIT_SAVE_DOCUEMENT_PREPARE描述中介绍的变更订单的注意事项。
信息输出:基本无限制。不过需要注意这个接口在Background处理的时候也会被Call到。
FORM routine USEREXIT_MOVE_FIELD_TO_VBAK (Include MV45AFZZ)
用途:这个接口用来给您自己添加在VBAK表中的项目付值。
Call:此接口在新订单创建的过程中,在VBAK_FUELLEN(SAPMV45A)的结尾被Call到。
数据读取:在此阶段还读取不到其他数据,因为此订单还在创建过程中。不过当参照其他订单创建销售订单的时候,在这个接口中通过内表CVBAK, CVBAP, CVBPA, CVBEP可以读到被参照订单的数据。读取这些数据的时候请注意保证这些表的表头不被更改,可以把数据导到自定义的构造中处理。
如果您想在此接口中对已经存在的VBAK项目值进行更改,请注意,针对这些项目进行过的检查是需要您重新触发的。请提前进行独立性分析,以避免数据不一致。不推荐在此接口中对VBAK以外的数据进行更改,很容易造成数据不一致。
信息输出:错误信息不允许才此接口直接输出。您可以通过FORM routine MESSAGE_HANDLING (main program SAPMV45A)对信息类型I或者E的信息来创建错误日志(如果是在变更模式下,这些信息将不会被直接输出,而是保存在日志中)。信息类型W的信息是不会被包含在日志中的。
FORM routine USEREXIT_MOVE_FIELD_TO_VBAP(Include MV45AFZZ)
用途:这个接口用来给您自己添加在VBAP表中的项目付值.
Call:这个接口会在创建项目的时候,在VBAP_FUELLEN(参照创建)或者VBAP_FUELLEN_OR(无参照创建)的末尾被Call到。
数据读取:此接口被Call到的时候,表头信息(结构VBAK)和合伙伙伴(内表XVBPA)可以读取到。新项目的状态(VBUP)还不能读取。如果之前已经登录了其他的项目,那么表头的状态可以在XVBUK中读取到。已经存在的项目状态可以在内表XVBUP中读取到。如果您想在此接口中对已经存在的标准表项目值进行更改,请注意,针对这些项目进行过的检查是需要您重新触发的。请提前进行独立性分析,以避免数据不一致。不建议在此接口中对其他表的项目值进行修改。请注意不要更改现有的内表的表头。建议创建您自己的结构来读取内表中的值以确保标准内表不被更改。
信息输出:直接的信息输出是不允许的,会造成数据不一致。您可以通过FORM routine MESSAGE_HANDLING (main program SAPMV45A)对信息类型I或者E的信息来创建错误日志(如果是在变更模式下,这些信息将不会被直接输出,而是保存在日志中)。
FORM routine USEREXIT_SAVE_DOCUMENT_PREPARE (Include MV45AFZZ)
用途:此接口是用途最广泛的接口。可以用来对销售定单中的数据进行最后的修改。当此接口被Call到的时候,这张单子的数据已经完整,只有订单号没有被决定(仅限于创建订单的时候)。因此在此接口中所作的修改一般是不会有后续检查来避免不一致的。
Call:此接口在订单被保存之前在BELEG_SICHERN (SAPMV45A)中被Call到。
数据读取:因为是在订单保存之前被Call到,所有信息都可以在内表中被读取到。现存的值是存在X表中,更改之前的值存在Y表中。
信息输出:如果您想输出信息的话,必须要考虑到这个接口在Background处理的时候也会被Call到。
FORM routine USEREXIT_SAVE_DOCUMENT (Include MV45AFZz)
用途:此接口用来保存您自定义的数据值。标准表中的信息已经不能被更改,因为才此阶段,标准表值已经被传输到更新。
Call:此接口在订单保存过程中,紧挨着Commit work之前被BELEG_SICHERN(SAPMV45A) Call到。
数据读取:跟USEREXIT_SAVE_DOCUMENT_PREPARE 一样,所有信息都可以在内表中被读取到。并且如果是登录订单的情况,订单号也可以读取到。请务必不要在此接口中加入COMMIT WORK 或ROLLBACK WORK 语句。
信息输出:不允许在此接口输出对话信息。因为此处已经非常临近Commit work了。如果业务要求必须中止订单保存,可以使用message type “A”来强行中止。