How to use LSMW as a wrapper for BAPIs.
Some junior developers might be a little overwhelmed the first time they are tasked with using a Business Application Programming Interface or BAPI. It is important to understand that a BAPI is just a regular function and not some mystical tool the inner workings of which can only be comprehended by the man behind the curtain.
Some SAP objects don't come with a convenient way to load their information into SAP or if they do it doesn't always work. For many objects there is one or more BAPIs that can be used to load the data without having to rely on cumbersome recordings or even more cumbersome IDOCs.
Most BAPIs have their own reporting built in. Useful validation reports created as part of the conversion step can be supplemented with the report produced by the BAPI. This allows the resource performing the load to provide a combined pre-load and post-load validation report to the business.
Determining what BAPI to use is the first step. In many cases the BAPI used to create an object is not the same BAPI used to change or delete an object. It is important to understand the ABAP language and have a familiarity with SAP's object-oriented language in order to write the wrapper correctly.
For this example the BAPIs for creating and changing the classification association to objects is used. Assigning a classification to an object is normally performed using a BDC or Direct Input with RCCLBI02
, but in some cases that doesn't work very well. Updating characteristic values with a batch calling the CL20 transaction repeatedly can be a little cumbersome and some internal BASIS teams are unable to resolve issues with logical file names that are not permitted due to customization issues.
The BAPIs for creating and changing the allocations of classifications to objects are respectively BAPI_OBJCL_CREATE
and BAPI_OBJCL_CHANGE
. The remarks in the source code give us and understanding of what parameters will be passed in and out of the function and how they must be formatted in order for the function to understand the parameters. These remarks are shown here for the purpose of edification.
FUNCTION BAPI_OBJCL_CREATE . *"---------------------------------------------------------------------- *"*"Lokale Schnittstelle: *" IMPORTING *" VALUE(OBJECTKEYNEW) LIKE BAPI1003_KEY-OBJECT *" VALUE(OBJECTTABLENEW) LIKE BAPI1003_KEY-OBJECTTABLE *" VALUE(CLASSNUMNEW) LIKE BAPI1003_KEY-CLASSNUM *" VALUE(CLASSTYPENEW) LIKE BAPI1003_KEY-CLASSTYPE *" VALUE(STATUS) LIKE BAPI1003_KEY-STATUS DEFAULT '1' *" VALUE(STANDARDCLASS) LIKE BAPI1003_KEY-STDCLASS OPTIONAL *" VALUE(CHANGENUMBER) LIKE BAPI1003_KEY-CHANGENUMBER OPTIONAL *" VALUE(KEYDATE) LIKE BAPI1003_KEY-KEYDATE DEFAULT SY-DATUM *" VALUE(NO_DEFAULT_VALUES) LIKE BAPI1003_KEY-FLAG DEFAULT SPACE *" EXPORTING *" VALUE(CLASSIF_STATUS) LIKE BAPI1003_KEY-STATUS *" TABLES *" ALLOCVALUESNUM STRUCTURE BAPI1003_ALLOC_VALUES_NUM OPTIONAL *" ALLOCVALUESCHAR STRUCTURE BAPI1003_ALLOC_VALUES_CHAR OPTIONAL *" ALLOCVALUESCURR STRUCTURE BAPI1003_ALLOC_VALUES_CURR OPTIONAL *" RETURN STRUCTURE BAPIRET2 *"----------------------------------------------------------------------
The IMPORTING
keyword denotes the values that will be passed in during the execution of the function. The EXPORTING
denotes variables that will be populated as a result of the execution of the function.
The TABLES
denotes a list of internal tables that will be passed in and out of the program. Functions can use some internal tables for input and populate other tables as a form of output. In this case the ALLOCVALUESNUM, ALLOCVALUESCHAR and ALLOCVALUESCURR represent internal tables with the characteristic values to be populated when the class is assigned to the object by the BAPI. RETURN represents an outbound table that will be populated with the report produced by the BAPI.
The remarks also describe the format that the BAPI expects the parameters to be in. The object that is to be allocated a classification is expected in the form of BAPI1003_KEY-OBJECT
. It is not enough to pass it as a character or string or even KLAH-CLASS
. The code is very specific and will err when correct data is passed in using the wrong format.
The best way to ensure that the variables are passed into the BAPI using the correct format is to define the variables in that format. Here the variables are defined using the formats from the remarks. For the sake of form the letter "L" precedes local variables, "WA" precedes a structure used as a work area and "IT" precedes an internal table.
data: lBAPI1003_KEY like BAPI1003_KEY, it_Char type standard table of BAPI1003_ALLOC_VALUES_CHAR initial size 0, it_Num type standard table of BAPI1003_ALLOC_VALUES_NUM initial size 0, it_Curr type standard table of BAPI1003_ALLOC_VALUES_CURR initial size 0, wa_Char like BAPI1003_ALLOC_VALUES_CHAR, it_BAPIRET2 type standard table of BAPIRET2 initial size 0, wa_Report type standard table of BAPIRET2 initial size 0, wa_BAPIRET2 like BAPIRET2.
The variable lBAPI1003_KEY
is an object containing the properties OBJECT
, OBJECTTABLE
, CLASSNUM
and CLASSTYPE
among others, so there is no additional need to create variables of those types.
The internal tables it_Num
, it_Curr
, it_Char
and it_BAPIRET2
will be used as parameters for the BAPI in there respective roles. The associated work area variables will be used to populate the inbound internal tables and to step through the outbound it_BAPIRET2
table.
In order to handle the hierarchical format of classification data the original program is used in LSMW, but no batch is created and no direct input is performed. This simply allows for the knitting together of the data in the formats ready for SAP.
In the BIKSSK section this code is included to populate the variables that will be passed to the BAPI. The formats for these variables is defined above.
lBAPI1003_KEY-OBJECT = BIKSSK-OBJEK. lBAPI1003_KEY-OBJECTTABLE = BIKSSK-OBTAB. lBAPI1003_KEY-CLASSNUM = BIKSSK-CLASS. lBAPI1003_KEY-CLASSTYPE = BIKSSK-KLART. *Start the characteristics internal tables as clean slates. clear it_Num. clear it_Char. clear it_Curr.
In the BIAUSP section of the hierarchy the internal tables used as parameters for the BAPI are populated one record at a time. Where the source data is a number and not a character value the it_Num
internal table is used to hold the value. This is more for form than for necessity as the BAPI is smart enough to accept all characteristic values as character values.
if CL20I-ATFLV ne ''. wa_Num-CHARACT = BIAUSP-ATNAM. wa_Num-VALUE_FROM = CL20I-ATFLV. append wa_Num to it_Num. else. wa_Char-CHARACT = BIAUSP-ATNAM. wa_Char-VALUE_CHAR = BIAUSP-ATWRT. append wa_Char to it_Char. endif.
After all of these preparations the BAPI for creating (or changing) is called using the parameters. In the remarks where the software describes importing variables, the wrapper will export those parameters. The reverse goes for parameters that are exported; they are imported by the wrapper. Internal tables can be used for import parameters, export parameters or both. Additionally, the RETURN
table is captured and added to an internal table for analysis after the fact.
call function 'BAPI_OBJCL_CREATE' exporting objectkeynew = lBAPI1003_KEY-OBJECT objecttablenew = lBAPI1003_KEY-OBJECTTABLE classnumnew = lBAPI1003_KEY-CLASSNUM classtypenew = lBAPI1003_KEY-CLASSTYPE status = '1' standardclass = 'X' changenumber = changenumber keydate = keydate no_default_values = no_default_values importing classif_status = lBAPI1003_KEY-STATUS tables allocvaluesnum = allocvaluesnum allocvalueschar = it_Char allocvaluescurr = allocvaluescurr return = it_BAPIRET2. loop at it_BAPIRET2 into wa_BAPIRET2. wa_BAPIRET2-PARAMETER = lBAPI1003_KEY-OBJECT. wa_BAPIRET2-MESSAGE_V4 = lBAPI1003_KEY-CLASSNUM. append wa_BAPIRET2 to it_Report. endloop.
Finally the BAPI_TRANSACTION_COMMIT
function is called. Even if the BAPI executes successfully nothing is written to the tables in SAP until this function is called. Alternatively the BAPI_TRANSACTION_ROLLBACK
function can be called to cancel (or rollback) the work done by the BAPI. In the sample LSMW below the option to commit or rollback the work of the BAPI is included so that the LSMW object can be used to generate detailed pre-load validation reports for the purpose of analysis without updating the SAP system.
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT' EXPORTING wait = 'X'.
Some finishing touches are added to make the interface more user-friendly. Additionally, an option to delete selected allocations is included along with the wrapper for that BAPI.
Download this LSMW object
The LSMW object using these BAPIs to create and change classification allocations is available here.
Note: Optionally the LSMW object can be used to release system locks on materials right before the BAPI attempts to allocate a classifiation. This will prevent any conflicts during the loads.