SAP接口编程案例 - VBA批量更新销售订单定价类型

碰到一个需求,需要对销售订单的定价类型进行批量更新,对这种临时批量处理,考虑到数据源一般放在 Excel 中,使用 VBA 来调用 BAPI 实现不失为一种快捷的方式。

了解 BAPI 如何使用

更改销售订单的 BAPI 是 BAPI_SALESORDER_CHANGE,这个 BAPI 因为参数比较多,我们首先要找到针对更改定价类型这种场景,相应的参数如何设置。基本方法就是 SE37 进行测试,以及查看函数的文档。
经过查找和测试,了解到需要更新定价类型需要填写如下的参数:

ORDER_HEADER_INX 的 UPDATEFLAG 参数要填写 U:


LOGIC_SWITCH 参数的 PRICING 是核心,这里填写要更新的定价类型。可以在 VA02 界面行项目的条件选项卡中查看。

当然要告诉 BAPI, 需要修改的行项目,需要填写 ORDER_ITEM_IN 和 ORDER_ITEM_INX 两个参数:

查看测试结果:


有了这些准备,可以编写程序了。

编写函数调用 BAPI_SALESORDER_CHANGE

因为本篇是讲解 RFC 的案例,所以并不详细说明 VBA 调用 BAPI 的要点和语法。之前我写过系列文章,小伙伴们可以自行查找。我将函数的调用封装在函数中,返回值为 BAPI 的 RETURN 参数:

Public Function ChangeSalesOrder(OrderNo As String, ItemNo As Integer, NewPricing As String) As String
    Dim functions As New SAPFunctionsOCX.SAPFunctions
    Dim func As SAPFunctionsOCX.Function
    Dim commitFunc As SAPFunctionsOCX.Function
    Dim orderItemIn As SAPTableFactoryCtrl.Table
    Dim orderItemInX As SAPTableFactoryCtrl.Table
    Dim returnTable As SAPTableFactoryCtrl.Table
    
    Dim retVal As String '函数返回只
    retVal = ""
    
    ' sapConnection is global
    If sapConnection Is Nothing Then
        MsgBox "请登录SAP系统!", vbOKOnly + vbInformation
        Exit Function
    End If
    
    If sapConnection.IsConnected <> tloRfcConnected Then
        MsgBox "请登录SAP系统!", vbOKOnly + vbInformation
        Exit Function
    End If
    
    Set functions.Connection = sapConnection
    Set func = functions.Add("BAPI_SALESORDER_CHANGE")
    
    ' BAPI参数-Importing
    func.Exports("SALESDOCUMENT").Value = OrderNo              ' 销售订单号
    func.Exports("ORDER_HEADER_INX").Value("UPDATEFLAG") = "U" ' U表示修改
    
    ' BAPI参数-Pricing(在LOGIC_SWITCH参数中)
    func.Exports("LOGIC_SWITCH").Value("PRICING") = NewPricing
    func.Exports("LOGIC_SWITCH").Value("COND_HANDL") = "X"
     
    'BAPI参数-ORDER_ITEM_IN / ORDER_ITEM_IN
    Set orderItemIn = func.Tables("ORDER_ITEM_IN")
    Set orderItemInX = func.Tables("ORDER_ITEM_INX")
     
    orderItemIn.AppendRow
    orderItemIn.Value(1, "ITM_NUMBER") = ItemNo
    
    orderItemInX.AppendRow
    orderItemInX.Value(1, "ITM_NUMBER") = ItemNo
    orderItemInX.Value(1, "UPDATEFLAG") = "U"
    
    'BAPI参数-返回值
    Set returnTable = func.Tables("RETURN")
    '执行函数
    If func.Call = False Then
        retVal = DumpReturn(returnTable)
        Exit Function
    Else
        retVal = DumpReturn(returnTable)
        Dim returnOfCommit As SAPTableFactoryCtrl.Table
        Set commitFunc = functions.Add("BAPI_TRANSACTION_COMMIT")
        commitFunc.Exports("WAIT").Value = "X"
        Set returnOfCommit = commitFunc.Tables("RETURN")
        
        If commitFunc.Call = False Then
            MsgBox func.Exception
            Exit Function
        End If
    End If
    
    ChangeSalesOrder = retVal
End Function

注意该 BAPI 需要在调用之后,根据是否成功,再调用另外一个 BAPI : BAPI_TRANSACTION_COMMIT 来实现真正的提交。

处理函数的返回值

函数的返回值 return 是一个表类型的参数,我们可以有两种方式来处理,第一种方式是将每一行的消息都返回:

Private Function DumpReturn(ret As SAPTableFactoryCtrl.Table) As String
    Dim i As Integer
    Dim retVal As String
    
    retVal = ""
    
    Dim returnOfLine As String
    If Not ret Is Nothing Then
        If ret.rowcount > 0 Then
            For i = 1 To ret.rowcount
                returnOfLine = "消息" & Str(i) & ": " & ret.Value(i, 1) & "," & ret.Value(i, 4) & ";"
                retVal = retVal & returnOfLine
             Next i
        End If
    End If
    
    DumpReturn = retVal
End Function

简便起见,我们也可以只获取 return 表参数的最后一行:

Private Function DumpReturn(ret As SAPTableFactoryCtrl.Table) As String
    Dim retVal As String    
    retVal = ""

    If Not ret Is Nothing Then
        If ret.rowcount > 0 Then
            retVal = "消息类型 " & ret.Value(ret.rowcount, 1) & "," & ret.Value(ret.rowcount, 4)
        End If
    End If
    
    DumpReturn = retVal
End Function

实现从 Excel 中读取数据,然后进行批量更新

Public Sub RunScript()
    Dim i As Long
    Dim returnVal As String
    
    For i = 4 To Sheet3.UsedRange.rows.Count
        If Sheet3.Range("A" & i).Value = "EOF" Then Exit Sub
        
        Dim leftCell As Range
        Set leftCell = Sheet3.Range("A" & i)
        returnVal = ChangeSalesOrder(leftCell.Value, leftCell.Offset(0, 1).Value, leftCell.Offset(0, 2).Value)
        leftCell.Offset(0, 3).Value = returnVal
    Next

在界面中进行测试:

源码

sap_interface_prog_rfc_vba: RFC programing using VBA (gitee.com)

参考

更新销售订单执行新定价——BAPI_SALESORDER_CHANGE

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

推荐阅读更多精彩内容