VBA调用 SAP RFC

最近接手到一个任务,用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)