Option Explicit
Global MY_RFC_TABLE_01 As Object 'SAP table as defined in the RFC
Global MY_RFC_TABLE_02 As Object 'SAP table as defined in the RFC
'The RFC Function I use is defined as follows:
'As parameters I give a material-code number for a bill-of-materials (structured) to SAP
'Then the RFC fills MY_RFC_TABLE_01 with the structured BOM, one line per material
'Or I give as parameter a list of material-code numbers to SAP
'Then the RFC fills MY_RFC_TABLE_02 with the material info, one line per material
Public Sub ConnectSap(SAP As Object)
Dim ConnString As String
Dim ConnectSap As String
Set SAP = CreateObject("SAP.Functions")
SAP.Connection.System = "ZZZ" 'SAP Server ID
SAP.Connection.SystemNumber = 0 'SAP System Number
SAP.Connection.Messageserver = "SAPCLUSTER" 'SAP Message Server Name (for loadbalancing SAP-clusters)
SAP.Connection.GroupName = "SAPGROUP" 'SAP Group Name (for loadbalancing SAP-clusters)
SAP.Connection.client = "400" 'SAP Client ID
SAP.Connection.user = "USERNAME" 'SAP Username
SAP.Connection.Password = "PASSWORD" 'SAP Password
SAP.Connection.language = "EN" 'SAP Language
ConnString = SAP.Connection.logon(0, True)
If ConnString <> True Then
ConnectSap = "Connection failed!"
Else
ConnectSap = "Connection successful."
End If
If ConnectSap = "Connection failed!" Then
Call MsgBox(ConnectSap, vbOKOnly, "SAP Connection")
End
End If
End Sub
Public Sub DisconnectSap(SAP As Object)
SAP.Connection.LOGOFF
'Call MsgBox("Connection closed.", vbOKOnly, "SAP Connection")
End Sub
Public Sub FillFlatList(ByRef pFlatList As Worksheet, Optional ByVal RowNumber As Long = 1, Optional ByVal ColumnNumber As Long = 1)
'This Sub fills the SAP-table with the necessary parameter values before calling the RFC
Dim TABLEROW As Long
TABLEROW = 1
While pFlatList.Cells(RowNumber, ColumnNumber).Value <> "" And pFlatList.Cells(RowNumber, ColumnNumber).Value <> "END1"
MY_RFC_TABLE_02.Rows.Add 'adds a new row in the SAP-table
MY_RFC_TABLE_02.Value(TABLEROW, "MATNR") = pFlatList.Cells(RowNumber, ColumnNumber).Value 'assigns value to the materialnumber parameter
TABLEROW = TABLEROW + 1 'increments SAP-table rowcounter
RowNumber = RowNumber + 1 'increments Excel-sheet rowcounter
Wend
End Sub
Public Sub GetSapFlatList(ByRef TargetSheet As Worksheet, Optional ByVal StartRow As Long = 1, _
Optional ByVal StartColumn As Long = 1)
Dim SAP As Object 'SAP Connection object
Dim RFC As Object 'RFC Function object
Dim ROW As Object 'ROW object in SAP-table
Dim Result As Boolean
'Open the connection to SAP
Call ConnectSap(SAP)
Set RFC = SAP.Add("MY_RFC_FUNCTION")
Set MY_RFC_TABLE_02 = RFC.tables("MY_RFC_TABLE_02")
'Call fill_selection_table for parameters for flat list
Call FillFlatList(TargetSheet, StartRow, StartColumn)
Result = RFC.Call 'after this line, SAP filled the MY_RFC_TABLE_02 table with the results
If Result = False Then
MsgBox RFC.EXCEPTION
Call DisconnectSap(SAP)
Exit Sub
End If
'Close the SAP connection
Call DisconnectSap(SAP)
'Extract filled SAP tables to Excel worksheet
For Each ROW In MY_RFC_TABLE_02.Rows
With TargetSheet
.Cells(StartRow, StartColumn + 0).Value = ROW("MATNR") 'Material Number as defined in SAP-RFC
.Cells(StartRow, StartColumn + 1).Value = ROW("DATAFIELD1") 'Material Datafield 1 as defined in SAP-RFC
.Cells(StartRow, StartColumn + 2).Value = ROW("DATAFIELD2") 'Material Datafield 2 as defined in SAP-RFC
.Cells(StartRow, StartColumn + 3).Value = ROW("DATAFIELD3") 'Material Datafield 3 as defined in SAP-RFC
.Cells(StartRow, StartColumn + 4).Value = ROW("DATAFIELD4") 'Material Datafield 4 as defined in SAP-RFC
.Cells(StartRow, StartColumn + 5).Value = ROW("DATAFIELD5") 'Material Datafield 5 as defined in SAP-RFC
End With
StartRow = StartRow + 1
Next
End Sub
Public Sub GetSapStructBom(ByVal Topcode As Variant, ByRef TargetSheet As Worksheet, _
Optional ByVal StartRow As Long = 1, Optional ByVal StartColumn As Long = 1)
Dim SAP As Object 'SAP Connection object
Dim RFC As Object 'RFC Function object
Dim RFCPARAM As Object 'RFC Function parameter (Sapcode)
Dim ROW As Object 'ROW object in SAP-table
Dim Result As Boolean 'Result of the Remote Function Call
'Open the SAP connection
Call ConnectSap(SAP)
Set RFC = SAP.Add("MY_RFC_FUNCTION")
Set MY_RFC_TABLE_01 = RFC.tables("MY_RFC_TABLE_01")
'Setting the input parameter for the RFC
Set RFCPARAM = RFC.exports("MATNR")
RFCPARAM.Value = Topcode 'sets the parameter for SAP
'Call the Remote Function
Result = RFC.Call
'Check for Call result
If Result = False Then
MsgBox RFC.EXCEPTION
Call DisconnectSap(SAP)
Exit Sub
End If
'Close the SAP connection
Call DisconnectSap(SAP)
'Fill sheet with SAP data
For Each ROW In MY_RFC_TABLE_01.Rows
With TargetSheet
.Cells(StartRow, StartColumn + 0).Value = ROW("MATNR") 'Material Number as defined in SAP-RFC
.Cells(StartRow, StartColumn + 1).Value = ROW("DATAFIELD1") 'Material Datafield 1 as defined in SAP-RFC
.Cells(StartRow, StartColumn + 2).Value = ROW("DATAFIELD2") 'Material Datafield 2 as defined in SAP-RFC
.Cells(StartRow, StartColumn + 3).Value = ROW("DATAFIELD3") 'Material Datafield 3 as defined in SAP-RFC
.Cells(StartRow, StartColumn + 4).Value = ROW("DATAFIELD4") 'Material Datafield 4 as defined in SAP-RFC
.Cells(StartRow, StartColumn + 5).Value = ROW("DATAFIELD5") 'Material Datafield 5 as defined in SAP-RFC
End With
StartRow = StartRow + 1
Next
End Sub
'Examples of function calls to retrieve SAP-info. These functions handle the connection to SAP
'themselves, via the provided functions ConnectSap and DisconnectSap. You can also do this yourself
'by calling them directly, but it is easier to let the first function handle it, that way you
'can transparantly call the function without worrying about the SAP-connection.
Public Sub Test()
'uses ActiveSheet.Cells(2, 3).Value as parameter for the RFC and
'returns the results to the Activesheet, starting on row 6, column 1
Call GetSapStructBom(ActiveSheet.Cells(2, 3).Value, ActiveSheet, 6, 1)
'uses the values in the Activesheet as parameters (more precisely, the values in
'column 1, starting at row 6) and returns the results to the same location
Call GetSapFlatList(ActiveSheet, 6, 1)
End Sub