RFC调用SAP函数的过程
RFC是Remote function call,远程调用函数的意思。调用SAP函数代码基本上是模式的代码,区别在于每个函数的参数不一样。总体过程如下:
- 创建SAPLogonControl对象
- 通过SAPLogonControl.NewConnection()方法创建Connection对象
- 登陆到SAP,改变Connection对象的状态
- 通过SAPFunctions.Add()方法创建Function对象
- 填充import参数
- 函数调用
- 获取返回值
- 显示返回的结果
- 注销
在SAP系统中查看函数的参数
我们以BAPI_COMPANYCODE_GETDETAIL
函数为例,演示RFC方式调用过程和方法。用事务码SE37查看函数的参数。import参数只有一个:CompanyCodeId
输出参数有三个,类型都是structure型
- COMPANYCODE_DETAIL: company code detail
- COMPANYCODE_ADDRESS: company code address
- RETURN: SAP BAPI标准的返回值(结构型)
SAP系统测试函数
输入公司代码0001
运行,获得返回值的界面如下:
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