RFC調用SAP函數的過程
RFC是Remote function call,遠程調用函數的意思。調用SAP函數代碼基本上是模式的代碼,區別在于每個函數的參數不一樣。總體過程如下:
RFC-3-1.jpg
- 創建SAPLogonControl對象
- 通過SAPLogonControl.NewConnection()方法創建Connection對象
- 登陸到SAP,改變Connection對象的狀態
- 通過SAPFunctions.Add()方法創建Function對象
- 填充import參數
- 函數調用
- 獲取返回值
- 顯示返回的結果
- 注銷
在SAP系統中查看函數的參數
我們以BAPI_COMPANYCODE_GETDETAIL
函數為例,演示RFC方式調用過程和方法。用事務碼SE37查看函數的參數。import參數只有一個:CompanyCodeId
RFC-3-2.jpg
輸出參數有三個,類型都是structure型
- COMPANYCODE_DETAIL: company code detail
- COMPANYCODE_ADDRESS: company code address
- RETURN: SAP BAPI標準的返回值(結構型)
RFC-3-3.jpg
SAP系統測試函數
輸入公司代碼0001
RFC-3-4.jpg
運行,獲得返回值的界面如下:
RFC-3-5.jpg
VBA代碼編寫
VBE添加對SAPFunctions控件的引用
方法不再贅述,參考上一篇。SAPFucntions控件的文件名為wdtfuncs.ocx,Windows 7 64位的默認路徑:C:\Program Files (x86)\SAP\FrontEnd\SAPgui。
代碼
代碼分為兩個module, module1為SAP Connection
Option Explicit
Public sapLogon As SAPLogonCtrl.SAPLogonControl
Public sapConnection As SAPLogonCtrl.Connection
Public Sub Logon()
Set sapLogon = New SAPLogonCtrl.SAPLogonControl
Set sapConnection = sapLogon.NewConnection()
Call sapConnection.Logon(0, False)
End Sub
Public Sub Logoff()
If sapConnection.IsConnected = tloRfcConnected Then
sapConnection.Logoff
End If
End Sub
Module2為RFC調用:
Option Explicit
Public Sub GetCompanyCodeData()
Dim functions As SAPFunctionsOCX.SAPFunctions
Dim fm As SAPFunctionsOCX.Function
' BAPI_COMPANYCODE_GETDETAIL的三個輸出參數,都是structure,'
' 對VB來說這些是輸入參數,獲得SAP返回的信息'
Dim ret As SAPFunctionsOCX.Structure '返回值'
Dim coCdDetail As SAPFunctionsOCX.Structure '公司代碼信息'
Dim addrData As SAPFunctionsOCX.Structure '地址信息'
' Step 1: 登陸SAP'
Call Logon
' 如果連接成功,調用BAPI'
If sapConnection.IsConnected <> tloRfcConnected Then
MsgBox "連接失敗!."
Exit Sub
End If
' Step 2: 創建functions(集合)'
Set functions = New SAPFunctionsOCX.SAPFunctions
Set functions.Connection = sapConnection
' Step 3 : 將BAPI加到SAPFunctions'
Set fm = functions.Add("BAPI_COMPANYCODE_GETDETAIL")
' Step 4: 填充參數, importing parameter對VB來說是輸出參數'
fm.Exports("COMPANYCODEID").Value = "0001"
' Step 5: 調用FM'
fm.Call
' 確定沒有Exceptions'
If fm.Exception <> "" Then
Exit Sub
End If
' Step 6: 獲取函數返回的信息'
Set ret = fm.Imports("RETURN") 'return參數是一個結構'
Set coCdDetail = fm.Imports("COMPANYCODE_DETAIL")
' Step 7: 展示return Values'
' 因為RETURN是一個structure(結構),用遍歷的方法得到structure各column的值'
Dim i As Integer
For i = 1 To ret.ColumnCount '從1開始'
Debug.Print ret.ColumnName(i) & ":" & ret.Value(i)
Next
Debug.Print "===================================" ' 分割'
' 展示SAP返回的公司代碼明細(company code detail)'
For i = 1 To coCdDetail.ColumnCount
Debug.Print coCdDetail.ColumnName(i) & ":" & coCdDetail.Value(i)
Next
' Step 8: Logoff'
Call Logoff
End Sub
要點說明
- SAPFunctions集合:SAPFunctions集合也可以使用晚綁定,代碼如下:
Dim functions As Object
Set functions = CreateObject(“SAP.Functions”)
- Function對象的初始化
Function對象是通過SAPFunctions.Add()方法來創建和初始化的:
Dim fm As SAPFunctionsOCX.Function
Set fm = functions.Add("BAPI_COMPANYCODE_GETDETAIL")
- SAP函數的參數
SAP函數參數分為單值型、結構型和表類型,對于VBA來說,SAP定義的輸入函數是VB的輸出參數,本例演示了單值參數的賦值方法:fm.Exports(“COMPANYCODEID”).Value = “0001”
其他類型的填充方法后面再做介紹。
SAP的輸出參數,對于VBA來說是輸入參數,大多情況下,輸出參數是結構和表類型。如果是結構類型,通過循環的方式獲取列名和每列的值。
列名:someStructure.ColumnName(index)
列值:someStructure.Value(i)
(使用field索引值,注意column從1開始,而不是0)
列值:someStructure.Value(“FieldName”)
(使用列名)
Dim coCdDetail As SAPFunctionsOCX.Structure
Dim i As Integer
Set coCdDetail = fm.Imports("COMPANYCODE_DETAIL")
For i = 1 To coCdDetail.ColumnCount
Debug.Print coCdDetail.ColumnName(i) & ":" & coCdDetail.Value(i)
Next