SAP大量使用Table作为参数,表达二维的数据。Table可以作为输入参数(Importing parameter),也可以作为输出参数(Exporting parameter)。我们首先来看看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
' FM加入Functions集合'
Set fm = functions.Add("BAPI_COMPANYCODE_GETLIST")
fm.Call
'通过Table参数获得company code details'
Set cocdDetail = fm.Tables("COMPANYCODE_LIST")
' Table输出至Sheet1'
Call WriteTable(cocdDetail, Sheet1)
End Sub