How To Run Any BAPI From VBA

Jimbo's picture

VBA LogoIn SAP, it is possible to write functions that can be called remotely. A special function with the ability to be called from outside of SAP is commonly referred to as a BAPI or "Business Application Programming Interface".

A connection to an SAP server is required to perform a function call from VBA. This sample code to create a connection to SAP was written for Excel and creates a temporary tab with instruction for the user to sign into SAP. The popup login screen for SAP often appears on another screen from the Excel spreadsheet, so this prompts the user to look for it.

Function GetR3(ByRef R3 As Object) As Boolean
    'Dim wsTemp As Worksheet
    'Set wsTemp = CreateTab("Attention")
    'wsTemp.Range("A1").Value = "Please sign into SAP."
    'wsTemp.Range("A1").Font.Size = 33
    
    Set R3 = CreateObject("SAP.Functions")
    '*************************************
    '  Put in your own credentials here.
    '*************************************
    R3.Connection.System = "P01"
    R3.Connection.SystemNumber = "00"
    R3.Connection.CLIENT = "100"
    R3.Connection.User = ""  ' Put your User ID here (optional).
    R3.Connection.Password = "" 'Put your password here (optional).
    R3.Connection.LANGUAGE = "EN"
    R3.Connection.ApplicationServer = "p01server.domain.ext"
       
    If R3.Connection.logon(0, True) <> True Then
       If R3.Connection.logon(0, False) <> True Then
            GetR3 = False
            Exit Function
       End If
    End If
    GetR3 = True
    'a = NukeTab("Attention")
End Function

Now a subroutine to call this function and populate an object with the SAP connection is called. It simply declares the connection as a generic object.

Sub GetSalesTexts()
    Dim R3 As Object, dStart As Date, nCountMARC As Long
    Dim nCurrent As Long, nCurrentRow As Long, nCurrentText As Long, nCountMVKE As Long
    Dim nCurrentRow2 As Long, nTextCount As Long
    Dim wsMVKE As Worksheet, wsTemp As Worksheet

    
    If Not GetR3(R3) Then
        'Add a popup here if desired.
        Exit Sub
    End If
    
    For nCurrent = 2 To 1048576
        'Most code to handle each row of the worksheet omitted for brevity . . .
        retval = GetMaterialTexts(R3, strMATNR, strVKORG, strVTWEG)  
    Next
    Sheets("LongTexts").Activate  'Probably not necessary as the other tabs are deleted.
    
    retval = DoEvents
    
    R3.Connection.logoff
    Set R3 = Nothing
    Columns("B:Z").AutoFit

End Sub

Like most functions, a BAPI has parameters that can be populated to pass information into the function. These parameters to the SAP function--along with the return values--are first declared as objects.

Function GetMaterialTexts(ByRef R3, strMATNR As String, strVKORG As String, strVTWEG As String) As Long

    Dim MyFunc, App As Object, Result As Boolean
    
    'Set up the variables.
    Dim MATERIAL As Object
    Dim SALESORGANISATION As Object
    Dim DISTRIBUTIONCHANNEL As Object
    
    Dim MATERIALTEXT As Object  'Sales Texts...
    
    Dim BAPIRET2 As Object 'Return is a reserved word...

Notice that the R3 variable is passed into this function where it can be used to set the MyFunc to an added RFC using the R3.Add method; the string parameter of the method is the BAPI to be called. Once the MyFunc object is set, the values to be passed into the BAPI can be populated using the MyFunc.exports method.

    Set MyFunc = R3.Add("BAPI_MATERIAL_GETALL")
    
    'Set up the values to be exported to the BAPI...
    Set MATERIAL = MyFunc.exports("MATERIAL")
    Set SALESORGANISATION = MyFunc.exports("SALESORGANISATION")
    Set DISTRIBUTIONCHANNEL = MyFunc.exports("DISTRIBUTIONCHANNEL")
    
    'Set up the variable to be imported from the BAPI...
    MATERIAL.Value = strMATNR
    SALESORGANISATION.Value = strVKORG
    DISTRIBUTIONCHANNEL.Value = strVTWEG

