SAP接口编程之 RFC系列(07): 实现通用数据库表读取功能

上一篇讲的是调用RFC_READ_TABLE查看SAP table的数据。为了方便查看数据,我们可以写一个通用的表查看程序。使用起来比SAP SE11或SE16N方便点。

本篇没有关于RFC调用新的知识点。主要说明函数调用后,VBA如何处理这些数据并在Excel中显示。不熟悉VBA的读者可以参考。由于VBA本身数据结构的限制,处理过程还是蛮啰嗦的。后续用C#调用的代码会方便很多。

不多说,上代码:

Option Explicit

Public Sub test()
    Call Logon
    Call ReadTable("T030", Sheet1)
    Call Logoff
End Sub

'--------------------------------------'
'读取tableName的数据,写入inSheet这个工作表
'--------------------------------------'
Private Sub ReadTable(tableName As String, inSheet As Worksheet)
    Dim functions As SAPFunctions
    Set functions = New SAPFunctions
    Dim fm As SAPFunctionsOCX.Function

    ' RFC_READ_TABLE的三个table型参数'
    Dim optionsTable As SAPTableFactoryCtrl.Table
    Dim dataTable As SAPTableFactoryCtrl.Table
    Dim fieldsTable As SAPTableFactoryCtrl.Table

    Dim delimeter As String
    delimeter = "~" '长度只能为1'

    If sapConnection Is Nothing Then Exit Sub
    Set functions.Connection = sapConnection

    If sapConnection.IsConnected = tloRfcConnected Then
        'FM加到functions collection'
        Set fm = functions.Add("RFC_READ_TABLE")

        '------------------------'
        '填充Import parameters
        '------------------------'
        'QUERY_TABLE是要查找的表名
        fm.Exports("QUERY_TABLE").Value = tableName 'Table name

        'DELIMITER是输出时字段的分割符'
        fm.Exports("DELIMITER").Value = delimeter

        Set optionsTable = fm.Tables("OPTIONS")  'OPTIONS是筛选条件'
        Set fieldsTable = fm.Tables("FIELDS")    'FIELDS表示要输出的列'
        Set dataTable = fm.Tables("DATA")        'DATA为输出的数据'

        fm.Call

        '如果有Exception,说明有错误产生'
        If fm.Exception <> "" Then
            Debug.Print fm.Exception
            Exit Sub
        End If

        ' 存储fields信息的数组'
        Dim fields() As Variant
        fields = ItabToArray(fieldsTable)

        ' 存储data信息的数组'
        Dim data() As Variant
        data = ItabToArray(dataTable)

        ' 将data分割'
        Dim splittedData() As Variant
        splittedData = splitData(data, delimeter)

        ' 为了Excel显示需要,将数据加上单引号, Excel显示为字符型'
        Dim r As Long
        Dim c As Long
        For r = 1 To UBound(splittedData, 1)
            For c = 1 To UBound(splittedData, 2)
                splittedData(r, c) = "'" + splittedData(r, c)
            Next
        Next

        ' 将field name, field text和data输出到工作表显示 '
        Call WriteData(fields, splittedData, Sheet1)
    End If
End Sub


' 将itab转换成数组'
Private Function ItabToArray(itab As SAPTableFactoryCtrl.Table) As Variant
    Dim arr() As Variant
    arr = itab.data

    ItabToArray = arr
End Function


Private Function splitData(data() As Variant, delimeter As String) As Variant
    Dim dataSplitted() As Variant '返回值'

    Dim rowcount As Long
    rowcount = UBound(data, 1)

    ' 列数需要计算'
    Dim testcol As Variant
    testcol = Split(data(1, 1), delimeter) '根据第一个数据来确定列数'

    Dim colcount As Long
    colcount = UBound(testcol) + 1
    ReDim dataSplitted(1 To rowcount, 1 To colcount)

    Dim line As Variant
    Dim r As Long
    Dim c As Long
    For r = 1 To rowcount
        line = Split(data(r, 1), delimeter) ' line 从0开始'
        For c = 1 To colcount
            dataSplitted(r, c) = line(c - 1)
        Next
    Next

    splitData = dataSplitted
End Function


Private Sub WriteData(fields() As Variant, data() As Variant, inSheet As Worksheet)
    ' Clear first'
    inSheet.Cells.ClearContents

    Dim fieldname() As Variant
    Dim fieldtext() As Variant

    Dim rowcount As Integer
    rowcount = UBound(fields, 1)
    ReDim fieldname(1 To rowcount)
    ReDim fieldtext(1 To rowcount)

    Dim r As Integer
    For r = 1 To UBound(fields, 1)
        fieldname(r) = fields(r, 1) ' 第一列为fieldname'
        fieldtext(r) = fields(r, 5) ' 第五列为fieldtext'
    Next

    ' fieldname和fieldtext写入工作表'
    ' 第一行fieldname'
    Dim fieldNameRange As Range
    Set fieldNameRange = inSheet.Range("A1")
    fieldNameRange.Resize(1, UBound(fieldname)).Value = fieldname

    ' 第二行fieldtext'
    Dim fieldTextRange As Range
    Set fieldTextRange = inSheet.Range("A2")
    fieldTextRange.Resize(1, UBound(fieldname)).Value = fieldtext

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

推荐阅读更多精彩内容