# BAPI_PO_CHANGE Example Generator for SAP ABAP

> Source: https://netray.co/tools/sap-ecc-bapi-po-change-abap-generator
> Publisher: Netray (netray.co), AI and integration engineering for ERP and manufacturing systems.
> Section: Free Tools

## Short answer

Generate a working ABAP program that changes an SAP purchase order item with BAPI_PO_CHANGE, with POITEM/POITEMX, schedule line date conversion, test run and commit handling.

## Category

developer

## Erp

SAP ECC 6.0

## Audience

- ABAP developer
- SAP MM consultant

## Tool

**Kind:** template

**Output:** code

**Language:** abap

**Fields:**

#### Report name

**Key:** report

**Type:** text

**Default:** ZMM_PO_CHANGE_BAPI

#### Purchase order

**Key:** po

**Type:** text

**Default:** 4500012345

#### PO item

**Key:** item

**Type:** text

**Default:** 00010

#### Change type

**Key:** mode

**Type:** select

**Options:**

- QTY
- PRIC
- DATE
- DEL
- UNDL
- BLCK

**Default:** DATE

**Help:** QTY quantity, PRIC net price, DATE delivery date, DEL delete, UNDL undelete, BLCK block

#### New quantity

**Key:** qty

**Type:** number

**Default:** 120

#### New net price

**Key:** price

**Type:** number

**Default:** 14.50

#### Price unit

**Key:** price_unit

**Type:** number

**Default:** 1

#### New delivery date (YYYYMMDD)

**Key:** date

**Type:** text

**Default:** 20261130

#### Schedule line

**Key:** sched

**Type:** text

**Default:** 0001

**Blocks:**

#### Program

**Body:** REPORT {{report}}.

PARAMETERS: p_ebeln TYPE ekko-ebeln               DEFAULT '{{po}}',
            p_ebelp TYPE ekpo-ebelp               DEFAULT '{{item}}',
            p_mode  TYPE char4                    DEFAULT '{{mode}}',
            p_menge TYPE bapimepoitem-quantity    DEFAULT '{{qty}}',
            p_netpr TYPE bapimepoitem-net_price   DEFAULT '{{price}}',
            p_peinh TYPE bapimepoitem-price_unit  DEFAULT '{{price_unit}}',
            p_eindt TYPE sy-datum                 DEFAULT '{{date}}',
            p_etenr TYPE eket-etenr               DEFAULT '{{sched}}',
            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

**Body:** * 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.

**Notes:** 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.

## Content

**Intro:** 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.

**Sections:**

#### How BAPI_PO_CHANGE expects data

**Body:** 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.

**Bullets:**

- Quantity and price: POITEM / POITEMX.
- Delivery date: POSCHEDULE / POSCHEDULEX.
- Deletion and block: DELETE_IND L or S, blank to undo.

#### How to use it

**Body:** 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

**Body:** 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

**Body:** 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.

**Cta:** 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.

**Faq:**

#### How do I change the delivery date with BAPI_PO_CHANGE?

**Answer:** 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?

**Answer:** 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?

**Answer:** 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?

**Answer:** 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.

## Search terms

bapi_po_change example in sap abap, sap bapi update purchase order, bapi_po_change delivery date, bapi_po_change delete item, bapi_po_change net price, sap bapi for purchase order, sap bapi error

---
Talk to an engineer: https://netray.co/contact?intent=erp_ai | Machine catalog: https://netray.co/agent/catalog.json
