BAPI_PO_CHANGE Example Generator for SAP ABAP
This generator writes an ABAP program for SAP ECC 6.0 that changes one purchase order item with BAPI_PO_CHANGE: quantity, net price, delivery date on a schedule line, delete, undelete or block. It runs as a test first, checks the return table, and commits only when you untick test run and no errors are returned.
Fill in
QTY quantity, PRIC net price, DATE delivery date, DEL delete, UNDL undelete, BLCK block
Program
REPORT ZMM_PO_CHANGE_BAPI.
PARAMETERS: p_ebeln TYPE ekko-ebeln DEFAULT '4500012345',
p_ebelp TYPE ekpo-ebelp DEFAULT '00010',
p_mode TYPE char4 DEFAULT 'DATE',
p_menge TYPE bapimepoitem-quantity DEFAULT '120',
p_netpr TYPE bapimepoitem-net_price DEFAULT '14.50',
p_peinh TYPE bapimepoitem-price_unit DEFAULT '1',
p_eindt TYPE sy-datum DEFAULT '20261130',
p_etenr TYPE eket-etenr DEFAULT '0001',
p_test AS CHECKBOX DEFAULT 'X'.
DATA: lv_ebeln TYPE ekko-ebeln,
lt_item TYPE STANDARD TABLE OF bapimepoitem,
ls_item TYPE bapimepoitem,
lt_itemx TYPE STANDARD TABLE OF bapimepoitemx,
ls_itemx TYPE bapimepoitemx,
lt_sched TYPE STANDARD TABLE OF bapimeposchedule,
ls_sched TYPE bapimeposchedule,
lt_schedx TYPE STANDARD TABLE OF bapimeposchedulx,
ls_schedx TYPE bapimeposchedulx,
lt_return TYPE STANDARD TABLE OF bapiret2,
ls_return TYPE bapiret2,
lv_extdate TYPE c LENGTH 10,
lv_error TYPE c.
START-OF-SELECTION.
CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
EXPORTING
input = p_ebeln
IMPORTING
output = lv_ebeln.
ls_item-po_item = p_ebelp.
ls_itemx-po_item = p_ebelp.
ls_itemx-po_itemx = 'X'.
CASE p_mode.
WHEN 'QTY'.
* With several schedule lines, change POSCHEDULE quantities instead
ls_item-quantity = p_menge.
ls_itemx-quantity = 'X'.
WHEN 'PRIC'.
ls_item-net_price = p_netpr.
ls_item-price_unit = p_peinh.
ls_itemx-net_price = 'X'.
ls_itemx-price_unit = 'X'.
WHEN 'DATE'.
* DELIVERY_DATE is in external (user) format, so convert first
CALL FUNCTION 'CONVERT_DATE_TO_EXTERNAL'
EXPORTING
date_internal = p_eindt
IMPORTING
date_external = lv_extdate
EXCEPTIONS
OTHERS = 1.
ls_sched-po_item = p_ebelp.
ls_sched-sched_line = p_etenr.
ls_sched-delivery_date = lv_extdate.
APPEND ls_sched TO lt_sched.
ls_schedx-po_item = p_ebelp.
ls_schedx-sched_line = p_etenr.
ls_schedx-po_itemx = 'X'.
ls_schedx-sched_linex = 'X'.
ls_schedx-delivery_date = 'X'.
APPEND ls_schedx TO lt_schedx.
WHEN 'DEL'.
ls_item-delete_ind = 'L'.
ls_itemx-delete_ind = 'X'.
WHEN 'UNDL'.
ls_item-delete_ind = space.
ls_itemx-delete_ind = 'X'.
WHEN 'BLCK'.
ls_item-delete_ind = 'S'.
ls_itemx-delete_ind = 'X'.
WHEN OTHERS.
MESSAGE 'Unknown change type' TYPE 'E'.
ENDCASE.
APPEND ls_item TO lt_item.
APPEND ls_itemx TO lt_itemx.
CALL FUNCTION 'BAPI_PO_CHANGE'
EXPORTING
purchaseorder = lv_ebeln
testrun = p_test
TABLES
return = lt_return
poitem = lt_item
poitemx = lt_itemx
poschedule = lt_sched
poschedulex = lt_schedx.
LOOP AT lt_return INTO ls_return.
WRITE: / ls_return-type, ls_return-id, ls_return-number, ls_return-message.
IF ls_return-type = 'E' OR ls_return-type = 'A'.
lv_error = 'X'.
ENDIF.
ENDLOOP.
IF lv_error = 'X' OR p_test = 'X'.
CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
IF lv_error = 'X'.
WRITE: / 'Errors found, nothing saved'.
ELSE.
WRITE: / 'Test run OK, nothing saved. Untick test run to post.'.
ENDIF.
ELSE.
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
EXPORTING
wait = 'X'
IMPORTING
return = ls_return.
WRITE: / 'Purchase order', lv_ebeln, 'changed'.
ENDIF.Optional: change the price through the condition (PB00) instead of NET_PRICE
* When the price comes from conditions, change the gross price condition: * DATA: lt_cond TYPE STANDARD TABLE OF bapimepocond, * ls_cond TYPE bapimepocond, * lt_condx TYPE STANDARD TABLE OF bapimepocondx, * ls_condx TYPE bapimepocondx. * ls_cond-itm_number = p_ebelp. * ls_cond-cond_type = 'PB00'. * ls_cond-cond_value = p_netpr. * ls_cond-change_id = 'U'. * APPEND ls_cond TO lt_cond. * ls_condx-itm_number = p_ebelp. * ls_condx-itm_numberx = 'X'. * ls_condx-cond_type = 'X'. * ls_condx-cond_value = 'X'. * ls_condx-change_id = 'X'. * APPEND ls_condx TO lt_condx. * Pass pocond = lt_cond and pocondx = lt_condx in the TABLES of BAPI_PO_CHANGE. * Verify BAPIMEPOCOND and BAPIMEPOCONDX field names in SE11 before use.
Verify in SE11 that BAPIMEPOITEM(X) and BAPIMEPOSCHEDULE / BAPIMEPOSCHEDULX carry the fields used here, and in the BAPI documentation (SE37) how your release treats NET_PRICE versus POCOND. DELETE_IND L deletes and S blocks an item in ECC 6.0. The program starts in test run mode on purpose; untick the checkbox to save.
Get a PO mass-change tool reviewed
Send us your scenario and we return a reviewed program that changes PO dates or quantities from a file, with test mode and a log.
Optional. The tool and every export work without this. No spam.
How BAPI_PO_CHANGE expects data
POITEM carries the new values and POITEMX says which fields to change: PO_ITEM is the key, PO_ITEMX = X marks the key as filled, and each changed field gets an X. Delivery dates are not in POITEM but in POSCHEDULE with PO_ITEM and SCHED_LINE, with POSCHEDULEX flags including PO_ITEMX and SCHED_LINEX. DELIVERY_DATE in POSCHEDULE is a 10-character field in the user's external date format, which is why the code converts the internal date first. TESTRUN = X runs all checks without saving.
- Quantity and price: POITEM / POITEMX.
- Delivery date: POSCHEDULE / POSCHEDULEX.
- Deletion and block: DELETE_IND L or S, blank to undo.
How to use it
Enter PO number, item, change type and only the value that type needs. Paste the code into SE38 and run it with test run ticked. Read the messages: warnings about tolerance or release strategy are normal, errors stop the change. Untick test run and run again to save. For mass changes, wrap the CASE block in a loop over a file or table and call BAPI_PO_CHANGE once per PO with all its items.
Worked example
PO 4500012345, item 00010, mode DATE, date 20261130, schedule line 0001. The program converts the date to the user format, for example 30.11.2026, sends POSCHEDULE with DELIVERY_DATE and the X flags, and the test run returns the standard message that the PO would be changed. After the real run, ME23N shows the new date on the delivery schedule tab and EKET-EINDT holds 20261130. If a release strategy applies, the change may reset the release status.
Gotchas
Setting NET_PRICE has no effect when the price is determined from conditions that override it; then change the PB00 condition through POCOND as in the optional block, or check the BAPI documentation for your release. A PO in use by ME22N returns a lock error. Items with goods receipts cannot get a quantity below the received quantity. Do not commit after a test run: the program rolls back on purpose. Read every message in RETURN, not only the first, because the real error is often further down.
Frequently Asked Questions
How do I change the delivery date with BAPI_PO_CHANGE?
Fill POSCHEDULE with PO_ITEM, SCHED_LINE and DELIVERY_DATE in external format, and POSCHEDULEX with the same keys plus PO_ITEMX, SCHED_LINEX and DELIVERY_DATE set to X. Also pass the item in POITEM and POITEMX with PO_ITEMX = X. Commit with BAPI_TRANSACTION_COMMIT.
How do I delete a PO item with BAPI_PO_CHANGE?
Set DELETE_IND = L in POITEM and DELETE_IND = X in POITEMX for that PO_ITEM. To block the item instead, use S. To undo deletion or block, send DELETE_IND blank with the X flag. Items with follow-on documents may only be marked, not physically removed.
Why does BAPI_PO_CHANGE return success but nothing changes?
Usually the X flag for the field is missing, the program ran with TESTRUN = X, or BAPI_TRANSACTION_COMMIT was not called. For prices, a condition may override NET_PRICE. Check that each changed field has its X flag and that the commit runs after a run without E or A messages.
Which BAPIs exist for purchase orders in ECC?
BAPI_PO_CREATE1 creates, BAPI_PO_CHANGE changes, BAPI_PO_GETDETAIL1 reads details, BAPI_PO_RELEASE releases and BAPI_PO_RESET_RELEASE cancels a release. BAPI_PO_GETITEMS lists items across POs. All need BAPI_TRANSACTION_COMMIT after write calls.
If you want buyers to ask about open POs and, with approval, change dates or quantities in plain English on your own servers, we can build that over your ECC system.
Related Tools
SAP BAPI_PO_CREATE1 ABAP Skeleton Generator
Fill in vendor, plant and material to generate an ABAP skeleton for creating a purchase order with BAPI_PO_CREATE1.
Developer ToolsSAP ECC BAPI_SALESORDER_CHANGE ABAP Generator
Generate a working ABAP program that updates an SAP sales order with BAPI_SALESORDER_CHANGE, with the correct X structures, schedule line handling, error check and commit or rollback.
SAPSAP MM and QM BAPI and API List Reference
A searchable list of the common SAP MM and QM BAPIs and S/4HANA OData APIs, what each does, and whether it needs a commit.
SAPSAP BAPI_GOODSMVT_CREATE ABAP Code Generator
Fill in plant, material, quantity and movement type to get a working ABAP skeleton for posting a goods movement through the standard BAPI.
More Developer Tools tools
See all- SAP ECC Enhancement Transactions and Exit Tables Reference (SMOD, CMOD, SE18, MODSAP, SXC_EXIT)
- SAP ECC Data Dictionary and Repository Tables Reference (DD02L, DD03L, T100, E070, TSTC)
- SAP ECC ABAP Runtime Errors (ST22 Dumps) and Error Log Transactions Reference
- SAP ECC Background Job History ABAP Query Generator (TBTCO + TBTCP)
- SAP ECC Background Job Creation ABAP Generator (JOB_OPEN, SUBMIT, JOB_CLOSE)
- SAP ECC IDoc Segment Data Reader ABAP Generator (EDIDC, EDID4, EDIDS)
- SAP ECC Custom Inbound IDoc Function Module Skeleton Generator
- SAP ECC BAPI_MATERIAL_SAVEDATA Material Creation ABAP Generator
- SAP ECC BAPI_ACC_DOCUMENT_POST G/L and Vendor Posting ABAP Generator
Keep exploring
Free tools
- SAP ECC BAPI_SALESORDER_CHANGE ABAP GeneratorGenerate a working ABAP program that updates an SAP sales order with BAPI_SALESORDER_CHANGE, with the correct X structures, schedule line handling, error check and commit or rollback.
- ABAP BAPI Return Handling and Commit GeneratorWrap any BAPI call with BAPIRET2 error checking, message text building and a safe commit or rollback.
- SAP BAPI_PO_CREATE1 ABAP Skeleton GeneratorFill in vendor, plant and material to generate an ABAP skeleton for creating a purchase order with BAPI_PO_CREATE1.
ERP fixes and how-tos
- SAP MM BAPI for PO Create and Change: BAPI_PO_CREATE1 and BAPI_PO_CHANGEHow to use BAPI_PO_CREATE1 and BAPI_PO_CHANGE: header, item and schedule structures, the X-structures, error handling in RETURN and the commit step.
- How to Use BAPI_TRANSACTION_COMMIT CorrectlyBAPIs never commit their own update. Here is when to call BAPI_TRANSACTION_COMMIT with WAIT, and why a BAPI can run fine and still save nothing.
- How to add AI to SAP ECC 6.0 on-prem without moving data to a cloudReference architecture for a private on-prem AI assistant on SAP ECC 6.0: RFC and BAPI reads, SLT replica, retrieval index, local LLM, permission mirroring.
Integrations
- How to automate email into SAP ECC 6.0Turn inbound emails into SAP ECC 6.0 transactions: customer POs into sales orders, supplier confirmations, RFQs and invoices, with review and BAPI posting.
- How to add AI agents to SAP ECC 6.0How to add AI agents to SAP ECC 6.0: a tool layer over BAPIs, RFC and IDocs, human approval before any posting, and an on-prem model that never leaves your network.