SAP allows customer additions to their own tables, for many of the main documents. E.g. the purchase order can hold data on tables EKKO
and EKPO
, which can also be maintained via a BAPI call to BAPI_PO_CHANGE
. The concept of a BAPI is allowing changes to a document via a programming interface (e.g. a function module). But how should SAP know which fields are added on the customer's site ? How should these fields be made changeable via function module parameters ? SAP's answer: the extension.
Extensions is a concept for allowing changes to non SAP-standard fields, used by several BAPI's. The example outlined here is for BAPI_PO_CHANGE
but also applies to many other BAPIs. The main components of extensions:
- Function module
BAPI_PO_CHANGE
has a tables parameter fieldEXTENSIONIN STRUCTURE BAPIPAREX OPTIONAL
. This table is used to hold the customer field changes for both the PO header (EKKO
) and the PO item (EKPO
). - Much like segments on an Idoc, the
EXTENSIONIN
structure holds a field calledSTRUCTURE
which is used to identify whether the entry is about the header fields (ekko), header field-update flags, item-fields (ekpo) or item fields update flags. - Again much like the Idoc segment concept, the actual data is set up on the
VALUEPART1
through toVALUEPART4
fields (which act much like theSDATA
field on tableEDIDD
. The Value-part fields act like a buffer field for the contents of the complete customer data extension (all fields concatenated together like held onEKKO
orEKPO
). - Like with standard SAP fields, the customer fields require an indicator to be checked, to enable the bapi to differentiate between clearing a field and leaving a field unchanged. Extensions work the same way, for the extension PO item fields, the actual field value (new value) must be maintained on
EXTENSIONIN
, and the field should be flagged for change on theEXTENSIONIN
next entry.
An example should clarify how this all hangs together:
A simple example which updates a customer field in the header of the PO. Data declaration and BAPI call preparation. Make sure the variabele p_ebeln is filled with a valid PO number...
DATA: p_ebeln like ekko-ebeln. DATA: i_return type table of bapiret2 with header line, BAPI_TE_MEPOHEADER LIKE BAPI_TE_MEPOHEADER, BAPI_TE_MEPOHEADERX LIKE BAPI_TE_MEPOHEADERX. FIELD-SYMBOLS: <WA> TYPE ANY. clear i_extensionin. clear BAPI_TE_MEPOHEADER. i_extensionin-STRUCTURE = 'BAPI_TE_MEPOHEADER'. BAPI_TE_MEPOHEADER-po_number = p_ebeln. BAPI_TE_MEPOHEADER-z_ownfield= 'MYVALUE'. ASSIGN i_extensionin-VALUEPART1 TO <WA> CASTING TYPE BAPI_TE_MEPOHEADER. <WA> = BAPI_TE_MEPOHEADER. APPEND i_extensionin. clear i_extensionin. clear BAPI_TE_MEPOHEADERX. i_extensionin-STRUCTURE = 'BAPI_TE_MEPOHEADERX'. BAPI_TE_MEPOHEADERX-po_number = p_ebeln. BAPI_TE_MEPOHEADERX-z_ownfield = 'X'. ASSIGN i_extensionin-VALUEPART1 TO <WA> CASTING TYPE BAPI_TE_MEPOHEADERX. <WA> = BAPI_TE_MEPOHEADERX. APPEND i_extensionin. |
Above the extension fields are added, the first line from this table holds the actual field change, the second line indicates which field should be changed. Now call the BAPI and respond with the error (if there is one):
CALL FUNCTION 'BAPI_PO_CHANGE' EXPORTING PURCHASEORDER = p_ebeln TABLES RETURN = I_RETURN * POITEM = p_poitem * POITEMX = p_poitemX EXTENSIONIN = i_extensionin. read table i_return with key type = 'E'. if sy-subrc ne 0. read table i_return with key type = 'A'. endif. if sy-subrc ne 0. * Commit changes to database call function 'BAPI_TRANSACTION_COMMIT'. write: 'Call succesful'. else. write: / i_return-message. exit. endif. |
If the total size of the customer fields in an extension is bigger than the contents of the VALUEPART1
field, the second valuepart should be filled (as well). How ? Well, the same rules apply as described in the article above, except for the use of a field symbol to move field contents into the VALUEPART1
field. Check out the above example.