Skip to Content
Technical Articles

Call SAP Business Application Programming Interface using SAP Intelligent RPA

Hello Everyone,

SAP Business Application Programming Interface (BAPI) provides interface to access processes and data defined in SAP Business Application System such as SAP E-Commerce for SAP R/3 or SAP S/4HANA system.

BAPIs are implemented generally as RFC enabled function modules. It also acts as function to a business object defined in BOR(Business Object Library). BAPIs provide stable and standard interfaces to interact with SAP back-end system.

Today we will demonstrate one example to showcase how to make a call to BAPI interface from SAP Intelligent RPA.

The basic technology we use to connect to SAP back-end system is SAP ActiveX component. Here is a comprehensive list of ActiveX control that can be used. Today we will demonstrate the “Function Control” specifically.

The example below is about getting the user information from the SAP system by passing the user-id as a parameter. We will create the activeX object and pass user-name as a parameter to the function. We will then make a call to BAPI, extract the export values and log the information to the log.

  • Open the “SAP Intelligent Robotic Process Automation Desktop” from your windows system.
  • Create an empty Project by going to File -> New Project. Enter the details about your project.
  • Go to Editor View (JavaScript) and open the Test JavaScript library.
  • Remove all the code and copy paste the code below to this file.
/** main process stop handler */
GLOBAL.events.QUIT.on(function (ev) {
});

/** main process start handler */
GLOBAL.events.START.on(function (ev) {
     systray.addMenu('', 'evTestBAPIActiveX', 'Test BAPI connectivity', '', function (ev) {
     bapi();
});
});

/** This method is used internally to initialize the BAPI object. */
function getBAPI(){
    var BAPI = new ActiveXObject("SAP.Functions");
    var Connection = BAPI.Connection;
    Connection.ApplicationServer = "<IP/name of app server>"; //Change this
    Connection.SystemNumber = 'xx'; //Change this
    Connection.Client = "xxxx"; //Change this
    Connection.User = "xxxx"; //Change this
    Connection.Password = "xxxx"; //Change this
    Connection.logon(0, true);
    return BAPI;
}

/** This method gets called when systray menu is selected. */
function bapi() {
    var BAPI = getBAPI();
    var UserInfo = BAPI.Add("BAPI_USER_GET_DETAIL");
    var UserImport = UserInfo.exports("USERNAME");
    UserImport.value = "xxxx"; //Change this
    UserInfo.Call();
    var Address = UserInfo.imports("ADDRESS");
    ctx.log('status= ' + Address("FIRSTNAME") + " " + Address("LASTNAME"));
}
  • Replace the system details and credentials accordingly. Look for comments “//Change this”.
  • Now run the scenario from desktop studio in debug mode. You will see agent coming up in sys tray. Select the menu “Test BAPI connectivity” and the bot will execute.
  • You will see a log in console about the users first name and last name.

Note: The first call to the BAPI will take some time, but 2nd call onward performance will be much better.

Follow SAP Intelligent RPA on Twitter and LinkedIn.

Share your feedback and happy bot building!

