How do you call an SAP BAPI from Excel?
To call SAP BAPIs from Excel you need four things: an RFC connection to SAP, the BAPI that fits the job, a mapping from your columns to its import and table parameters, and a commit after every call that returns no error. A BAPI is an RFC-enabled function module that SAP publishes for a business object; it reports the outcome in a RETURN table. PostNow.ai handles all four in Excel: it finds the BAPI in your own system, maps the columns, simulates with a rollback, commits clean rows and writes SAP's message back to each row.
- The commit is yours. Most BAPIs post nothing until the caller runs
BAPI_TRANSACTION_COMMITin the same RFC session. A document number with nothing in SAP almost always means a missing or misplaced commit. - Success means no E or A in
RETURN. Read every message, not only the first, and roll back when an error is present.
A BAPI Excel upload is the cleanest way to post spreadsheet data into SAP when a BAPI covers the fields you need: no screens to replay, and a structured answer for every document. If no BAPI covers a field you must fill, record the transaction instead: the trade-off is explained in BAPI vs BDC in SAP. Everything below assumes a BAPI fits, and follows the call in order, from the RFC connection to the message on the row.
What calling a BAPI from Excel involves: an RFC connection and five steps
PostNow.ai calls a BAPI from Excel over RFC, under the SAP login the user stored in PostNow.ai on their own computer, and closes the connection after each call. Any route from Excel to a BAPI goes through the same five steps, starting with the RFC connection; the table shows who does each one in PostNow.ai and in a program you write yourself.
| Step | In PostNow.ai | In your own VBA, .NET or Python code |
|---|---|---|
| 1. Connect over RFC | Uses the user's stored SAP login (application server, system number, client, user) and opens an RFC connection when the user starts the action | An RFC library (SAP GUI's RFC controls, the SAP .NET Connector or the NetWeaver RFC SDK) plus logon parameters in your code or config |
| 2. Read the interface | Reads the BAPI's parameters from your system with RFC_GET_FUNCTION_INTERFACE and expands each structure into fields | The connector reads the metadata for you, but you still need to know which parameters and fields to fill (SE37 or transaction BAPI) |
| 3. Call the BAPI | One call per document: header and item rows of one document go into one call | Fill the import parameters and table rows from the sheet and call the function |
| 4. Commit or roll back | BAPI_TRANSACTION_COMMIT with WAIT = 'X' when RETURN holds no E or A message; BAPI_TRANSACTION_ROLLBACK otherwise | Call the commit yourself, in the same RFC session as the BAPI |
| 5. Report the result | SAP's message in the Run Log column of the row, the document number in a column you choose | Loop over RETURN and write the messages and export values back to the sheet |
Two authorisation layers apply to every call. The RFC call itself needs authorisation object S_RFC (activity 16, execute) for the function group of each module called, which includes the BAPI and the commit and rollback modules (function group BAPT). The BAPI then runs the business checks SAP built into it, such as the purchasing organisation or company code a user may post in. A missing S_RFC authorisation is a typical reason a first BAPI call from Excel fails before it reaches any business logic.
Find the right BAPI: the BAPI Explorer and Find with AI
PostNow.ai searches the function modules of your own SAP system (with SAP's RFC_FUNCTION_SEARCH), so the list matches your release and includes custom RFC modules. Find with AI takes a transaction code or a plain-English request: ME21N leads to BAPI_PO_CREATE1, FB50 to BAPI_ACC_DOCUMENT_POST, VA01 to BAPI_SALESORDER_CREATEFROMDAT2.

In SAP itself, transaction BAPI opens the BAPI Explorer. It lists BAPIs by business object in the component hierarchy, or alphabetically, and shows only released BAPIs unless you change the setting in the Goto menu. Select a method, then use Detail for the function module name and parameters and Documentation for SAP's description. Before you build on a BAPI, check four things in that documentation:
- Does it commit itself? Almost no BAPI does; the few that do say so in their documentation and are listed in SAP Note 131838.
- Does it have a
TESTRUNparameter?BAPI_PO_CREATE1andBAPI_GOODSMVT_CREATEdo. It runs SAP's checks without saving. - Which X structures go with the data structures?
POHEADERpairs withPOHEADERX,POITEMwithPOITEMX. A value whose X field is blank is ignored. - Which table holds the messages? Most BAPIs use
RETURNwith structureBAPIRET2. Older ones return a singleBAPIRETURNorBAPIRETURN1structure, and a few use a table with another name.
If no BAPI covers a field you have to fill, such as a field that exists only on a custom screen, record the transaction instead. The full trade-off, including commit and screen behaviour, is in BAPI vs BDC in SAP; how to record so the replay holds is in the BDC recording guide.
Map Excel columns to BAPI parameters
PostNow.ai shows every parameter and field of the BAPI next to your Excel columns in the BAPI Mapping Designer, and Mapping AI proposes the matches from your column headers; it never receives the row values. The mapping is the real work of a BAPI Excel upload, because a sheet is flat and a BAPI is not.
| Parameter kind | Example in BAPI_PO_CREATE1 | How it maps to Excel |
|---|---|---|
| Import, single field | TESTRUN | Usually a fixed value in the template, not a column |
| Import, structure | POHEADER (vendor, company code, purchasing organisation, document type) | One value per document: columns on the header row |
| Tables | POITEM, POSCHEDULE, POACCOUNT | One line per item: columns on the item rows |
| X structures | POHEADERX, POITEMX, POSCHEDULEX | An X for every field you send; no column needed |
| Extensions | EXTENSIONIN | Customer fields, packed into the extension structure your system defines |
| Export | EXPPURCHASEORDER | Written back to a result column after the call |
| Messages | RETURN (BAPIRET2) | Read after the call; never mapped as input |

Four details decide whether the first call works:
- Header and items. A document with several items needs a rule for which rows belong together. PostNow.ai uses a marker column: an
Hrow starts a document and theDrows below it become its item lines. The item number is copied into the schedule and account lines built from the same row, so they reach the right item. - X flags. PostNow.ai fills the X structures from the shape of each data structure and asks you to review the pairs it cannot decide. In your own code, every field you fill needs its X field set too.
- Internal formats. Over RFC, SAP expects the internal value. Vendor
100045must arrive as0000100045; PostNow.ai switches on leading zeros for every field whose domain uses theALPHAconversion exit. Dates go asYYYYMMDD, and you can set a date format per field. - Codes behind the screen text. Some fields show one value on screen and store another, through a language-dependent conversion: units of measure are the classic case, where an English logon shows
PCfor pieces and SAP storesST. Send the internal value, or prove the screen value on a test call first.

Read RETURN for every row
PostNow.ai reads the BAPI's RETURN messages after each call and writes SAP's message into the Run Log column of the row, with the document number in a column you choose. Whether a row succeeded is decided by the message types: no E or A message means the document can be committed.
| Type | Meaning | What to do with the row |
|---|---|---|
S | Success, often carrying the new document number | Commit, then write the number back |
W | Warning; SAP would still post | Commit, but keep the text where the preparer sees it |
I | Information | Commit |
E | Error; the document is not valid | Roll back and show the message on the row |
A | Abort; processing was cancelled | Roll back and show the message on the row |
An empty RETURN also means no error. Each BAPIRET2 line carries the message class (ID), NUMBER, the text in MESSAGE, the variables MESSAGE_V1 to MESSAGE_V4, and PARAMETER, ROW and FIELD, which point at the input that failed. Read all lines: BAPI_PO_CREATE1, for example, can return a general "Purchase order still contains faulty items" (MEPO 000) above the message that names the field.
The success message usually holds the number: BAPI_PO_CREATE1 returns 06 017, "Standard PO created under the number 4500017532", and the same number in the export parameter EXPPURCHASEORDER. In PostNow.ai the token $DOC_NO picks up the document number, $V1 to $V4 pick up the message variables, and a custom success message can add $USER, $DATE and $TIME.

Commit with BAPI_TRANSACTION_COMMIT
PostNow.ai commits each document with BAPI_TRANSACTION_COMMIT and WAIT = 'X' only when its RETURN holds no E or A message, and calls BAPI_TRANSACTION_ROLLBACK otherwise, so a failed row leaves nothing behind. SAP's BAPI rules leave the commit to the caller, which is why a BAPI call from Excel needs this second call at all.
- Same session, or no commit. The commit only closes the work of the BAPI that ran in the same RFC session. A program that opens a new connection for the commit, or uses a stateless call, gets a success message and a document number from the BAPI, and nothing in SAP.
- Commit per document. A rollback discards everything since the last commit. Call the BAPI and commit (or roll back) for each document, so one bad document cannot take the good ones with it.
WAIT = 'X'when the next step reads the result. It makes the commit wait for the update task. Without it, a follow-up call that reads the new document can run before the document exists.- Self-committing BAPIs. The few BAPIs that commit internally are listed in SAP Note 131838. Calling the commit after them does no harm, but a rollback cannot undo them.
RETURN line.Test before you post: Validate, Simulate and TESTRUN
PostNow.ai tests in two stages. Validate checks the sheet offline, without calling SAP: required fields, type, length, characters, dates, decimals and allowed values. Simulate then sends each document to SAP as a real BAPI call and always follows it with BAPI_TRANSACTION_ROLLBACK, never a commit, so you read SAP's own messages for every row before the real run. The exception is the small group of BAPIs that commit internally (SAP Note 131838): a rollback cannot undo them, so test those in a quality client and use their TESTRUN parameter where they have one.

Inside SAP you have two ways to test a BAPI by hand:
TESTRUNwhere the BAPI has it. SetTESTRUN = 'X'and the BAPI runs its checks and returns messages without saving. Check the parameter's documentation: what is checked in a test run differs by BAPI.- SE37 test sequence. In SE37, Function Module, Test, Test Sequences lets you run the BAPI and then
BAPI_TRANSACTION_COMMITin one session. A single SE37 test of the BAPI alone shows the messages but leaves nothing posted, which is a quick way to see what SAP returns for one record.
Test on a few documents per template, then again after any configuration change, a support pack or a new field in the sheet.
How PostNow.ai calls a BAPI from Excel
PostNow.ai runs the whole call from the Excel ribbon, on the user's own computer and under the user's own SAP login. A designer builds the template once; operators fill the sheet and run it.
- Find the BAPI. Search by name in your system, or type a transaction code or a sentence into Find with AI. PostNow.ai reads the BAPI's interface from your system, including the extension structures you declare for customer fields.
- Map the columns. Drag fields onto columns, or let Mapping AI match your file's headers (or screenshots of the SAP screen) to the BAPI's fields. Set fixed values, date formats, leading zeros and allowed values per field.
- Group header and items. Choose single record or header/detail; with header/detail, the H/D marker column turns one header row and its item rows into one call.
- Validate. The offline check marks failing cells on the sheet before anything reaches SAP.
- Simulate. Each document is sent to the BAPI and rolled back; SAP's messages land on the rows.
- Run. Clean documents are committed with
BAPI_TRANSACTION_COMMIT; documents with an E or A message are rolled back. The Run Log shows SAP's message, the user, the time and the SAP system on each row. - Re-run safely. Before a real Run, PostNow.ai reads the Run Log and lists the documents that already posted, with Skip posted rows, Post again or Cancel. Retry Failed re-posts only the rows marked ERROR. A row marked UNKNOWN lost SAP's answer after the call was sent, so look the document up in SAP before you post it again.

BAPI calls need no PostNow.ai objects in SAP: standard RFC and the user's RFC authorisation are enough. A template published to the team library becomes run-only for operators; that side is covered in Excel to SAP automation. PostNow.ai's free SAP upload templates come with their columns already mapped to the BAPI.
Worked example: a BAPI Excel upload with BAPI_PO_CREATE1
A buyer at company code 1010 posts 40 purchase orders with 112 items from one Excel sheet through PostNow.ai. The designer built the template on BAPI_PO_CREATE1, starting from the free ME21N purchase order template.
| Excel column | BAPI field | Row | Note |
|---|---|---|---|
| Marker | (grouping) | H and D | H starts a purchase order |
| Vendor | POHEADER-VENDOR | H | 100045, sent as 0000100045 |
| Purch. org / group | POHEADER-PURCH_ORG, PUR_GROUP | H | 1010 / 001 |
| Doc. type | POHEADER-DOC_TYPE | H | Fixed value NB |
| Material, plant, quantity | POITEM-MATERIAL, PLANT, QUANTITY | D | TG-1001, 1010, 24 |
| Delivery date | POSCHEDULE-DELIVERY_DATE | D | Item number copied from the item line |
| PO number | $DOC_NO | H | Result column |
Validate stops two item rows whose quantity reads "12 pcs" instead of a number; the buyer fixes the cells. Simulate sends all 40 orders and rolls each one back. Two orders come back with an E message on their header rows: one item in each uses a material that is not extended to plant 1010. The buyer replaces the material, simulates those two orders again, and runs the sheet. Each of the 40 orders is committed separately, and each H row shows "Standard PO created under the number ..." with the number in the result column.
Next morning a colleague opens the workbook and clicks Run by mistake. PostNow.ai lists the 40 orders that already posted and offers Skip posted rows; nothing is sent twice. In a home-made macro, that protection is code someone has to write.
Do-it-yourself routes: VBA, SAP .NET Connector and Python
PostNow.ai is the no-code route: the RFC connection, mapping, commit and per-row results come with the add-in. If you write the call yourself, you need an RFC library, and three are in common use. Whichever you pick, the code still has to handle the commit in the same session, the X flags, the internal formats and the Run Log, which are the parts that take the time.
| Route | What you need | What to know |
|---|---|---|
| PostNow.ai (Excel add-in) | The add-in, the user's SAP login and RFC authorisation | No code; BAPI search, mapping, Simulate with rollback, commit per document and SAP's message on every row |
| Excel VBA | The RFC ActiveX controls installed with SAP GUI for Windows (SAP.Functions) | The controls once depended on the classic RFC library, which SAP no longer supports; SAP GUI 7.50 delivers them on the NetWeaver RFC library, so re-test old macros after a GUI upgrade |
| SAP .NET Connector (NCo) 3.1 | The connector from the SAP Support Portal, plus a .NET program or Excel add-in that uses it | Supported on .NET Framework 4.6.2 to 4.8.1 and, from patch level 3.1.5, on .NET 8; NCo 3.0 is out of support |
| Python with PyRFC | PyRFC and the SAP NetWeaver RFC SDK, plus a script that reads the workbook | SAP stopped maintaining PyRFC and archived its public repository, and recommends a fork or a new project for future work |
A VBA macro that calls a BAPI is a different thing from a macro that drives SAP GUI screens. Screen scripting replays clicks, not an interface, and is covered in SAP GUI scripting alternative.
Calling BAPIs from Excel on S/4HANA
PostNow.ai calls BAPIs on SAP ECC and S/4HANA on-premise the same way, and adds API mode, which posts Excel rows through SAP's published OData V2, OData V4 and SOAP APIs. Most BAPIs carry over, with these points to check:
- Longer material numbers. The material number can be 40 characters in S/4HANA, and many BAPIs keep the 18-character
MATERIALfield next to a newMATERIAL_LONG. Map the long field and its X flag. - Business Partner for customers and suppliers. Customer and supplier master data is maintained in transaction
BP; load it through the Business Partner interfaces rather than the old customer and vendor BAPIs. - Cloud, public edition. SAP S/4HANA Cloud, public edition, integrates through the APIs SAP has released for it, listed on the SAP Business Accelerator Hub.
What to plan for before the first real run
PostNow.ai posts through the BAPI's own logic, so SAP's rules decide every result. Settle these points before volume:
- RFC authorisation. Ask security for
S_RFCon the function groups of the BAPI and the commit, for every user who will run the template. - Simulate on a few documents. Validate checks the file offline; SAP's own checks start with Simulate.
- Self-committing BAPIs. If the BAPI appears in SAP Note 131838, a rollback cannot undo it: test it in a quality client, with its
TESTRUNparameter where it has one. - Fixed values. Put document type, purchasing group or company code in the template as fixed values when they never change, so operators cannot mistype them.
- One workbook per run. The re-post check reads this sheet's Run Log; a new file with the same rows meets only SAP's own duplicate checks.
- Re-test after upgrades. A support pack or a configuration change can change what the BAPI checks. Simulate the template again before the next run.
BAPI call errors from Excel and the fix
PostNow.ai writes SAP's message for each failed document into its row, so these are the messages you will read in the Run Log, or in your own code's output.
| Symptom or message | What it means | Fix |
|---|---|---|
| Document number returned, nothing in SAP | No commit, or the commit ran in another RFC session | Call BAPI_TRANSACTION_COMMIT on the same connection after a clean RETURN; PostNow.ai does this on every clean document |
| Value sent but not posted | The field's X flag was blank | Set the matching field in the X structure |
| Master record "does not exist" although it does | The number was sent without leading zeros | Send the internal format (ALPHA), for example 0000100045 |
| RFC authorisation error before any business message | The user lacks S_RFC for the function group | Ask security to add the function group; an authorisation trace (STAUTHTRACE) shows which check failed |
| MEPO 085 Check item number in table | A schedule or account line has no item number, or the wrong one | Fill PO_ITEM in each child table; PostNow.ai copies it from the item line |
| Row marked UNKNOWN | The connection dropped after the call was sent | Look the document up in SAP before you post the row again |
Choosing a method for other SAP objects is covered in SAP mass upload from Excel.
