如何通过SAP NCo3调用BAPI_MATERIAL_SAVEDATA并传递自定义字段
Hey there, let's work through getting your custom field passed via BAPI_MATERIAL_SAVEDATA using SAP NCO3. The critical piece you're missing is that this requires both SAP system-side configuration to extend the BAPI structures and map the field, plus adjustments to your C# code. Here's a step-by-step breakdown:
SAP System-Side Setup (Mandatory First Step)
You can't access the custom field in your NCO3 code until you've extended the relevant BAPI structures and added an enhancement to persist the value to your MARA table:
1. Enhance the
BAPI_TE_MARAstructure
Head to transactionSE11, enterBAPI_TE_MARA, and click "Change". Add your custom fieldZMM_JOB_REFERENCE, making sure its data type and length exactly match the corresponding field in yourMARAtable (e.g., ifMARA-ZMM_JOB_REFERENCEis a CHAR 20 field, set the same properties here). Activate the structure once done.2. Implement the user exit to map the field
Use transactionCMODto create an enhancement project (or use an existing one). Add the enhancement spotEXIT_SAPLMGMU_001—this is the exit triggered when saving material master data via the BAPI. In the exit function module, add code to extract the custom field value from theEXTENSIONINparameter and update theMARAtable. Example ABAP code:DATA: ls_extension TYPE bapiparex, ls_te_mara TYPE bapi_te_mara. LOOP AT extensionin INTO ls_extension. IF ls_extension-structure = 'BAPI_TE_MARA'. MOVE ls_extension-valuepart1 TO ls_te_mara. IF ls_te_mara-material IS NOT INITIAL. UPDATE mara SET zmm_job_reference = ls_te_mara-zmm_job_reference WHERE matnr = ls_te_mara-material. ENDIF. ENDIF. ENDLOOP.Activate the function module and your enhancement project.
3. Test the BAPI directly in SAP
Use transactionSE37to testBAPI_MATERIAL_SAVEDATAinternally. Populate theEXTENSIONINtable with your enhancedBAPI_TE_MARAstructure and custom field value, then verify the material is updated correctly. This confirms your SAP setup works before moving to C# code.
C# Code Adjustments with SAP NCO3
Once your SAP system is configured, here's how to update your code to pass the custom field:
// Get metadata for the enhanced BAPI_TE_MARA structure and create an instance var bapiTeMaraMeta = repo.GetStructureMetadata("BAPI_TE_MARA"); IRfcStructure bapiTeMara = bapiTeMaraMeta.CreateStructure(); // Populate required fields (now your custom field exists in the structure) bapiTeMara.SetValue("MATERIAL", material.Number); bapiTeMara.SetValue("ZMM_JOB_REFERENCE", "f"); // Create the EXTENSIONIN structure (BAPIPAREX) to wrap our BAPI_TE_MARA data var bapiParExMeta = repo.GetStructureMetadata("BAPIPAREX"); IRfcStructure extensionIn = bapiParExMeta.CreateStructure(); // Set the structure name and pack the BAPI_TE_MARA data into VALUEPART1 extensionIn.SetValue("STRUCTURE", "BAPI_TE_MARA"); // Convert the structure to a byte array and encode to match SAP's code page (iso-8859-1 is standard) byte[] teMaraBytes = bapiTeMara.ToByteArray(); extensionIn.SetValue("VALUEPART1", Encoding.GetEncoding("iso-8859-1").GetString(teMaraBytes)); // Get the EXTENSIONIN table from the BAPI function and add our structure IRfcFunction bapiMaterialSave = repo.CreateFunction("BAPI_MATERIAL_SAVEDATA"); IRfcTable extensionTable = bapiMaterialSave.GetTable("EXTENSIONIN"); extensionTable.Append(extensionIn); // --- Don't forget to populate other required BAPI parameters (HEADDATA, CLIENTDATA, etc.) --- // Execute the BAPI bapiMaterialSave.Invoke(destination); // Check for errors in the RETURN table IRfcTable returnTable = bapiMaterialSave.GetTable("RETURN"); foreach (IRfcStructure returnRow in returnTable) { string messageType = returnRow.GetString("TYPE"); string messageText = returnRow.GetString("MESSAGE"); // Handle errors/warnings as needed (e.g., log, throw exception) } // Commit the transaction if no critical errors IRfcFunction commitBapi = repo.CreateFunction("BAPI_TRANSACTION_COMMIT"); commitBapi.Invoke(destination);
Key Notes
- Ensure the encoding used (
iso-8859-1in the example) matches your SAP system's code page—this is essential for correctly packing the structure data intoVALUEPART1. - Always validate the
RETURNtable after invoking the BAPI to catch any issues with your extension fields. - If your custom fields live in other material tables (like
MARC), extend the correspondingBAPI_TE_*structure (e.g.,BAPI_TE_MARC) and adjust the user exit code accordingly.
内容的提问来源于stack exchange,提问作者THER