/
41 Comments
You must be Logged on to comment or reply to a post.
  • Hello Vijay G,

    thanks for your blog.

    With all respect I am not really sure if the using of a deprecated technology, like the ActiveX libraries, in the context of IRPA is really a good idea. Frank Krause wrotes on the 31st of May 2017 about the ActiveX libraries. Very often we have here in the forums requests about compatibility problems with the ActiveX libraries. In my opinion it is better to wait for an integrated IRPA solution, it seems that all the prerequisites are there. Hope this is only a small step.

    Best regards
    Stefan

  • Good morning Vijay G.

    I use your code and tried to invoke the BAPI, it seems to return a connection because getBAPI get back and object which all methods you can use for example: Add, aboutBox, CreateStructure, Remove, RemoveAll between others, but when it is trying to add the BAPI “BAPI_USER_GET_DETAIL” I’ve got the following error:

    ctx: ‘Action’
    action: ‘ctx.log’
    params:
    [0]: ‘No connection to SAP system available.’
    [1]: 1
    verb: ‘LOGMESS’
    parentId: 70
    name: ‘SyntaxError’
    message: ‘No connection to SAP system available.’
    number: -2146827287
    description: ‘No connection to SAP system available.’

    As enter parameters I am using:

    1. ApplicationServer
    2. SystemNumber
    3. Client
    4. User
    5. Password
    6. SAPRouter

    Could you give advice. Thanks

    • Are you able to login to the system with SAP logon from the same system? Since this is using the activeX route, it expects the corresponding dll files. From the error it seems to be the connection error.

      • Hi Vijay I’m having the same problem but I don’t understand what dll files are necessary and where to put it those , could you give more scope to solve my issue please.

  • Hi Vijay G

    I can already connect to the BAPI and get data from import and export, but it does me hard to fetch data from a table. How to do that? Do you have the suitable syntax?

    it does not display the values.

    This is the data from ERP

    I need to dispatch this data to Excel. Anything idea how to to do this.

  • Hi Luis,

    The issue seems to be related to your access of a BAPI Tables there.

     

    As this is a type of array, it should be treated as an enumeration and looped. Here is an example of a case.

    var ProfTable = UserInfo.tables(“PROFILES”);

    for (var enumerator = new Enumerator(ProfTable.Rows); !enumerator.atEnd(); enumerator.moveNext()) {

    var ProfTableRow = enumerator.item();

    ctx.log(“Profile= ” + ProfTableRow(“BAPIPROF”) + ” ” +ProfTableRow(“BAPIPTEXT”) );

    }

     

    Here there is parameter of type Tables which is called PROFILES. Once you get that table you need to iterate through it.

    Each row has 2 fields BAPIPROF and BAPIPTEXT. Once the row from iterator is extracted it can be used as explained.

     

    Maybe could you adapt your code in a similar way.

    • I really appreciate your help Sabine. I was stuck, I didn’t know how to go forward. Thanks to that, I can read the data and bring them to context variable to finally drawing them in Excel.

  • Hi people

    Just now I have another issue with this bot.

    The first time I tried to connect to the system, I checked “hold my decision” and clicked “Allow” and worked, up to date that falls and show me “No connection to SAP system available”

    I tried in different ways to fix this issue but without success.

    Now, I tried to connect to another system. it is going out the same message. I am sure if I check the same will work. But surely is missing something in my connection. Could you someone help me, please?

    Here, my param connections.

  • Hello Vijay,

    The following lines of code are to pass input parameters to the BAPI.

    var UserImport = UserInfo.exports (“USERNAME”);
    UserImport.value = “xxxx”; // Change this

    Now, how do you pass a table as input?

    Could you give advice. Thanks

    Best regards,
    Miguel Rojas

    /
    • Hi Miguel,

      See reply from Sabine above. I am putting the code snippet below.

      //Read table parameter
      var ProfTable = UserInfo.tables(“PROFILES”);
      
      //Iterate through the tables parameter
      for (var enumerator = new Enumerator(ProfTable.Rows); !enumerator.atEnd(); enumerator.moveNext()) {
         var ProfTableRow = enumerator.item();
         ctx.log(“Profile= ” + ProfTableRow(“BAPIPROF”) + ” ” +ProfTableRow(“BAPIPTEXT”) );
      }

      Best Regards,

      Vijay

      • Thank you Vijay.

        But I understand that this is the way to iterate through it an answer table.

        In my case, I need to pass tables to the BAPI as input parameters.

        Best regards,

        Miguel Rojas

        /
        • Ok, to add a row to table please use the below code.

          var row = UserInfo.tables("PROFILES").Rows.Add;
          row("BAPIPROF") = "Value1";
          row("BAPIPTEXT") = "Value2";

          Hope this helps!

          Best Regards,

          Vijay

          • Thank you Vijay,

            With the following line of code, it is possible to recover the structure of the table:

            var row = matGetList.tables(“MATNRSELECTION”).Rows.Add;

            But it is not possible to add the values to these fields, see attached image

            Could you give advice. Thanks

             

            Best regards,

            Miguel Rojas

            /
          • Once the Add is called, in index will increment by 1. The row value that you get back can be used to modify the value of the row. I have tested it and it works fine.

          • I was able to get advice from Vijay and got it working.

            Thank you very much Vijay.

            In case any of you have the same question, below is the corrected code.

            You will get a compile error, but if you go to File-> Settings-> Debugger-> Compilation-> Check the box “Allow Run with Compile Errors”, you will be able to continue debugging and get the expected result.

            Per Vijay, SAP will fix this bug in the Desktop Studio soon.

            /
          • Now I have another BAPI, in which the input parameter is a structure in the IMPORT section.

            My question is, how can I pass those values to the CENTRALDATAPERSON structure? Clearly, the above code does not apply in this case.

          • Hi Miguel,

            your post is not displaying the images. The initial post has details on how to pass structure to BAPI.

            Regards, Vijay
          • Hi Vijay.

            I updated my post..

            This case is different from the previous one, in which a table was passed as input parameter in the tables section, now it is a structure in the Import section.

            Best regards,

            Miguel

          • Hi Miguel,

            If the FM has a imports structure you will use it in call as exporting parameter.

            var DataPerson= UserInfo.exports(“CENTRALDATAPERSON”);
            DataPerson(“FIRSTNAME”) = “TEST – First name”;
            DataPerson(“LASTNAME”) = “TEST Value – Last name”;

            This is how you need to work with structure.

            Regards, Vijay

          • Hello Vijay,

            Thank you very much for the solution provided. Now I have the following issue:

            After executing the call to BAPI_BUPA_CREATE_FROM_DATA , I get the value of NumberBP (in the code below), but the BP is not registered in SAP tables. For this reason I call another function BAPI_TRANSACTION_COMMIT… I don’t get any errors, but the creation doesn’t finish successfully.

            Please check the code below:

            Thank you very much in advance.

            Best regards,

            Miguel

             

            /
          • Hi Miguel,

            Again your reply does not show images correctly.

            Based on what you wrote, does not seems to be an issue with BAPI connector. It is the way the FM has to be used. i would suggest you to try reading the documentation correctly and try out the scenario directly in the ABAP system via se37 -> execute. Once you have it working then you can try replicating to the BOT.

            Regards, Vijay

          • Hi Vijay,

            I updated my post..

            The BAPI works correctly, I have a variant in SAP S/4 HANA that validates this execution.

             

            Best regards,

            Miguel

          • Hi,

            This is mainly because of  the way you have structured the code. You should not instantiate BAPI object for every BAPI call. You need to keep the connection object globally and add BAPI to the same connection. Otherwise the commit will not happen. This was not clear from your screenshot but I looked at the ticket to understand it. Hope this resolved your issue.

            Regards,

            Vijay

  • Hi  Vijay G / Luis Guerra /  Joanna Shi / Miguel Rojas

    Thanks for sharing this wonderful blog.

    I have been trying this and facing couple of issues.

    it doen’t seems like BAPI call is working.

    I tried to print the output BAPI output parameter “OBJ_KEY” to check if i got any value, but it printing $ instead of the document number .

    I tried to fetch the “RETURN” table values and again i am getting the type error at row no 91 in screen shot below. I don’t see document any document number generated in the back-end also.

    I tried printing the Doc_Date and PSTNG_DATE to log and it is coming out to be blank.

    Please see my complete code blow and please help to figure out the possible issue.

        var BAPI = getBAPI();
        var postBapi = BAPI.Add("BAPI_ACC_DOCUMENT_POST");
        var commitBapi =  BAPI.Add("BAPI_TRANSACTION_COMMIT");
    var txt = ctx.getDate();
    			
    	//var row = hdrdata.Rows.Add;	
    	var hdrdata = postBapi.exports("DOCUMENTHEADER");
    	hdrdata("OBJ_TYPE") = "BKPFF";
    	hdrdata("OBJ_SYS") = "SXXCLNT200";
    	hdrdata("BUS_ACT") = "RFBU";
    	hdrdata("HEADER_TXT") = "RFC demo";
    	hdrdata("COMP_CODE") = "1810";
    	hdrdata("DOC_DATE") =  txt;
    	hdrdata("PSTNG_DATE") = txt;
    	hdrdata("FISC_YEAR") = "2020";
    	hdrdata("FIS_PERIOD") = "02";
    	hdrdata("DOC_TYPE") = "AB";
    	hdrdata("REF_DOC_NO") = "Demo Reference";
    	
    	var GLData =  postBapi.tables("ACCOUNTGL");
    		
    	var glrow = GLData.rows.add;	
    	glrow("ITEMNO_ACC") = "0000000001";
    	glrow("GL_ACCOUNT") = "10010000";
    	glrow("ITEM_TEXT") = "ITEM TEXT 1";
    	
            glrow = GLData.rows.add;	
    	glrow("ITEMNO_ACC") = "0000000002";
    	glrow("GL_ACCOUNT") = "10010000";
    	glrow("ITEM_TEXT") = "ITEM TEXT 2";	
    	
    	var CurrData =  postBapi.tables("CURRENCYAMOUNT");
    	
    	var Currow = CurrData.rows.add;
    	Currow("ITEMNO_ACC") = "0000000001";
    	Currow("CURR_TYPE") = "00";
    	Currow("CURRENCY") = "USD";
    	Currow("AMT_DOCCUR") = "1410";
    	
    	Currow = CurrData.rows.add;
    	Currow("ITEMNO_ACC") = "0000000002";
    	Currow("CURR_TYPE") = "00";
    	Currow("CURRENCY") = "USD";
    	Currow("AMT_DOCCUR") = "1410-";
    	
    	postBapi.Call();
    	
    	commitBapi.Call();
    	
    	var objKey = postBapi.imports("OBJ_KEY");
    	ctx.log(objKey.value);	
    	
    	var Resp = postBapi.tables("RETURN");
    	
    	for ( var Enumerator = new Enumerator(Resp.rows); !Enumerator.atEnd(); Enumerator.maveNext())
    	{
    		var repRow = Enumerator.item();
    		ctx.log("Message= " + repRow("BAPI_MSG"));
    	}
    
    /
    • Did you check if the BAPI is calling successfully using se37? Use the same data in IRPA and check. May be there is some validation error happening in BAPI.

      Also try to build the date in the format(that the BAPI accepts I guess(YYYYMMDD) format) and put it as a string.

  • Hi All,

    After a successful call to a ‘Z’ RFC function module, I am trying to IMPORT (and not TABLES) a parameter that is defined as table type. What is the way to read this table type and get the data from each row?

    e.g.

    var BAPI = getBAPI();

    var MyDocs = BAPI.Add(“ZfunctionModule”);

    var TicketId = MyDocs.exports(“OBJECTID”);

    TicketId.value = “1234567890”;

     

    MyDocs.Call();

    var DocList = MyDocs.imports(“T_ATTACHMENTS”);

     

    Now T_ATTACHMENTS is defined as a table type in ABAP with line type, say columns ‘FILE_NAME’ and ‘FILE_SIZE’.

    Regards.

    Lalit

    • This is to me a limitation for now. Generally if you have tables in import/export it will be included in tables. See if you can change it in Z FM.

  • Hi Vijay G,

    Thank you very much for your advice about call BAPI using SAP iRPA now

     

    For now, I can read data from BAPI table.

    But I try to read “FIRSTNAME” and “LASTNAME” when use UserInfo.imports(“ADDRESS”)

    There is error as “Structure member not found “FIRSTNAME”.

     

    Please give me an advice.

    Best Regards

    • go to File-> Settings-> Debugger-> Compilation-> Check the box “Allow Run with Compile Errors”. Its a studio JS validation error. BAPI expects the assignment in a specific way.

  • Hi Vijay G,

    Thank you very much for your advice about call BAPI using SAP iRPA.

    I have tried testing your code, but when doing the build, it gives me the error “Property connection never defined on BAPI” … and I don’t know why … any idea?

    I don’t know what to look at anymore …

    Thanks in advance.

    Best Regards.

     

    • go to File-> Settings-> Debugger-> Compilation-> Check the box “Allow Run with Compile Errors”. Its a studio JS validation error. BAPI expects the assignment in a specific way. See with this you are able to run. There will still be error displayed but you can continue and execute.

  • Hello my bot is working fine and updating records . But whenever i try to run it after commit it gives me this pop.So Always i have to click on this OK button to continue for next record . Please suggest me how to suppress this pop up.

     

    POP%20UP

    POP UP

    /
    POP%20UP
  • Hello Vijay,

    I have “parse error. invalid assignment target” . It prevents project from building nad regeneration of workflow code.

    getBAPI( rootData );
    var BAPI = rootData.BAPI.BAPI;

    var UserInfo = BAPI.Add(“Z_OP_SALES_ORDER_CREATE”);

    var it_items = UserInfo.tables(“ITEMS_IN”);

    var z = rootData.SO_items[i];
    var item = it_items.Rows.Add;

    item(“POSNR”) = z.posnr;  // on this line the parse error is

     

    The BAPI call works if I set settings “Allow run with Compile Error” but the workflow code is not regenerated.

    If I use item(“POSNR”).value = z.posnr;  then there is no parse error, but the value is not passed to BAPI.

    The same error is in bot from the Store BAPI_SALESORDER_CREATE.

    /
  • Hello I´m using the bot “Creation of Business Partner” but i have the next error “SAP Connection Failed” in the trace of the program is showing error “LOGMESS” and reading other comments from laters post it´s looks that is related to Activex .dll files but really I don’t have any idea where to get them and where to put it, into the options of Internet Explorer all referring to this theme is enabled, someone can help me with the info to solve this error, thanks in advanced.

     

    /
  • Hi All,

    I am trying to create a purchase requisition number using BAPI_REQUISITION_CREATE.

    I am facing issue while passing Delivery Date (Error : object expected)

    var BAPI = getBAPI();

    var postBapi = BAPI.Add(“BAPI_REQUISITION_CREATE”);

    var postValue1 = postBapi.tables(“REQUISITION_ITEMS”);

    var postValue = postValue1.Rows.add;

    postValue(“PREQ_ITEM”).value = “00010”;

    postValue(“DOC_TYPE”).value = “AB”;

    postValue(“PUR_GROUP”).value = “006”;

    postValue(“CREATED_BY”).value =”xyz”;

    postValue(“MATERIAL”).value = “000000000000001234”;

    postValue(“PLANT”).value = “6000”;

    postValue(“STORE_LOC”).value = “0006”;

    postValue(“QUANTITY”).value = “10”;

    postValue(“DELIV_DATE”).value = “20201020”; // YYYYMMDD

    postBapi.Call();

    var prNumber = postBapi.imports(“NUMBER”);

    ctx.log(“PrNumber = ” + prNumber(“number”));