Notice how these ".exports" parameters in the MyFunc objects are linked to the input parameters of the BAPI as seen in SE37. The return values are in the form of internal tables; the BAPIRET2 and MATERIALTEXT objects are set after the function is called.
Calling the BAPI

This code is called after the BAPI to tease the returned values from the MATERIALTEXT object. The values are passed back as an internal table so it is required to get the name of each Column and then use the Column names to get the values from each row.

    nRowCount = MATERIALTEXT.Rows.Count
    
    If nRowCount > 0 Then
        'There is some work to do.
        Set wsOutput = GetTab("Temp") 'Okay to use this sheet.
        
        'Set up the headers in the output sheet.
        wsOutput.Range("F1").Value = "MATNR"
        wsOutput.Range("G1").Value = "VKORG"
        wsOutput.Range("H1").Value = "VTWEG"
        nColumns = 0
        For Each objROW In MATERIALTEXT.Columns
            retval = DoEvents
            'Put the name of the Column in the first row of the output sheet.
            wsOutput.Range(Chr(73 + nColumns) & "1").Value = objROW.NAME
            nColumns = nColumns + 1
        Next
        
        'Find the first available row.
        For nCurrentRow = 2 To 1048576
            If wsOutput.Range("F" & nCurrentRow) = "" Then
                Exit For  'Next available row.
            End If
        Next
    
        For Each objROW In MATERIALTEXT.Rows
            If objROW("APPLOBJECT") = "MVKE" Then 'Sales Text!
                wsOutput.Range("F" & nCurrentRow & ":Q" & nCurrentRow).NumberFormat = "@" 'Text
                For nCurrentHeader = 0 To nColumns - 1
                    'wsOutput.Range(Chr(73 + nCurrentHeader) & nCurrentRow).NumberFormat = "@" 'Text
                    wsOutput.Range(Chr(73 + nCurrentHeader) & nCurrentRow).Value = objROW(wsOutput.Range(Chr(73 + nCurrentHeader) & "1").Value)  'Pass in the field name.
                Next
                wsOutput.Range("F" & nCurrentRow).Value = strMATNR
                wsOutput.Range("G" & nCurrentRow).Value = strVKORG
                wsOutput.Range("H" & nCurrentRow).Value = strVTWEG
                nCurrentRow = nCurrentRow + 1 'Move to the next line.
            End If
        Next
        
        
        GetMaterialTexts = nRowCount
        
    End If

Finally, the tables are cleared and each object is set to Nothing. The library retains these returned tables in memory if they are not cleared using the .Rows.RemoveAll method before setting the object to Nothing.

    'Clear out all of the values from memory.  If not then they're here the next time we call the function.
    MyFunc.Tables("RETURN").Rows.RemoveAll
    MyFunc.Tables("MATERIALTEXT").Rows.RemoveAll
    
    'Clean up the memory.
    Set BAPIRET2 = Nothing
    Set MATERIAL = Nothing
    Set SALESORGANISATION = Nothing
    Set DISTRIBUTIONCHANNEL = Nothing
    Set MATERIALTEXT = Nothing
    Set wsOutput = Nothing



Examples

Here are some other examples of RFCs being used to affect change or extract data from SAP.

Here is the sample program used above. Naturally, it is provided without warranty, expressed or implied, so please use caution.
https://cdn-icons-png.flaticon.com/512/8243/8243070.png|https://cdn4.iconfinder.com/data/icons/flat-file-types-1-1/300/xlsm-512.png|https://cdn-icons-png.flaticon.com/512/8361/8361477.png|https://cdn-icons-png.flaticon.com/512/8361/8361459.png|https://ineasysteps.com/wp-content/uploads/2017/01/Code-icon.jpg|https://filewikia.com/images/icons/10356/excel-open-xml-macro-enabled-spreadsheet.png|https://png.pngtree.com/png-vector/20190419/ourmid/pngtree-xlsm-file-document-icon-png-image_955770.jpg|https://www.tudoexcel.com.br/wp-content/uploads/2022/12/XLSM-arquivo-no-excel-1.png_MaterialMasterSalesAreaExtractRFC.xlsm


