三个月精通ABAP(4)

用户增强: 所有的Enhancement在表MODSAP,用户增强大概有三类

MODSAP是Enhancement表, 而TFDIR是看是否此enhancement被激活,就看字段MAND是否是"C"而已

1. E Enhancement exits :就是常说的写User_exit

2. C GUI codes 没用过

3. 3. S Subscreens 屏幕增强

OK,其实上面不用coding, 通过search MODSAP发现EXIT_SAPMM06E_013 在Enhancement MM06E005中.

使用T-code :SMOD F8 test运行然后可激活EXIT_SAPMM06E_013 ,如果你确实找不到enhancement name和exit函数对应关系,也没关系. 使用SMOD自己建立一个Enhancement 比如叫

ZPOSO ,然后你将function 加入,它也会有错误提示告诉你它属于的enhancement,还有就是使用上面的code直接update .

你自己可写个code将所有的user_exit找出来,很容易的哟.如你完全明白这篇文章,我想你就理解了user_exit 和BAPI的使用. 建立BAPI并使用其它语言call同样很简单.

EXIT_SAPMM06E_013 include程序 ZXM06U44

在coding前使用SE37 test BAPI :BAPI_SALESORDER_CREATEFROMDATA

***注意各企业因为设置的fields status不同可能有所不同.

对ORDER_HEADER_IN只需下面几个参数

ORDER_ITEMS_IN只需要MATERIAL,REQ_QTY-(Order qty in sales units - 00009001 corresponds to 9.001,就是说call BAP REQ_QTY测试时= actual qty * 1000)

, COND_TYPE, COND_VALUE,(即对应到price很奇怪必须/10, 不知其他系统是否这样,此是注意点)

PO_METH_S(Ship-to party purchase order type,如果设置了必须输入的话),

ORDER_PARTNERS如果SP和SH相同的话,只要一条SP然后输入customer No就可,如果ship-to-party不同多家一条SH+customer No.吧.

还有一样要注意. AG-SP, RE-BP

-SH (SAP经常有这样的case,就是save在DB中的数据和display出来的数据有所不同, 为什么要这样, 不得而知,难怪SAP不推荐直接使用DB table 做报表,或者这是SAP AG的一个策略)

测试OK.开始coding on ZXM06U44, Source code 如下,log写在ZPOSO表中.

测试使用BAPI_SALESORDER_CHANGE

就是说它实际是call BAPI_SALESDOCUMENT_CHANGE的

你可知道ORDER_HEADER_INX-UPDATEFLAG为U时是update,为D时是Delete sales order,不选还不行.

好了下面是Source Code(仅供参考,大体框架OK,可能根据你的SAP实际情况做些调整) .

*----------------------------------------------------------------------*

* INCLUDE ZXM06U44

* 在company 1000建立PO时同时建立SO in 1000和PO in 2000 *

* 注意此程序会反复call .

*----------------------------------------------------------------------*

data:

ZORDER_HEADER_IN like BAPISDHEAD ,

ZORDER_ITEMS_IN like BAPIITEMIN occurs 0 with header line ,

ZORDER_PARTNERS like BAPIPARTNR occurs 0 with header line ,

ZSALESDOCUMENT like BAPIVBELN-VBELN ,

ZRETURN like BAPIRETURN .

Data:

ZPOHEADER like BAPIEKKOC ,

ZPOITEMS like BAPIEKPOC occurs 0 with header line,

ZPO_ITEM_SCHEDULES like BAPIEKET occurs 0 with header line,

ZPURCHASEORDER like BAPIEKKOC-PO_NUMBER .

tables :ZPOSO .

data zposolog like zposo occurs 0 with header line.

data : Zrepcall(1) type C. "防止反复调用BAPI_PO_CREATE.

Refresh : ZORDER_ITEMS_IN .

*** 实际应用根据I_EKKO-EBELN(其实从EBELN-PO No.可判断出plant)

*** 1.I_EKKO-EBELN前面5位用case语句判断

*** 2.根据I_EKKO-BUKRS(comp. code)和XEKPO-WERKS(plant)判断

*** company code 2000是专门用来采购的HK 公司.

*if I_EKKO-BUKRS <> '1000'.

* exit.

*endif.

check I_EKKO-BUKRS eq '1000'. "只对comp 1000适用.

