Material master creation for all organizational levels with BAPI_MATERIAL_SAVEDATA
March 9, 2012 3 Comments
I have to admit that I am lazy when it comes to creating test data before user trainings. Too much clicking for nothing. I’d rather stay overnight and prepare LSMW tool, eCATT tool or write some ABAP code that would either generate data or simply upload some Excel data then click it myself. This is what I’d do even if I have to add manually 3 test cases. Another good thing is that in the process of creating the tool you learn a lot about the system.
This time the problem is different, there was a need to create material master data for all organizational levels… And there were lots of them! Imagine 9 company codes, each with 1-3 plants, each plant with 1-5,6,7-13, 14, 15 or more storage locations, multiply these and you’ll see why I say “lazy”… Then there was the WM part with the warehouses, storage types and storage bins and all the materials could be placed everywhere! And the PM team asked me to do this every other week so that they could test some different scenarios… So I ABAPed my way out of it 😉
The point is the following code is just to show you that sometimes ABAPing is better than all the other tools! And with BAPI_MATERIAL_SAVEDATA you can do it all at once and you have a better insight of what is happening than with LSMW (OK.. this is just my opinion).
So let’s see what this code is all about.
First check the FM through se37 -> BAPI_MATERIAL_SAVEDATA and see which tables/structures you need. If you don’t really understand which you should use consult Google or even better consult a senior and you will realize which of them you really need. HINT: Another starting point how you can discover which of the structures you need to use is to create manually one new material in the system and see which are obligatory fields while you create it and through the technical information find out the structure where they belong. So in an hour 0r two you will (like it or not) learn all the tables that make the material master data.
REPORT ZMM_MMASTER_ALL. DATA: HEADDATA LIKE BAPIMATHEAD, CLIENTDATA LIKE BAPI_MARA, CLIENTDATAX LIKE BAPI_MARAX, PLANTDATA LIKE BAPI_MARC, PLANTDATAX LIKE BAPI_MARCX, PLANNINGDATA LIKE BAPI_MPGD, PLANNINGDATAX LIKE BAPI_MPGDX, STORAGELOCATIONDATA LIKE BAPI_MARD, STORAGELOCATIONDATAX LIKE BAPI_MARDX, VALUATIONDATA LIKE BAPI_MBEW, VALUATIONDATAX LIKE BAPI_MBEWX, WAREHOUSENUMBERDATA LIKE BAPI_MLGN, WAREHOUSENUMBERDATAX LIKE BAPI_MLGNX, SALESDATA LIKE BAPI_MVKE, SALESDATAX LIKE BAPI_MVKEX, STORAGETYPEDATA LIKE BAPI_MLGT, STORAGETYPEDATAX LIKE BAPI_MLGTX, FLAG_ONLINE LIKE BAPIE1GLOBAL_DATA-TESTRUN, RETURN LIKE BAPIRET2, S_LOC TYPE T001L-LGORT, ST_TYPE TYPE BAPI_MLGT-STGE_TYPE, SLS_ORG TYPE BAPI_MVKE-SALES_ORG. TABLES: BAPI_MAKT, BAPI_MLTX, BAPI_MLAN. TABLES: T001L, T001W. DATA: MATERIALDESCRIPTION TYPE TABLE OF BAPI_MAKT WITH HEADER LINE, MATERIALLONGTEXT TYPE TABLE OF BAPI_MLTX WITH HEADER LINE, TAXCLASSIFICATIONS TYPE TABLE OF BAPI_MLAN WITH HEADER LINE, IT_T001L TYPE TABLE OF T001L WITH HEADER LINE, IT_T001W TYPE TABLE OF T001W WITH HEADER LINE.
I am sure that by analyzing these lines of code you will learn many of the tables where the material master data is stored in SAP and the people there were nice enough to give them descriptive names in the BAPI so that you find your way out easily.
Next step internal table that represents the migration structure and will be needed in the Excel file.
* --- INTERNAL TABLE data:begin of itab occurs 0, MATERIAL type BAPIMATHEAD-MATERIAL, IND_SECTOR type c, MATL_TYPE type bapimathead-MATL_TYPE, OLD_MAT_NO type bapi_mara-old_mat_no, EXTMATLGRP TYPE BAPI_MARA-EXTMATLGRP, MATL_GROUP type bapi_mara-MATL_GROUP, MATL_DESC TYPE BAPI_MAKT-MATL_DESC, MATL_DESCMK TYPE BAPI_MAKT-MATL_DESC, BASE_UOM TYPE BAPI_MARA-BASE_UOM, TRANS_GRP TYPE BAPI_MARA-TRANS_GRP, BATCH_MGMT TYPE BAPI_MARA-BATCH_MGMT, LOADINGGRP TYPE BAPI_MARC-LOADINGGRP, AVAILCHECK TYPE BAPI_MARC-AVAILCHECK, SERNO_PROF TYPE BAPI_MARC-SERNO_PROF, MRP_TYPE TYPE BAPI_MARC-MRP_TYPE, LOTSIZEKEY TYPE BAPI_MARC-LOTSIZEKEY, MRP_CTRLER TYPE BAPI_MARC-MRP_CTRLER, SM_KEY TYPE BAPI_MARC-SM_KEY, PLND_DELRY TYPE BAPI_MARC-PLND_DELRY, ACCT_ASSGT TYPE BAPI_MVKE-ACCT_ASSGT, ITEM_CAT TYPE BAPI_MVKE-ITEM_CAT, PLACEMENT TYPE BAPI_MLGN-PLACEMENT, WITHDRAWAL TYPE BAPI_MLGN-WITHDRAWAL, * STGE_TYPE TYPE BAPI_MLGT-STGE_TYPE, STGE_BIN TYPE BAPI_MLGT-STGE_BIN, PRICE_CTRL TYPE BAPI_MBEW-PRICE_CTRL, VAL_CLASS TYPE BAPI_MBEW-VAL_CLASS, STD_PRICE TYPE BAPI_MBEW-STD_PRICE, end of itab, IT_BAPI LIKE BAPI_MAKT OCCURS 0 WITH HEADER LINE.
This table should be prepared so that it suits your needs (or your client’s needs). And following is the code for uploading the file in the table.
AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_file. PERFORM GET_FILE. START-OF-SELECTION. PERFORM UPLOAD_FILE_ITAB. PERFORM CALL_BAPI. *&---------------------------------------------------------------------* *& Form GET_FILE *&---------------------------------------------------------------------* FORM GET_FILE. CALL FUNCTION 'F4_FILENAME' EXPORTING program_name = syst-cprog dynpro_number = syst-dynnr IMPORTING file_name = p_file. ENDFORM. " GET_FILE *&---------------------------------------------------------------------* *& Form UPLOAD_FILE_ITAB *&---------------------------------------------------------------------* FORM UPLOAD_FILE_ITAB . DATA:v_file TYPE string. MOVE p_file TO v_file. CALL FUNCTION 'GUI_UPLOAD' EXPORTING filename = v_file filetype = 'ASC' has_field_separator = 'X' TABLES data_tab = itab . ENDFORM. "UPLOAD_FILE_ITAB
OK let’s get to the most serious part of this migrating code. I hope you already analyzed the BAPI and realized that for every BAPI structure there is a BAPIX 🙂 These contain the same fields like the BAPI but they are all single chars and if they have the value ‘X’ it means update should be done with the value given in the BAPI structure, if it is space update shouldn’t be done. So let’s see the core of the code…
*&---------------------------------------------------------------------* *& Form CALL_BAPI *&---------------------------------------------------------------------* form CALL_BAPI . LOOP AT ITAB. *CODE FOR CREATION SELECT * FROM T001W INTO IT_T001W WHERE BEDPL = 'X'. APPEND IT_T001W. ENDSELECT. *LOOP PLANTS / SORgs(Plant(2)00) / WHouses (Plant(3)) / StorageType(SLoc(1)0SLoc(4) LOOP AT IT_T001W. CLEAR IT_T001L[]. SELECT * FROM T001L INTO IT_T001L WHERE T001L~WERKS = IT_T001W-WERKS AND T001L~XBLGO = 'X'. APPEND IT_T001L. ENDSELECT. LOOP AT IT_T001L. *LOOP SLocs / Storage type CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT' EXPORTING INPUT = ITAB-MATERIAL IMPORTING OUTPUT = HEADDATA-MATERIAL . " HEADDATA-MATERIAL = ITAB-MATERIAL. " matnr HEADDATA-IND_SECTOR = ITAB-IND_SECTOR. " indsector HEADDATA-MATL_TYPE = ITAB-MATL_TYPE. " mattype HEADDATA-BASIC_VIEW = 'X'. HEADDATA-SALES_VIEW = 'X'. HEADDATA-PURCHASE_VIEW = 'X'. HEADDATA-MRP_VIEW = 'X'. HEADDATA-STORAGE_VIEW = 'X'. HEADDATA-WAREHOUSE_VIEW = 'X'. HEADDATA-ACCOUNT_VIEW = 'X'. *CLIENT DATA + UPDATE FIELD CLIENTDATA-MATL_GROUP = ITAB-MATL_GROUP. "matgr CLIENTDATA-BASE_UOM = ITAB-BASE_UOM. "unitmeasure CLIENTDATA-OLD_MAT_NO = ITAB-OLD_MAT_NO. CLIENTDATA-EXTMATLGRP = ITAB-EXTMATLGRP. CLIENTDATA-TRANS_GRP = ITAB-TRANS_GRP. CLIENTDATA-BATCH_MGMT = ITAB-BATCH_MGMT. CLIENTDATAX-MATL_GROUP = 'X'. "ITAB-MATL_GROUP'. "matgr CLIENTDATAX-BASE_UOM = 'X'. " ITAB-BASE_UOM. "unitmeasure CLIENTDATAX-OLD_MAT_NO = 'X'. "ITAB-OLD_MAT_NO. CLIENTDATAX-EXTMATLGRP = 'X'. "ITAB-EXTMATLGRP. CLIENTDATAX-TRANS_GRP = 'X'. "ITAB-TRANS_GRP. CLIENTDATAX-BATCH_MGMT = 'X'. "ITAB-BATCH_MGMT. PLANTDATA-PLANT = IT_T001W-WERKS. PLANTDATA-PUR_GROUP = '999'. PLANTDATA-AVAILCHECK = ITAB-AVAILCHECK. PLANTDATA-MRP_TYPE = ITAB-MRP_TYPE. PLANTDATA-LOTSIZEKEY = ITAB-LOTSIZEKEY. PLANTDATA-MRP_CTRLER = ITAB-MRP_CTRLER. PLANTDATA-SM_KEY = ITAB-SM_KEY. PLANTDATA-PLND_DELRY = ITAB-PLND_DELRY. PLANTDATA-LOADINGGRP = ITAB-LOADINGGRP. PLANTDATA-SERNO_PROF = ITAB-SERNO_PROF. PLANTDATAX-PLANT = IT_T001W-WERKS. PLANTDATAX-PUR_GROUP = 'X'. PLANTDATAX-AVAILCHECK = 'X'. PLANTDATAX-MRP_TYPE = 'X'. PLANTDATAX-LOTSIZEKEY = 'X'. PLANTDATAX-MRP_CTRLER = 'X'. PLANTDATAX-SM_KEY = 'X'. PLANTDATAX-PLND_DELRY = 'X'. PLANTDATAX-LOADINGGRP = 'X'. PLANTDATA-SERNO_PROF = 'X'. * *PLANNINGDATA-PLANT = '1100'. *PLANNINGDATA-PLNG_MATL = ''. *PLANNINGDATA-PLNG_PLANT = ''. * *PLANNINGDATAX-PLANT = 'X'. *PLANNINGDATAX-PLNG_MATL = 'X'. *PLANNINGDATAX-PLNG_PLANT = 'X'. STORAGELOCATIONDATA-PLANT = IT_T001W-WERKS. STORAGELOCATIONDATA-STGE_LOC = IT_T001L-LGORT. STORAGELOCATIONDATA-STGE_BIN = ITAB-STGE_BIN. STORAGELOCATIONDATAX-PLANT = IT_T001W-WERKS. STORAGELOCATIONDATAX-STGE_LOC = IT_T001L-LGORT. STORAGELOCATIONDATAX-STGE_BIN = 'X'. VALUATIONDATA-VAL_AREA = IT_T001W-WERKS. VALUATIONDATA-PRICE_CTRL = ITAB-PRICE_CTRL. VALUATIONDATA-VAL_CLASS = ITAB-VAL_CLASS. VALUATIONDATA-STD_PRICE = ITAB-STD_PRICE. VALUATIONDATAX-VAL_AREA = IT_T001W-WERKS. VALUATIONDATAX-PRICE_CTRL = 'X'. VALUATIONDATAX-VAL_CLASS = 'X'. VALUATIONDATAX-STD_PRICE = 'X'. *WAREHOUSENUMBERDATA WAREHOUSENUMBERDATA-WHSE_NO = IT_T001W-WERKS(3). WAREHOUSENUMBERDATA-PLACEMENT = ITAB-PLACEMENT. WAREHOUSENUMBERDATA-WITHDRAWAL = ITAB-WITHDRAWAL. WAREHOUSENUMBERDATAX-WHSE_NO = IT_T001W-WERKS(3). WAREHOUSENUMBERDATAX-PLACEMENT = 'X'. WAREHOUSENUMBERDATAX-WITHDRAWAL = 'X'. *STORAGETYPEDATA CONCATENATE IT_T001L-LGORT(2) IT_T001L-LGORT+3(1) INTO ST_TYPE. STORAGETYPEDATA-WHSE_NO = IT_T001W-WERKS(3). STORAGETYPEDATA-STGE_TYPE = ST_TYPE. STORAGETYPEDATA-STGE_BIN = ITAB-STGE_BIN. STORAGETYPEDATAX-WHSE_NO = IT_T001W-WERKS(3). STORAGETYPEDATAX-STGE_TYPE = ST_TYPE. STORAGETYPEDATAX-STGE_BIN = 'X'. *SALESDATA CONCATENATE IT_T001W-WERKS(2) '00' INTO SLS_ORG. SALESDATA-SALES_ORG = SLS_ORG. SALESDATA-DISTR_CHAN = '99'. SALESDATA-ITEM_CAT = ITAB-ITEM_CAT. SALESDATA-ACCT_ASSGT = ITAB-ACCT_ASSGT. SALESDATAX-SALES_ORG = SLS_ORG. SALESDATAX-DISTR_CHAN = '99'. SALESDATAX-ITEM_CAT = 'X'. SALESDATAX-ACCT_ASSGT = 'X'. * MATERIAL DESCRIPTION - MK & EN MATERIALDESCRIPTION-LANGU = '봋'. MATERIALDESCRIPTION-LANGU_ISO = 'MK'. MATERIALDESCRIPTION-MATL_DESC = ITAB-MATL_DESCMK. APPEND MATERIALDESCRIPTION. MATERIALDESCRIPTION-LANGU = 'E'. MATERIALDESCRIPTION-LANGU_ISO = 'EN'. MATERIALDESCRIPTION-MATL_DESC = ITAB-MATL_DESC. APPEND MATERIALDESCRIPTION. *TAXCLASSIFICATIONS *MK Macedonia MWST Output Tax 1 Taxable TAXCLASSIFICATIONS-DEPCOUNTRY = 'MK'. TAXCLASSIFICATIONS-DEPCOUNTRY_ISO ='MK'. TAXCLASSIFICATIONS-TAX_TYPE_1 = 'MWST'. TAXCLASSIFICATIONS-TAXCLASS_1 = '1'. APPEND TAXCLASSIFICATIONS. CALL FUNCTION 'BAPI_MATERIAL_SAVEDATA' EXPORTING HEADDATA = HEADDATA CLIENTDATA = CLIENTDATA CLIENTDATAX = CLIENTDATAX PLANTDATA = PLANTDATA PLANTDATAX = PLANTDATAX * FORECASTPARAMETERS = * FORECASTPARAMETERSX = * PLANNINGDATA = PLANNINGDATA * PLANNINGDATAX = PLANNINGDATAX STORAGELOCATIONDATA = STORAGELOCATIONDATA STORAGELOCATIONDATAX = STORAGELOCATIONDATAX VALUATIONDATA = VALUATIONDATA VALUATIONDATAX = VALUATIONDATAX WAREHOUSENUMBERDATA = WAREHOUSENUMBERDATA WAREHOUSENUMBERDATAX = WAREHOUSENUMBERDATAX SALESDATA = SALESDATA SALESDATAX = SALESDATAX STORAGETYPEDATA = STORAGETYPEDATA STORAGETYPEDATAX = STORAGETYPEDATAX * FLAG_ONLINE = ' ' * FLAG_CAD_CALL = ' ' * NO_DEQUEUE = ' ' * NO_ROLLBACK_WORK = ' ' IMPORTING RETURN = RETURN TABLES MATERIALDESCRIPTION = MATERIALDESCRIPTION * UNITSOFMEASURE = * UNITSOFMEASUREX = * INTERNATIONALARTNOS = * MATERIALLONGTEXT = MATERIALLONGTEXT TAXCLASSIFICATIONS = TAXCLASSIFICATIONS * RETURNMESSAGES = * PRTDATA = * PRTDATAX = * EXTENSIONIN = * EXTENSIONINX = . CALL FUNCTION 'BAPI_TRANSACTION_COMMIT' . write: 'PLANT: ',IT_T001W-WERKS, ' STORAGE LOCATION: ', IT_T001L-LGORT, ' ', RETURN-type , ' MESSAGE:', RETURN-MESSAGE, '/'. WAIT UP TO 2 SECONDS. ENDLOOP. ENDLOOP. ENDLOOP. " itab ENDFORM. "call_bapi
Run the code, go make some coffee and check the results after it is done 😉