SAP接口编程之 RFC系列(05) : Table作为输出参数

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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容