***判断表ZPOSO有无PO no.无call BAPI_SALESORDER_CREATEFROMDATA create SO

*** 如果存在call BAPi BAPI_SALESORDER_CHANGE change SO.

***注意在ME22N change PO时间XEKPO内表中只保留了被改变line item的数据.

select single * from ZPOSO where EBELN eq I_EKKO-EBELN.

if sy-subrc eq 0 .

* Change Sales Order,Purchase Order留给你自己写不告诉你

*CALL FUNCTION 'BAPI_SALESORDER_CHANGE'

*CALL FUNCTION 'BAPI_PO_CHANGE'

else . "建立Purchase Order 和Sales Order

*** 从ZFLAG表中读取Zrepcall看是否是T, 不管使用什么方法总之不要反复

**在此处设置断点在第二次调用时将Zrepcall设成T退出.

**好象无法设置到那种真正的全局变量只好使用一个表罗

**你就会发现当在comp 1000建立PO同时也建立了SO并且comp 2000也有PO

*select single Zrepcall into Zrepcall from zflag .

if Zrepcall = 'T' .

exit .

endif.

***注意使用PO另一个user_exit 001将Zflag的zrepcall设置成F

***接下来的语句立即update zflag将zrepcall设置成T.

***----------------------------------------------***

*** 开始建立Purchase Order in company 2000 ***

***----------------------------------------------***

***----------------------------------------------***

*** 开始建立Sales Order in same company 1000 ***

***----------------------------------------------***

***根据公司实际更改ZOR是标准Sales order

***----Sales Order Header --- ***

ZORDER_HEADER_IN-DOC_TYPE = 'ZOR'.

ZORDER_HEADER_IN-SALES_ORG = '1100'.

ZORDER_HEADER_IN-DISTR_CHAN = '11'.

ZORDER_HEADER_IN-DIVISION = '11'.

ZORDER_HEADER_IN-CURRENCY = I_EKKO-WAERS. "Order currency

ZORDER_HEADER_IN-PURCH_NO = I_EKKO-EBELN .

***---Purchase Order Header ---***

ZPOHEADER-PURCH_ORG = I_EKKO-EKORG. "正式使用换2000的采购组织

ZPOHEADER-PUR_GROUP = I_EKKO-EKGRP . "正式使用换comp2000的采购组

ZPOHEADER-CO_CODE = '2000' .

ZPOHEADER-VENDOR = I_EKKO-LIFNR .

ZPOHEADER-DOC_TYPE = 'NB' . "I_EKKO-BSART.

***根据PO item写入SO item和另家公司的PO items

loop at XEKPO .

***----写SO items ---***

ZORDER_ITEMS_IN-ITM_NUMBER = XEKPO-EBELP .

* 使PO item NO和SO item No完全相对应,PO,SO item可manual input.

ZORDER_ITEMS_IN-MATERIAL = XEKPO-MATNR. "'08K2555'.

ZORDER_ITEMS_IN-REQ_QTY = XEKPO-MENGE .

ZORDER_ITEMS_IN-REQ_QTY = ZORDER_ITEMS_IN-REQ_QTY * 1000 .

* Call SO BAPI时Qty 测试时间必须乘上1000.ABAP中则不用

ZORDER_ITEMS_IN-COND_TYPE = 'ZPR1'. "ZPR1是EST定义的price cond.

ZORDER_ITEMS_IN-COND_VALUE = XEKPO-NETPR.

ZORDER_ITEMS_IN-COND_VALUE = ZORDER_ITEMS_IN-COND_VALUE / 10 .

*Call SO BAPI test时Price必须/10

ZORDER_ITEMS_IN-PO_METH_S = '010' . "表示是维修期,EST设置成必输字段.

Append ZORDER_ITEMS_IN .

***---写另公司的PO items,如果有必要让俩公司PO外部给号PONo可一致---***

ZPOITEMS-PUR_MAT = XEKPO-MATNR.

ZPOITEMS-PLANT = XEKPO-WERKS .

ZPOITEMS-NET_PRICE = XEKPO-NETPR.

***仅仅是test,注意XEKET,shedules delivery date 没item不同哟.自己去加强吧

ZPO_ITEM_SCHEDULES-DELIV_DATE = SY-DATUM . " XEKET-EINDT

ZPO_ITEM_SCHEDULES-QUANTITY = XEKPO-MENGE .

