How to do an SAP MM mass upload from Excel
PostNow.ai does an SAP MM mass upload from Excel one object per template, in load order: materials, vendors, info records, requisitions, purchase orders, goods receipts, invoices. Each template posts through a BAPI, such as BAPI_PO_CREATE1 for ME21N, or a recording. Validate checks the file offline, Simulate shows SAP's messages first, and Run writes each document number back.
- Receipts before invoices. A goods receipt against a purchase order credits GR/IR and the invoice clears it, so post them in that order and reconcile GR/IR after each run.
- A blocked invoice has posted. Release it in MRBR; never run that row again.
Use this page to plan a materials management load from start to finish: which MM object comes first, which route PostNow.ai uses for each, and what to check once the run is over. Each object has its own how-to page, linked from the tables below. For choosing a method across all SAP modules, see SAP mass upload from Excel; the sales side is on SAP SD mass upload.
What an SAP MM mass upload covers
PostNow.ai handles a mass upload in SAP MM for the master data and purchasing documents a procurement team keeps in spreadsheets. Master data comes first, because every document reads it. The documents then form one chain, each created with reference to the one before it: requisition, purchase order, goods receipt, supplier invoice.
| MM object | Transaction | What one Excel row usually is | How-to page |
|---|---|---|---|
| Material master (create) | MM01 | One material for one plant, storage location or sales area | MM01 mass create materials |
| Material master (change) | MM02 | One material with the fields to change | MM02 mass update |
| Vendor master | XK01 (ECC), BP (S/4HANA) | One vendor with company code and purchasing organization data | XK01 vendor master upload |
| Bill of material | CS01 | A header row per BOM, then one row per component | CS01 BOM upload |
| Purchase requisition | ME51N | A header row, then one row per item | ME51N mass upload |
| Purchase order | ME21N | A header row, then one row per item | ME21N mass upload |
| Goods movement | MIGO | One line of a material document, such as one PO item received | MIGO goods movement upload |
| Supplier invoice | MIRO | A header row per invoice, then one row per PO item | MIRO mass invoice posting |
Purchasing info records (ME11) sit between the vendor and the purchase order: they hold the price and planned delivery time that a PO item proposes for that vendor and material. A data migration in SAP MM at go-live loads the same objects, with open quantities and original dates; the cutover order across all master data is on SAP master data migration.
How PostNow.ai uploads MM data from Excel
PostNow.ai runs every MM object through the same six steps; only the template underneath changes.
1. Pick the BAPI or record the transaction
In the BAPI Explorer, search your system or ask Find with AI: its transaction list maps MM01 to BAPI_MATERIAL_SAVEDATA, ME21N to BAPI_PO_CREATE1, MIGO to BAPI_GOODSMVT_CREATE and MIRO to BAPI_INCOMINGINVOICE_CREATE. PostNow.ai reads the interface from your system, so the mapper shows the parameters of your release. For XK01 and ME11, record the transaction once instead.
2. Map the columns
Requisitions, purchase orders and invoices use header and item rows: the H row carries document type, vendor and purchasing organization (or the invoice reference and amount), and the D rows under it carry material, quantity, plant and price. Where a BAPI pairs a structure with an X twin, such as POITEM and POITEMX, the template sets the change flags, so the file holds values only.
3. Fix what should not vary
Give plant, purchasing organization and company code fixed values or an allow-list with Restrict on, so Validate refuses a plant the template was not built for. Switch on Leading Zeros for vendor and document numbers, so 4711 reaches SAP as 0000004711.
4. Validate, then Simulate
Validate checks the file offline: required fields, lengths, formats, dates and allowed values. Simulate then asks SAP: a BAPI template calls the BAPI and rolls back instead of committing; a recording replays the screens without the final save. Either way you read SAP's messages per row, so a closed posting period or a missing price shows on the first document, before anything is saved.
5. Run, and write the document number back
Run commits a BAPI call only when SAP returns no E or A message and rolls it back otherwise. Recordings replay through SAP GUI with synchronous update, so each row's messages and number return at once in the Run Log; PostNow.ai logs in to SAP GUI only on your own computer, with your own stored login, when you start the action. The PO, material document or invoice number lands in its own column, and with ME23N as the Call Transaction a PO number opens the order in one click.
6. Re-run only what failed
Retry Failed re-posts only rows whose Run Log starts with ERROR, scanning from the current Start Row down. A normal Run first reads the Run Log and, if rows in scope already hold a document number, offers Skip posted rows, Post again or Cancel. A row marked UNKNOWN lost SAP's answer after it may have posted: look it up in SAP before you post it again.
Every run is also written to PostNow.ai's central audit with template, SAP system, client, user, result and document number. When a row fails, AI Review in the run diagnostics explains SAP's messages; by default it receives the messages, the BAPI name and the field structure, never the cell values.
SAP MM objects, T-codes and BAPIs
PostNow.ai posts through a BAPI where SAP offers one that fits, and through a recording of the transaction where it does not. This is the route we build each MM template on, and why.
| Object (T-code) | PostNow.ai route | Why this route | Written back |
|---|---|---|---|
| Material (MM01, MM02) | BAPI_MATERIAL_SAVEDATA, one material per call | One BAPI creates, extends to new plants and changes, with the same structures and X twins | SAP's message per row |
| Vendor (XK01, ECC) | XK01 recording, one vendor per row | BAPI_VENDOR_CREATE takes no vendor data, so the recording carries general, company code and purchasing data in one save | Vendor number from SAP's save message |
| Supplier (BP, S/4HANA) | API mode with API_BUSINESS_PARTNER, or BAPI_BUPA_CREATE_FROM_DATA | XK01 redirects to BP on S/4HANA, and SAP KBA 1951318 says BP is not supported for batch input | Business partner number |
| Info record (ME11) | ME11 recording, one record per row | SAP's own batch input for info records (program RM06IBI0, LSMW object 0060) runs on the same screens | SAP's message per row |
| Bill of material (CS01) | BAPI_MATERIAL_BOM_GROUP_CREATE or a CS01 recording | Header and components in one call, or the screens your engineers use | SAP's message on the header row |
| Purchase requisition (ME51N) | BAPI_PR_CREATE, one call per requisition | SAP Note 1803189 names it the successor of BAPI_REQUISITION_CREATE; Note 217437 rules out batch input for ME51N | Requisition number from NUMBER |
| Purchase order (ME21N) | BAPI_PO_CREATE1, one call per order | SAP Note 217437: batch input is not possible for ME21N; the BAPI takes any number of items | PO number from EXPPURCHASEORDER |
| Goods movement (MIGO) | BAPI_GOODSMVT_CREATE, GM code 01 for a PO receipt | MIGO's controls do not replay through batch input; the BAPI covers receipts, issues and transfers | MATERIALDOCUMENT and MATDOCUMENTYEAR |
| Supplier invoice (MIRO) | BAPI_INCOMINGINVOICE_CREATE, one call per invoice | SAP Note 381593: batch input is not possible for MIRO | INVOICEDOCNUMBER and FISCALYEAR |
Which method suits which kind of object in general is on BAPI vs BDC in SAP, and how to record a transaction so it replays reliably is in the BDC recording guide. Free Excel templates for ME51N, ME21N, MIGO and MIRO are on the materials management templates page, and those for MM01, MM02 and CS01 on the master data templates page.
The load order for MM data
PostNow.ai runs one template per object, so you set the load order, and SAP's dependencies decide it: the procure-to-pay chain reads top to bottom, and each object reads the ones above it when it is created.
| Order | Object | Must already exist | What happens if it does not |
|---|---|---|---|
| 1 | Material with purchasing, MRP and accounting views | Material type, plant and valuation area in Customizing | The PO item is rejected for that material and plant (ME 046 or ME 034) |
| 2 | Vendor with company code and purchasing organization data | Account group or BP grouping, number range | The order is rejected with 06 027: vendor not created for that purchasing organization |
| 3 | Info records | Material, vendor and purchasing organization | No error at load time; a PO item with no price source fails with 06 218 "Net price must be greater than 0" |
| 4 | Purchase requisitions | Material and plant, plus the cost center or order for account-assigned items | The requisition item is rejected |
| 5 | Purchase orders | Vendor, material, prices, and the requisition if the order references one | The order is rejected for the missing vendor, material, price or requisition item |
| 6 | Goods receipts | A released PO item with open quantity; MM and FI periods open for the posting date | ME 390 (purchasing document not yet released), or M7 053 for a closed MM period |
| 7 | Supplier invoices | The PO item, and its goods receipt where the item uses GR-based invoice verification | The invoice cannot name a receipt, or posts blocked for a quantity variance |
The step to watch is the gap between receipt and invoice. A goods receipt against a purchase order credits the GR/IR clearing account and the invoice for the same item debits it, so the line clears only when both exist and agree. Load the receipts first, reconcile GR/IR the same day, then post the invoices. Inverted, an invoice for an item with nothing received either cannot reference a receipt (GR-based invoice verification) or posts blocked for quantity.
Master data: materials and vendors
PostNow.ai loads SAP MM master data with the same template pattern as documents, and the master data upload is where most later failures are decided. A purchase order run that stops on a whole block of rows nearly always points back to a material or vendor that was not ready for that plant or purchasing organization.
- Materials. Basic data exists once per material, while each plant, storage location and valuation area is its own segment, so a material for three plants is three rows. Extending an existing material to a new plant is a create on the same BAPI. The MM01 upload covers views, number assignment and the 40-character material number of S/4HANA; changes such as a new MRP controller or purchasing group across thousands of materials go through the MM02 mass update, where Mass Change downloads today's values into the sheet and posts the rows you changed with
BAPI_MATERIAL_SAVEDATA. - Vendors. On ECC, the vendor is created in XK01 with its account group, which sets the number range and the fields the recording sees. On S/4HANA the supplier is a Business Partner with roles FLVN00 (company code) and FLVN01 (purchasing). Screen the file for duplicates on tax number and bank details first: the Duplicate Master Data (Vendors) report in PostNow.ai's Report Library groups the vendors already in SAP by name, country and VAT number and counts the matches. The XK01 vendor master upload has both routes.
- Info records. Load them when purchase orders should take their price from SAP rather than from the file. An ME11 recording creates one record per row; a price per quantity scale or several conditions per record need their own recording, proved in Debug first.
- Bills of material. Subcontracting orders take their components from the BOM of the finished material, so load BOMs before subcontracting purchase orders, lowest level first. The CS01 BOM upload covers multi-level loads.
Check the result before any document runs: Material Master 360 shows each material's plant and valuation data in one sheet (SAP material master report), and the vendor master purchasing report (Vendor Master Purchasing 360) shows the purchasing organization data the orders will read.
Purchasing documents: requisitions and purchase orders
PostNow.ai uploads purchase orders from Excel through BAPI_PO_CREATE1 and requisitions through BAPI_PR_CREATE, one H row per document with D rows for its items, so an order with 40 lines is one call. Both run under the user's own SAP login, so SAP applies purchasing authorisations and determines the release strategy as it does in ME51N and ME21N (SAP KBA 1497235, on release strategies that are not determined, lists the BAPIs next to the transactions).
- Release fires per document. A run of 300 orders can put 300 documents in an approver's inbox that normally sees a few a day. Tell them before the run.
- Grouping sets the approval level. With a value-based strategy, how items are grouped into documents decides each document's value. Group by vendor, requester or project as purchasing agrees, never to stay under a limit.
- Unreleased orders wait. A goods receipt against an order still in release fails with ME 390, so the order run is finished only when the release queue in ME29N or ME28 has been worked.
- Your price or SAP's. With an info record or contract in place, SAP's pricing can replace the net price from the file (SAP KBA 2577898). Leave the price column empty to take SAP's price, or map
NET_PRICEwithPO_PRICEand Simulate one item with an info record before the volume.
Requisition grouping, account assignment and the conversion to orders are on the ME51N page; the PO structures, conditions and errors are on the ME21N page. Changes to open orders, such as new delivery dates from a supplier's confirmation file, go through Mass Change with BAPI_PO_CHANGE, covered on SAP mass change from Excel.
Goods movements and invoices
PostNow.ai uploads goods receipts through BAPI_GOODSMVT_CREATE and posts supplier invoices through BAPI_INCOMINGINVOICE_CREATE, and these two runs decide whether procurement reconciles. A receipt against a PO item posts the stock and credits GR/IR; the invoice for that item debits GR/IR and creates the payable.
- Receive against the order. A receipt that fails against its PO item gets fixed, not re-posted as a receipt without a PO: that leaves the order open, posts nothing to GR/IR and gives the invoice nothing to match. Movement types, GM codes and reversals for every goods movement are on the MIGO goods movement upload page.
- Two periods, both open. MM allows postings in the current and the previous period, and finance closes its own periods separately in OB52. A backdated receipt file fails with M7 053 when the MM period has moved on; MMRV shows where it stands.
- Tolerances are the control. A supplier who over-delivers is stopped by the over-delivery tolerance on the PO item (M7 022). Receive the ordered quantity and let the buyer decide the rest; raising the tolerance to clear the run removes the check.
- Blocked invoices have posted. An invoice above tolerance posts and is blocked for payment, with a document number like any other row. Release it in MRBR; a second Run creates a second liability for the same supplier invoice.
- Check duplicates in the file. SAP KBA 1859210 states that logistics invoice verification does not check for duplicates among invoices created through BAPI, EDI or API, and KBA 2036775 describes how to enable that check. Until it is on, compare the file with the supplier references already in SAP before the run.
Tolerance keys, GR-based invoice verification and MRBR are on the MIRO mass invoice posting page, and 2-way versus 3-way matching is on SAP invoice matching. For the reconciliation, PostNow.ai's Report Library has the goods movements report in Excel (Goods Movements 360) for the material documents of a run, GR/IR Reconciliation for the GR and IR totals per PO item, and Blocked Invoices for posted invoices waiting for release.
Worked example: 12 purchase orders, their receipts and invoices
PostNow.ai runs this as three templates in load order. Purchasing organization 1010 buys spare parts for plant 1010 from vendor 100045 and two others, after a sourcing round agreed the prices in a spreadsheet. Materials and vendors already exist, which Material Master 360 and Vendor Master Purchasing 360 confirm for plant 1010 and purchasing organization 1010.
- Purchase orders. The ME21N template holds 12 orders with 31 items. Validate stops two rows with plant
1100, which the allow-list refuses. Simulate returns 06 218 "Net price must be greater than 0" for one item with no price in the file and no info record; the buyer adds the agreed price. Run creates 12 orders, each number written back as a link to ME23N. Four orders above the release limit wait in ME29N; the approver releases them before the warehouse posts any receipt. - Goods receipts. The warehouse file has 27 lines against those orders. The MIGO template posts them with GM code 01 and movement type 101. One line for 120 pieces on an item ordered as 100 fails with M7 022; receiving posts 100 and the buyer takes up the extra 20 with the vendor. The purchase order report in Excel (Purchase Order 360) shows each item's GR history.
- Supplier invoices. At month-end, 12 invoices arrive. The MIRO template posts them with the PO item on each D row. One invoice billed a higher unit price and posts blocked for price; the buyer accepts the new price, and AP releases it in MRBR. GR/IR Reconciliation then shows received and invoiced values equal for every item that was both received and invoiced; the four items not yet delivered stay open on their orders.
MM upload errors and the fix
PostNow.ai writes SAP's message to the row, so the message number below is what you see in the Run Log or in Simulate.
| Message | Object | What it means | Fix |
|---|---|---|---|
| 06 218 Net price must be greater than 0 | Purchase order | No price in the file and none found by pricing for that vendor, material and plant | Map the agreed price, or load the info record first; never post 0.01 |
| ME 390 Purchasing document … not yet released | Goods receipt | The order is still waiting in its release strategy | Release it in ME29N or ME28, then post the receipt |
| M7 053 Posting only possible in periods … | Goods receipt | The posting date falls outside the open MM periods | Fix a misread date with the field's date format; if the period itself is behind, whoever owns period-end moves it with MMPV |
| M7 022 … exceeded by … | Goods receipt | The quantity is above the PO item's over-delivery tolerance | Receive the ordered quantity; the buyer decides the excess |
| M8 462 / M8 108 Check if invoice already entered | Supplier invoice | A possible duplicate, where SAP's check is active for the supplier | Look up the earlier document before you post this row |
| MD_BP028 | Vendor on S/4HANA | XK01 redirects to transaction BP | Load suppliers as Business Partners, as in the methods table |
Each object page lists the full error set for its BAPI. When a whole block fails with the same message, fix the master data or Customizing it points to and use Retry Failed, rather than editing rows one by one.
