美文网首页SAP ABAP
VBA调用 SAP RFC

VBA调用 SAP RFC

作者: Stern_ | 来源:发表于2018-09-20 11:15 被阅读20次

    最近接手到一个任务,用excel VBA 编写一个查询报表给业务部门使用,最后使用的方案是使用VBA调用 SAP RFC 来输出报表。对于VBA 和SAP ABAP我都属于新手,接到任务也是头皮发麻,最终在查阅大量资料后在昨天全部完成。

    环境准备

    在环境准备部分就有一个大坑,vba创建sap.functions、sap.logoncontrol对象时使用的是sap gui目录下的wdtfuncs.ocx、wdtlog文件,而这些文件是32位的,如果使用64位的excel则访问不到此文件,会报错429“不能创建对象”,最后的解决方案,换32位的excel…(巨坑),在网上看到一个博主也提到了这个问题,留言询问有没有别的解决方法后,他给的回复是使用和excel位数一致的.ocx文件是不是就可以了?但我也没找到有64位的.ocx文件,不知道广大网友能不能解决这个问题。

    在菜单栏 【工具】——【引用】添加上述控件后就完成环境准备部分。

    代码编写

    新建模块,编写代码:

    Option Explicit

    Dim sapLongonControl As SAPLogonCtrl.SAPLogonControl

    Dim sapConnection As SAPLogonCtrl.Connection

    Public Sub Logon()

        Set sapLongonControl = CreateObject("SAP.LogonControl.1")

        Set sapConnection = sapLongonControl.NewConnection

        With sapConnection

        '    .System = "ED1"                    '系统标识

        '    .ApplicationServer = "100.100.190.210"    '应用服务器

            .SAPRouter = "/H/61.155.85.163/H/" '外网连接的SAP路由

            .SystemNumber = "00"            '实例编号

            .Client = "600"                       '客户端

            .User = "****"                '用户名

            .Password = "****"    '密码

            .CodePage = "8400"       '解决中文乱码问题

        End With

        Call sapConnection.Logon(0, True) ' hWnd, Silent Logon   '此处如果括号里是False则会跳出登陆窗口,True则不跳登陆窗口直接登陆

        If sapConnection.IsConnected = tloRfcConnected Then

    '        MsgBox "OK"

        Else

            MsgBox "Error code:" & sapConnection.IsConnected

        End If

    End Sub

    Public Sub Logoff()

        If sapConnection.IsConnected = tloRfcConnected Then

            sapConnection.Logoff

        End If

    End Sub

    RFC部分

    在RFC部分使用的Tbale参数作为输出参数传到VBA,查询条件作为输入参数。RFC的创建及代码部分不做详细介绍,思路是将要查询的数据创建结构作为输出表,在代码编写部分主要就是SQL的编写及数据的整合。

    注:RFC 的输出参数在VBA里是输入参数,输入参数在VBA里是输出参数。在使用Table接受数据时,需要使用到tableFactory控件。控件为wdtaocx.ocx,Windows 7下默认的路为: C:\Program Files (x86)\SAP\FrontEnd\SAPgui。

    VBA代码部分

    Private Sub GetData()

        Dim functions As SAPFunctionsOCX.SAPFunctions

        Dim fm As SAPFunctionsOCX.Function

        Dim cocdDetail As SAPTableFactoryCtrl.Table

        Set functions = New SAPFunctions

        Set functions.Connection = sapConnection

        ' FM加入Functions集合

        Set fm = functions.Add("RFC函数名")

       '填充参数,RFC的输入参数对VBA来说是输出参数

        fm.Exports("SPART_IN").Value = ***

        '调用

        fm.Call

        '得到Table参数

        Set cocdDetail = fm.Tables("ITAB_OUT")

        Call WriteTable(cocdDetail, Sheet2)       '输出结果,此处cocdDetail是一个二维表,所以时候遍历的方式取得表数据。为了更具一般性,编写一个通用的routine,将表输出到excel。

    End Sub

    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 = xlCalculationAutomaticEnd Sub

    相关文章

      网友评论

        本文标题:VBA调用 SAP RFC

        本文链接:https://www.haomeiwen.com/subject/wtjgnftx.html