append ZPOITEMS .

append ZPO_ITEM_SCHEDULES .

endloop.

***为了简单就将SP-Sold_to_Party和SH-Ship_to_Party设置成相同.

***AG-SP:sold_to WE:SH Shipping-to,BAPI测试只要SP,call时则要求俩者

***下面假设PO vendor no就是SO 的customer no,如非就建立对应关系.

ZORDER_PARTNERS-PARTN_ROLE = 'AG'.

ZORDER_PARTNERS-PARTN_NUMB = I_EKKO-LIFNR.

***实际应用时HK开PO时产生的SO customer当然只有一个就是SZ公司.

Append ZORDER_PARTNERS .

ZORDER_PARTNERS-PARTN_ROLE = 'WE'.

ZORDER_PARTNERS-PARTN_NUMB = I_EKKO-LIFNR.

Append ZORDER_PARTNERS .

CALL FUNCTION 'BAPI_SALESORDER_CREATEFROMDATA'

EXPORTING

ORDER_HEADER_IN = ZORDER_HEADER_IN

IMPORTING

SALESDOCUMENT = ZSALESDOCUMENT

* SOLD_TO_PARTY =

* SHIP_TO_PARTY =

* BILLING_PARTY =

RETURN = ZRETURN

TABLES

ORDER_ITEMS_IN = ZORDER_ITEMS_IN

ORDER_PARTNERS = ZORDER_PARTNERS

* ORDER_ITEMS_OUT =

* ORDER_CFGS_REF =

* ORDER_CFGS_INST =

* ORDER_CFGS_PART_OF =

* ORDER_CFGS_VALUE =

* ORDER_CFGS_BLOB =

* ORDER_CCARD =

.

if ZSALESDOCUMENT <> '' .

loop at XEKPO .

zposolog-ebeln = I_EKKO-EBELN. "PO No.

zposolog-ebelp = XEKPO-EBELP. "PO item No.

zposolog-vbeln = ZSALESDOCUMENT."SO No.

zposolog-posnr = XEKPO-EBELP . "SO Item NO.

zposolog-waers = I_EKKO-WAERS . "Currency

zposolog-matnr = XEKPO-MATNR . "Material

zposolog-kwmeng = XEKPO-MENGE. "PO/SO qty

zposolog-netpr = XEKPO-netpr. "PO/SO price

zposolog-bapimsg = 'Creation OK' . "ZRETURN-MESSAGE .

zposolog-flag = 'T'. "Failure

append zposolog .

insert ZPOSO from zposolog.

endloop.

else.

zposolog-ebeln = I_EKKO-EBELN.

* zposolog-bapimsg = ZRETURN-MESSAGE .

***为了好SE91查找message合并message type, messge code,和message text

concatenate ZRETURN-TYPE '--' ZRETURN-CODE '--:' ZRETURN-MESSAGE into

zposolog-bapimsg .

zposolog-flag = 'F'. "Failure

append zposolog .

insert ZPOSO from zposolog.

endif.

***----------------------PO可能会反复调用吗---------------------

*** 不管如何做到call一次就退出.

*** 建立一表ZFLAG, 可只有一个字段, Zrepcall,default是F,

CALL FUNCTION 'BAPI_PO_CREATE'

EXPORTING

PO_HEADER = ZPOHEADER

* PO_HEADER_ADD_DATA =

* HEADER_ADD_DATA_RELEVANT =

* PO_ADDRESS =

* SKIP_ITEMS_WITH_ERROR = 'X'

* ITEM_ADD_DATA_RELEVANT =

IMPORTING

PURCHASEORDER = ZPURCHASEORDER "好瞧瞧

TABLES

PO_ITEMS = ZPOITEMS

* PO_ITEM_ADD_DATA =

PO_ITEM_SCHEDULES = ZPO_ITEM_SCHEDULES

* PO_ITEM_ACCOUNT_ASSIGNMENT =

* PO_ITEM_TEXT =

* RETURN =

* PO_LIMITS =

* PO_CONTRACT_LIMITS =

* PO_SERVICES =

* PO_SRV_ACCASS_VALUES =

* PO_SERVICES_TEXT =

* PO_BUSINESS_PARTNER =

* EXTENSIONIN =

* POADDRDELIVERY =

.

Endif. "结束建立Purchase Order 和Sales Order

你可能感兴趣的:(abap)