Jul 3, 2026

A Aample Program Using BAPI_RESERVATION_CHANGE to Change Quantity and Storage Location

Storage location changes via this BAPI aren't as clean as quantity changes — SAP requires you to also populate MOVE_ITEM correctly or the storage location update silently gets ignored while quantity still updates fine. That's the part people usually miss and then spend an hour debugging why the reservation shows on the wrong bin/plant.

BAPI_RESERVATION_CHANGE requires you to explicitly flag every field you're changing in ITEMCONTROL — omitting the flag means the value in ITEMDATA is ignored even if populated.

For storage location changes specifically, you need MOVEMENT_ALLOWED context (goods movement not yet posted against that item) — if GI already happened against the reservation item, the BAPI will reject the storage location change via RETURN.

abap
REPORT zbapi_reservation_change.

DATA: lv_rsnum   TYPE rsnum VALUE '0000001234',  " your reservation number
      lv_rspos   TYPE rspos VALUE '0001'.        " reservation item number

DATA: lt_itemdata    TYPE STANDARD TABLE OF bapi2093_res_item,
      lt_itemcontrol TYPE STANDARD TABLE OF bapi2093_res_item_ctrl,
      lt_return      TYPE STANDARD TABLE OF bapiret2.

DATA: ls_itemdata    TYPE bapi2093_res_item,
      ls_itemcontrol TYPE bapi2093_res_item_ctrl.

* --- Optional but recommended: read current item first ---
DATA ls_resb TYPE resb.
SELECT SINGLE * FROM resb
  INTO ls_resb
  WHERE rsnum = lv_rsnum
    AND rspos = lv_rspos.

IF sy-subrc <> 0.
  WRITE: / 'Reservation item not found'.
  RETURN.
ENDIF.

* --- Fill ITEMDATA: the new values ---
ls_itemdata-res_item  = lv_rspos.
ls_itemdata-material   = ls_resb-matnr.
ls_itemdata-plant      = ls_resb-werks.
ls_itemdata-stge_loc   = 'STG2'.        " new storage location
ls_itemdata-entry_qnt  = '50'.          " new quantity
ls_itemdata-entry_uom  = ls_resb-meins.
APPEND ls_itemdata TO lt_itemdata.

* --- Fill ITEMCONTROL: flags telling SAP which fields to actually apply ---
ls_itemcontrol-res_item = lv_rspos.
ls_itemcontrol-stge_loc = abap_true.    " flag: storage location changed
ls_itemcontrol-entry_qnt = abap_true.   " flag: quantity changed
APPEND ls_itemcontrol TO lt_itemcontrol.

* --- Call the BAPI ---
CALL FUNCTION 'BAPI_RESERVATION_CHANGE'
  EXPORTING
    reservation = lv_rsnum
  TABLES
    itemdata    = lt_itemdata
    itemcontrol = lt_itemcontrol
    return      = lt_return.

* --- Check for errors before committing ---
READ TABLE lt_return TRANSPORTING NO FIELDS
  WITH KEY type = 'E'.
IF sy-subrc = 0.
  LOOP AT lt_return INTO DATA(ls_return) WHERE type CA 'EA'.
    WRITE: / ls_return-message.
  ENDLOOP.
ELSE.
  CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
    EXPORTING
      wait = abap_true.
  WRITE: / 'Reservation updated successfully'.
ENDIF.

 


Jul 2, 2026

IDOC Extension Step by Step in SAP




Ref: https://www.youtube.com/watch?v=aLv6uF2JM1M&t

Jun 30, 2026

How to Move Files between Directories on the Application Server?

SAP developers natively accomplish this using one of three standard methods: standard ABAP dataset commands, OS-level commands via SXPG_COMMAND_EXECUTE, or specialized functions like ARCHIVFILE_SERVER_TO_SERVER. 

Option 1: Native ABAP Statements (Recommended & Safest)
The cleanest, platform-independent approach is to copy the file content data line-by-line using datasets and then delete the original file. This completely eliminates operating system dependencies. 
abap
DATA: lv_line TYPE string.

" 1. Open the original source file
OPEN DATASET p_src_file FOR INPUT IN BINARY MODE.
IF sy-subrc = 0.
  
  " 2. Open the destination target file
  OPEN DATASET p_tgt_file FOR OUTPUT IN BINARY MODE.
  IF sy-subrc = 0.
    
    " 3. Read line by line and transfer data
    DO.
      READ DATASET p_src_file INTO lv_line.
      IF sy-subrc <> 0.
        EXIT.
      ENDIF.
      TRANSFER lv_line TO p_tgt_file.
    ENDDO.
    
    CLOSE DATASET p_tgt_file.
  ENDIF.
  
  CLOSE DATASET p_src_file.
  
  " 4. Delete the source file once successfully transferred
  IF sy-subrc = 0.
    DELETE DATASET p_src_file.
  ENDIF.
ENDIF.

Option 2: Function Module ARCHIVFILE_SERVER_TO_SERVER
You can utilize the standard function module ARCHIVFILE_SERVER_TO_SERVER to replicate a copy of the file on the server and then pair it with a DELETE DATASET statement. [1, 2]
  • Limitation: The source and target parameter variables have a maximum length of 70 characters. If your filepath or filename structure exceeds this limitation, you must utilize Option 1 instead. [1]
abap
CALL FUNCTION 'ARCHIVFILE_SERVER_TO_SERVER'
  EXPORTING
    sourcepath       = p_src_file
    targetpath       = p_tgt_file
  EXCEPTIONS
    error_file       = 1
    OTHERS           = 2.

IF sy-subrc = 0.
  DELETE DATASET p_src_file. " Removes original file to complete the move action
ENDIF.

Option 3: Function Module SXPG_COMMAND_EXECUTE
If you are moving exceptionally large files, executing an operating system level command (mv for Unix/Linux or move for Windows) is the fastest option since it changes file pointers rather than rewriting raw blocks. 
  1. Create a custom OS command (e.g., ZMV) mapped to your OS type in transaction SM69.
  2. Call the function module programmatically: 
abap
DATA: lv_parameters TYPE btcxpgpar,
      lv_status     TYPE btcxpgstat.

" Concatenate source and target paths as arguments for the terminal command
CONCATENATE p_src_file p_tgt_file INTO lv_parameters SEPARATED BY space.

CALL FUNCTION 'SXPG_COMMAND_EXECUTE'
  EXPORTING
    commandname         = 'ZMV'
    additional_parameters = lv_parameters
  IMPORTING
    status              = lv_status
  EXCEPTIONS
    no_permission       = 1
    command_not_found   = 2
    security_risk       = 3
    OTHERS              = 4.

If you would like to proceed with setting up one of these options, let me know:
  • What is the average size of the files you are moving?
  • Will your typical filepaths exceed 70 characters?
  • Which Operating System (Unix, Linux, Windows) is your SAP application server running on?