Material master creation for all organizational levels with BAPI_MATERIAL_SAVEDATA

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 😉