SAP 大量使用 Table 作为参数,表达二维的数据。Table 可以作为输入参数,也可以作为输出参数。我们首先来看看 Table 作为输出参数的用法。
添加 TableFactory 控件的引用
为了使用 Table 接收数据,需要使用 tableFactory 控件。控件为wdtaocx.ocx,Windows 7下默认的路径为:
C:\Program Files (x86)\SAP\FrontEnd\SAPgui。
TableFactory 的数据读取
Table 是一个二维的形式,读取的方法由多种。详细介绍读者可以参考PA教材 BIT525。
按单元格方式读取
oTable.Value(x, y)
因为列有名称,对于列来说,也可以用列名,比如说y列的名称为CODE,则表示为
oTable.Value(x, "CODE")
按行方式读取
oTable.Rows.Item(x)表示x行
oTable.Rows.Item(x).Value (y) 表示x行y列的值
或者用简写形式
oTable.Rows(x)表示x行
oTable.Rows(x).Value (y)
按列方式读取
oTable.Columns.Items(y)表示y列
oTable.Columns.Item(y).Value (x) 表示x行y列的值
或者用简写形式
oTable.Columns(y)表示y列
oTable.Columns(y).Value (x)
为了说明table参数的用法,我们以 BAPI_COMPANYCODE_GETLIST
函数为例。这个函数的table参数返回SAP系统已经创建的公司代码清单。
Option Explicit
Dim sapLogon As SAPLogonCtrl.SAPLogonControl
Dim sapConn As SAPLogonCtrl.Connection
Public Sub Logon()
Set sapLogon = New SAPLogonControl
Set sapConn = sapLogon.NewConnection
sapConn.Logon 0, False
End Sub
Public Sub Logoff()
If sapConn.IsConnected = tloRfcConnected Then
sapConn.Logoff
End If
End Sub
Public Sub GetCoCdList()
Dim functions As SAPFunctionsOCX.SAPFunctions
Dim fm As SAPFunctionsOCX.Function
Dim cocdDetail As SAPTableFactoryCtrl.Table
Call Logon
Set functions = New SAPFunctions
Set functions.Connection = sapConn
' FM加入Functions集合
Set fm = functions.Add("BAPI_COMPANYCODE_GETLIST")
'调用
fm.Call
'得到Table参数
Set cocdDetail = fm.Tables("COMPANYCODE_LIST")
' 打印出公司代码的名称
Dim row As Integer
For row = 1 To cocdDetail.RowCount
Debug.Print cocdDetail.Value(row, "COMP_NAME")
Next
Call Logoff
End Sub
因为cocdDetail是一个二维表,所以使用遍历的方式取得所有公司代码的列表。为了更具一般性,我们可以写一个通用的routine,将internal table输出到Excel单元格。
Public Sub WriteTable(itab As SAPTableFactoryCtrl.Table, sht As Worksheet)
Dim col As Long ' column index
Dim row As Long ' row index
Dim headerRange As Variant '在Excel中根据itab的header大小,类型为Variant数组
Dim itemsRange As Variant '在Excel中根据itab的行数和列数,类型为Variant数组
If itab.RowCount = 0 Then Exit Sub
'-------------------------------------------------
' 取消Excel的屏幕刷新和计算功能以加快速度
'-------------------------------------------------
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
' 清除cells的内容
sht.Cells.ClearContents
'------------------------------
' 将Table的Header写入Worksheet
'------------------------------
' 根据内表的列数,使用Range创建一个数组
Dim headerstarts As Range
Dim headerends As Range
Set headerstarts = sht.Cells(1, 1)
Set headerends = sht.Cells(1, itab.ColumnCount)
headerRange = sht.Range(headerstarts, headerends).Value
' 将内表列名写入数组
For col = 1 To itab.ColumnCount
headerRange(1, col) = itab.Columns(col).Name
Next
' 从数组一次性写入Excel,这样效率较高
sht.Range(headerstarts, headerends).Value = headerRange
'-------------------------------
' 将Table的行项目写入Worksheet
'-------------------------------
' 根据内表的大小,使用Range创建数组
Dim itemStarts As Range
Dim itemEnds As Range
Set itemStarts = sht.Cells(2, 1)
Set itemEnds = sht.Cells(itab.RowCount + 1, itab.ColumnCount)
itemsRange = itab.Data
' 一次性将数组写入Worksheet
sht.Range(itemStarts, itemEnds).Value = itemsRange
'---------------------------------
' 恢复Excel的屏幕刷新和计算
'---------------------------------
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
End Sub
有了以上通用routine,程序可以简化为:
Public Sub GetCompanyCodeList()
Dim functions As SAPFunctionsOCX.SAPFunctions
Dim fm As SAPFunctionsOCX.Function
Dim cocdDetail As SAPTableFactoryCtrl.Table
If sapConnection Is Nothing Or sapConnection.IsConnected <> tloRfcConnected Then
MsgBox "没有连接到目标SAP系统,请先建立连接!", vbExclamation
Exit Sub
End If
Set functions = New SAPFunctions
Set functions.Connection = sapConnection 'lonon成功后,sapConnection为SAP连接
' FM加入Functions集合
Set fm = functions.Add("BAPI_COMPANYCODE_GETLIST")
'调用FM
fm.Call
'通过Table参数获得company code details
Set cocdDetail = fm.Tables("COMPANYCODE_LIST")
' Table输出至Sheet1
Call WriteTable(cocdDetail, Sheet1)
End Sub