Know your parameters

SAP maintains a list of Parameters for every function in the FUPARAREF table. The PARAMTYPE field tells the programmer if the field is one of these three types.

  • I -- Input parameter. These are used to pass values into the function as strings, numbers or as structures with multiple pieces of data.
  • E -- Export parameter. These are used to pass values out of the function as strings, numbers or as structures with multiple pieces of data.
  • T -- Table Parameter. These parameters are used to pass multiple values in a structured table. The structure of the table can be derived in the VBA debugger by looking at the Columns and Rows properties of the object or by interrogating the code in SE37.



The need for permissions

It is important to remember that the user account connecting to SAP must have access to call RFCs. Learn more about creating an RFC user in this article.

https://techcommunity.microsoft.com/t5/image/serverpage/image-id/27291i4FF95811E492D1AC/image-size/large?v=v2&px=999|https://cdn.extendoffice.com/images/stories/shot-kutools-excel/reading-view/shot-reading-layout.gif|https://support.content.office.net/en-us/media/8cc0eff7-d899-416d-9aef-ea6c3d71c9e8.gif|https://user-images.githubusercontent.com/4182043/32186288-b62e23a0-bd6f-11e7-83d9-ee83d9671f60.gif|https://cdn.goskills.com/blobs/blogs/203/39.gif|https://static.wixstatic.com/media/9d7f1e_a36ce5f5928142878069d5b79ebae942~mv2.gif|https://i2.wp.com/www.myofficetricks.com/wp-content/uploads/2020/11/myofficetricks.com_2020-11-23_03-53-57.gif?ssl=1|https://s37447.pcdn.co/wp-content/uploads/2016/05/12-gif.gif|https://cdn.vox-cdn.com/uploads/chorus_asset/file/21997566/exceldatatypes.gif|https://miro.medium.com/max/1400/1*t7Gy7CZb7LI-2g8cMfqJBA.gif|https://www.spreadsheetweb.com/wp-content/uploads/2019/04/How-to-filter-by-using-a-formula-in-Excel.gif|https://seotoolsforexcel.com/content/images/2016/11/intro-33.gif|https://www.bleepstatic.com/images/news/u/986406/Microsoft/Excel-JavaScript.gif|https://9.9.9.9|https://www.exceldemy.com/wp-content/uploads/2018/12/4.point-and-click-different-worksheet-keyboard.gif|https://www.vertex42.com/blog/images/excel-training/how-to-group-rows-in-excel-anim.gif|https://i1.wp.com/www.myofficetricks.com/wp-content/uploads/2019/09/SUM4.gif?ssl=1|https://support.content.office.net/en-us/media/f3544583-de81-442d-b387-dc99a76bdaa5.gif|https://www.exceltip.com/wp-content/uploads/2020/01/gif8-1.gif|https://d13ot9o61jdzpp.cloudfront.net/images/hr_dashboard_webinar.gif|https://cdn.pastemagazine.com/www/articles/Autofilter.gif|https://cdn.comsol.com/release/52a/livelink-excel/llexcel_autoupdate.gif|https://blog.hubspot.com/hs-fs/hubfs/excel-simple-math.gif?width=650&name=excel-simple-math.gif|https://d13ot9o61jdzpp.cloudfront.net/images/data_types_geography.gif|https://prodmediacdn.blob.core.windows.net/media/2020/07/New_data_types_and_smart_templates.gif|https://wmfexcel.files.wordpress.com/2019/01/excel-tips-using-structure-reference-in-conditional-formatting3.gif|https://user-images.githubusercontent.com/1297882/35767301-2fd0c490-08ea-11e8-89d7-933238fed3f2.gif|https://www.windowscentral.com/sites/wpcentral.com/files/field/image/2020/03/money_in_excel.gif