关于BAPI的参数有很多描述,但是它们是无法理解的。 我将解决方案发布在这里,因为我自己在实现EXCEL VBA的参数化BAPI调用时遇到了很多困难。
我的任务是查询SAP。应该可以(在Excel中通过表单)选择
-日期范围
-不同的状态(例如10、20、60)
-不同的部门代码(例如10、20、60)
-是否显示Z800项目
要访问BAPI,您必须达到以下条件:
If Not (connection Is Nothing) Then
debug.print "connection is successful"
Set functions = sapFunctions(connection)
Set obSapBapi = functions.Add(BapiName)
如果您看到BAPI对象在调试模式下包含BAPI名称,则此分配成功完成: Successful BAPI assignment 如果分配不成功,则BAPI对象包含“ Nothing”。
BAPI可以具有2种不同的参数类型(每个参数都引用SAP视图中的一个显式字段): 1.仅传递1个值:这是.exporting(例如,姓=“ Smith”) 2.传递了多个参数:这是通过表格进行的(例如,姓氏=“ Smith”或“ Myer”或“ Pitt”,订购日期> 4/1/2019和<4/15/2019) Input / Output of a BAPI
输入和输出表具有相同的类型。您的SAP部门可以命名您的数据表。 要获取BAPI的所有表(及其字段),您可以运行以下代码(指输入表和输出表):
If obSapBapi.Call <> False Then
'Function Call is Successfull
Dim oTables As Object
Set oTables = obSapBapi.Tables 'Tables collection
Call GetColumnDetails(oTables)
Set oTables = Nothing
Debug.Print "Function Call is Successfull"
End If
子代码:
Private Sub GetColumnDetails(ByVal obTables As Object)
on error resume next
Dim iLoop As Integer, iColIndx As Integer, iColValuePos As Integer
Dim iTblCnt As Integer, iColCnt As Integer
dim iRowCnt As Integer, iRowIndx As Integer
Dim oTable As Object, oColumn As Object, iValuePosn As Integer
iTblCnt = obTables.Count
iValuePosn = 1
For iLoop = 1 To iTblCnt
Set oTable = obTables.Item(iLoop)
iColCnt = oTable.ColumnCount
iRowCnt = oTable.RowCount
iColValuePos = 1
Sheet3.Cells(iValuePosn, 1) = oTable.Name
iValuePosn = iValuePosn + 1
For Each oColumn In oTable.Columns
Sheet3.Cells(iValuePosn, iColValuePos) = oColumn.Name
iColValuePos = iColValuePos + 1
Next oColumn
Set oTable = Nothing
Next
End Sub
导入/输入表 导入表通常看起来像: SAP import/input table
将单行组装为与OR连接的SQL-WHERE语句。输入表的说明:
Field Zeile(zh-CN)
您必须提供行号(i ++,从1开始)!!!
栏位签名
(仅)可能的值:
I:包含范围在内
E:专属定义范围
字段OPTION的可能值(=运算符):
-EQ等于(=低)
-NE不等于(<>低)
-BT在低和高之间,包括两者(低<= x <=高)
-NB在低和高之外(x <低和x>高)
-CP包含图案
-NP不包含图案
-LT低于(
-LE下限等于(<=下限)
-GT大于(>低)
-GE大于等于(> =低)
字段LOW的可能值
取决于引用字段的数据类型。范例:
字段“高”的可能值
数据类型
SAP BAPI Data Type / Description / Passed from VBA as
C (<len>) / Character / string
D(8) / Date / Format$(mydate,”yyyyMMdd”)
F(<len>) / float / Double
I(<len>) / Integer / Integer
N(<len>) / Numeric / Integer / long
B / Boolean / String (length 1)
示例: 我在上面描述了我的任务。应该可以选择
解决方案
单击工作表中的按钮后,将显示一个表单。输入上面所有可能的值,然后将其写入工作表“ Connection”,B9:B13
B9: 20190401
B10: 20190701
B11: 10;20;40
B12: X
B13: 05;08;11
和代码:
Function ReadCatsData()
On Error GoTo ReadCatsDataError
Dim MyWB As Workbook
Dim MyWS As Worksheet
Dim connection As Object
Dim SAP_System As String
Dim WinUser As String
Dim functions As Object
Dim ErrText As String
Dim ErrTitel As String
Dim BapiName As String
Dim DatumVon As String
Dim DatumBis As String
Dim Status As String
Dim Z8 As String
Dim ILC As String
Dim Result() As String
Dim a As Integer
Dim i As Integer
Dim obSapBapi As Object
'Basiswerte setzen:
ErrTitel = "Monitoring times"
WinUser = UCase(Environ$("Username"))
SAP_System = ActiveWorkbook.Sheets("Connection").Cells(2, 1)
BapiName = "Z_BAPI_CATS_MON_GET"
Set MyWB = ActiveWorkbook
Set MyWS = MyWB.Worksheets("SapDaten")
Debug.Print SAP_System, WinUser, BapiName
Set connection = sapConnectionLogon(SAP_System, WinUser) ' "SGI"
If Not (connection Is Nothing) Then
Set functions = sapFunctions(connection)
Set obSapBapi = functions.Add(BapiName)
If Not (obSapBapi Is Nothing) Then
DatumVon = Sheets("Connection").Cells(9, 2).Value
'DatumVon = "20190401"
DatumBis = Sheets("Connection").Cells(10, 2).Value
'DatumBis = "20190418"
Status = Sheets("Connection").Cells(11, 2).Value
'Status = "10;20;30"
Z8 = Sheets("Connection").Cells(12, 2).Value
ILC = Sheets("Connection").Cells(13, 2).Value
'ILC = "05;08"
Debug.Print DatumVon, DatumBis, Status, Z8, ILC
'Declare the Table Parameters => Uebergabewerte
' Date table (1)
Dim vbIT_WORKD_RANGE As Object
Set vbIT_WORKD_RANGE = obSapBapi.Tables("IT_WORKD_RANGE")
vbIT_WORKD_RANGE.Rows.Add
vbIT_WORKD_RANGE(1, "SIGN") = "I"
vbIT_WORKD_RANGE(1, "OPTION") = "BT"
vbIT_WORKD_RANGE(1, "LOW") = DatumVon
vbIT_WORKD_RANGE(1, "HIGH") = DatumBis
' Status (2)
If Status <> "" Then
Dim vbIT_STATUS_RANGE As Object
Set vbIT_STATUS_RANGE = obSapBapi.Tables("IT_STATUS_RANGE")
Result = Split(Status, ";")
For i = LBound(Result()) To UBound(Result())
vbIT_STATUS_RANGE.Rows.Add
vbIT_STATUS_RANGE(vbIT_STATUS_RANGE.Rows.Count, _
"SIGN") = "I"
vbIT_STATUS_RANGE(vbIT_STATUS_RANGE.Rows.Count, _
"OPTION") = "EQ"
vbIT_STATUS_RANGE(vbIT_STATUS_RANGE.Rows.Count, _
"LOW") = Result(i)
Debug.Print i, Result(i)
Next i
End If
Erase Result
' Industry_line (3)
If ILC <> "" Then
Dim vbIT_ZZIDL_RANGE As Object
Set vbIT_ZZIDL_RANGE = obSapBapi.Tables("IT_ZZIDL_RANGE")
Result = Split(ILC, ";")
For i = LBound(Result()) To UBound(Result())
vbIT_ZZIDL_RANGE.Rows.Add
vbIT_ZZIDL_RANGE(vbIT_ZZIDL_RANGE.Rows.Count, _
"SIGN") = "I"
vbIT_ZZIDL_RANGE(vbIT_ZZIDL_RANGE.Rows.Count, _
"OPTION") = "EQ"
vbIT_ZZIDL_RANGE(vbIT_ZZIDL_RANGE.Rows.Count, _
"LOW") = Val(Result(i))
Debug.Print i, Result(i)
Next i
End If
'Declare the Export Parameter
' show Z800 projects (4)
obSapBapi.exports("IF_AWART") = Z8
'Call the function. get error in Bapi via obSapBapi.Exception
If obSapBapi.Call = False Then
ErrText = "Established connection with SAP system " & _
SAP_System & vbCrLf
ErrText = ErrText & "BAPI " & BapiName & " exists. " & vbCrLf
ErrText = ErrText & "BAPI could not be called. " & vbCrLf
ErrText = ErrText & "SAP delivers the following message: " & _
obSapBapi.Exception & vbCrLf
ErrText = ErrText & "Data cannot be fetched from SAP." & vbCrLf
a = MsgBox(ErrText, vbOKOnly + vbCritical, ErrTitel)
Else
'Function Call is Successfull
Dim obSAPTblData As Object
Set obSAPTblData = obSapBapi.Tables("ET_Data")
Dim SheetRowPos As Integer
Dim iRowCnt As Integer
Dim iRowIndx As Integer
Dim iColCnt As Integer
Dim iColIndx As Integer
iColCnt = obSAPTblData.ColumnCount
iRowCnt = obSAPTblData.RowCount
SheetRowPos = 1 'init
For iRowIndx = 1 To iRowCnt
SheetRowPos = SheetRowPos + 1 'start at row 2
For iColIndx = 1 To iColCnt
MyWS.Cells(SheetRowPos, _
iColIndx) = obSAPTblData.Value(iRowIndx, iColIndx)
Next
Next
'Debug.Print "Col.: " & iColCnt & ", Rows: " & iRowCnt
End If
Set vbIT_WORKD_RANGE = Nothing
Set vbIT_STATUS_RANGE = Nothing
Set vbIT_ZZIDL_RANGE = Nothing
functions.Remove (BapiName)
Set obSapBapi = Nothing
Else
ErrText = "Established connection with SAP system " & _
SAP_System & vbCrLf
ErrText = ErrText & "BAPI " & BapiName & _
" was not found (could not instantiate object)." & vbCrLf
ErrText = ErrText & "Data cannot be fetched from SAP." & vbCrLf
a = MsgBox(ErrText, vbOKOnly + vbCritical, ErrTitel)
End If
connection.LogOff
Set connection = Nothing
Set functions = Nothing
Else
ErrText = "Could not establish connection with SAP system." & vbCrLf
ErrText = ErrText & "User: " & WinUser
ErrText = ErrText & ", SAP System: " & SAP_System & vbCrLf
ErrText = ErrText & "Data cannot be fetched from SAP." & vbCrLf
a = MsgBox(ErrText, vbOKOnly + vbCritical, ErrTitel)
End If
ReadCatsDataExit:
Set MyWS = Nothing
Set MyWB = Nothing
Exit Function
ReadCatsDataError:
Resume ReadCatsDataExit
End Function
答案 0 :(得分:0)
您提到的外部文档中未解释的是,在7.70之前的SAP GUI版本中(当前为beta,尚未公开),SAP GUI脚本OCX库为32位。许多人使用MS Office 64位,因此您必须按照there所述更改一些SAP GUI条目的Windows注册表。
如果调用涉及称为 BAPI 的特殊RFC功能模块,要创建,更新或删除数据,则需要分别根据成功或失败来调用BAPI_TRANSACTION_COMMIT
或RESULT
参数E
的消息中指示的失败(如果存在类型为A
,X
或objRfcFunc.Call = False
的消息)。请注意,internetMessageId
表示系统错误。
答案 1 :(得分:0)
您能否也为 BAPI“导入结构化参数”发布类似的代码。您发布的以下代码适用于 BAPI 表
Set vbIT_WORKD_RANGE = obSapBapi.Tables("IT_WORKD_RANGE")
vbIT_WORKD_RANGE.Rows.Add
vbIT_WORKD_RANGE(1, "SIGN") = "I"
vbIT_WORKD_RANGE(1, "OPTION") = "BT"
vbIT_WORKD_RANGE(1, "LOW") = DatumVon
vbIT_WORKD_RANGE(1, "HIGH") = DatumBis
我在将值传递给 BAPI GRAC_API_RISK_ANALYSIS 中导入参数结构的相同 4 个字段 (SIGN/OPTION/HIGH/LOW) 时遇到问题,参数名称 - IT_SYS_RANGE
答案 2 :(得分:0)
以下是问题作者给出的解决方案(她最初发布在她的问题中)。
解决方案
单击工作表中的按钮后,将显示一个表单。输入上述所有可能的值,然后写入工作表“连接”,B9:B13
B9: 20190401
B10: 20190701
B11: 10;20;40
B12: X
B13: 05;08;11
和代码:
Function ReadCatsData()
On Error GoTo ReadCatsDataError
Dim MyWB As Workbook
Dim MyWS As Worksheet
Dim connection As Object
Dim SAP_System As String
Dim WinUser As String
Dim functions As Object
Dim ErrText As String
Dim ErrTitel As String
Dim BapiName As String
Dim DatumVon As String
Dim DatumBis As String
Dim Status As String
Dim Z8 As String
Dim ILC As String
Dim Result() As String
Dim a As Integer
Dim i As Integer
Dim obSapBapi As Object
'Basiswerte setzen:
ErrTitel = "Monitoring times"
WinUser = UCase(Environ$("Username"))
SAP_System = ActiveWorkbook.Sheets("Connection").Cells(2, 1)
BapiName = "Z_BAPI_CATS_MON_GET"
Set MyWB = ActiveWorkbook
Set MyWS = MyWB.Worksheets("SapDaten")
Debug.Print SAP_System, WinUser, BapiName
Set connection = sapConnectionLogon(SAP_System, WinUser) ' "SGI"
If Not (connection Is Nothing) Then
Set functions = sapFunctions(connection)
Set obSapBapi = functions.Add(BapiName)
If Not (obSapBapi Is Nothing) Then
DatumVon = Sheets("Connection").Cells(9, 2).Value
'DatumVon = "20190401"
DatumBis = Sheets("Connection").Cells(10, 2).Value
'DatumBis = "20190418"
Status = Sheets("Connection").Cells(11, 2).Value
'Status = "10;20;30"
Z8 = Sheets("Connection").Cells(12, 2).Value
ILC = Sheets("Connection").Cells(13, 2).Value
'ILC = "05;08"
Debug.Print DatumVon, DatumBis, Status, Z8, ILC
'Declare the Table Parameters => Uebergabewerte
' Date table (1)
Dim vbIT_WORKD_RANGE As Object
Set vbIT_WORKD_RANGE = obSapBapi.Tables("IT_WORKD_RANGE")
vbIT_WORKD_RANGE.Rows.Add
vbIT_WORKD_RANGE(1, "SIGN") = "I"
vbIT_WORKD_RANGE(1, "OPTION") = "BT"
vbIT_WORKD_RANGE(1, "LOW") = DatumVon
vbIT_WORKD_RANGE(1, "HIGH") = DatumBis
' Status (2)
If Status <> "" Then
Dim vbIT_STATUS_RANGE As Object
Set vbIT_STATUS_RANGE = obSapBapi.Tables("IT_STATUS_RANGE")
Result = Split(Status, ";")
For i = LBound(Result()) To UBound(Result())
vbIT_STATUS_RANGE.Rows.Add
vbIT_STATUS_RANGE(vbIT_STATUS_RANGE.Rows.Count, _
"SIGN") = "I"
vbIT_STATUS_RANGE(vbIT_STATUS_RANGE.Rows.Count, _
"OPTION") = "EQ"
vbIT_STATUS_RANGE(vbIT_STATUS_RANGE.Rows.Count, _
"LOW") = Result(i)
Debug.Print i, Result(i)
Next i
End If
Erase Result
' Industry_line (3)
If ILC <> "" Then
Dim vbIT_ZZIDL_RANGE As Object
Set vbIT_ZZIDL_RANGE = obSapBapi.Tables("IT_ZZIDL_RANGE")
Result = Split(ILC, ";")
For i = LBound(Result()) To UBound(Result())
vbIT_ZZIDL_RANGE.Rows.Add
vbIT_ZZIDL_RANGE(vbIT_ZZIDL_RANGE.Rows.Count, _
"SIGN") = "I"
vbIT_ZZIDL_RANGE(vbIT_ZZIDL_RANGE.Rows.Count, _
"OPTION") = "EQ"
vbIT_ZZIDL_RANGE(vbIT_ZZIDL_RANGE.Rows.Count, _
"LOW") = Val(Result(i))
Debug.Print i, Result(i)
Next i
End If
'Declare the Export Parameter
' show Z800 projects (4)
obSapBapi.exports("IF_AWART") = Z8
'Call the function. get error in Bapi via obSapBapi.Exception
If obSapBapi.Call = False Then
ErrText = "Established connection with SAP system " & _
SAP_System & vbCrLf
ErrText = ErrText & "BAPI " & BapiName & " exists. " & vbCrLf
ErrText = ErrText & "BAPI could not be called. " & vbCrLf
ErrText = ErrText & "SAP delivers the following message: " & _
obSapBapi.Exception & vbCrLf
ErrText = ErrText & "Data cannot be fetched from SAP." & vbCrLf
a = MsgBox(ErrText, vbOKOnly + vbCritical, ErrTitel)
Else
'Function Call is Successfull
Dim obSAPTblData As Object
Set obSAPTblData = obSapBapi.Tables("ET_Data")
Dim SheetRowPos As Integer
Dim iRowCnt As Integer
Dim iRowIndx As Integer
Dim iColCnt As Integer
Dim iColIndx As Integer
iColCnt = obSAPTblData.ColumnCount
iRowCnt = obSAPTblData.RowCount
SheetRowPos = 1 'init
For iRowIndx = 1 To iRowCnt
SheetRowPos = SheetRowPos + 1 'start at row 2
For iColIndx = 1 To iColCnt
MyWS.Cells(SheetRowPos, _
iColIndx) = obSAPTblData.Value(iRowIndx, iColIndx)
Next
Next
'Debug.Print "Col.: " & iColCnt & ", Rows: " & iRowCnt
End If
Set vbIT_WORKD_RANGE = Nothing
Set vbIT_STATUS_RANGE = Nothing
Set vbIT_ZZIDL_RANGE = Nothing
functions.Remove (BapiName)
Set obSapBapi = Nothing
Else
ErrText = "Established connection with SAP system " & _
SAP_System & vbCrLf
ErrText = ErrText & "BAPI " & BapiName & _
" was not found (could not instantiate object)." & vbCrLf
ErrText = ErrText & "Data cannot be fetched from SAP." & vbCrLf
a = MsgBox(ErrText, vbOKOnly + vbCritical, ErrTitel)
End If
connection.LogOff
Set connection = Nothing
Set functions = Nothing
Else
ErrText = "Could not establish connection with SAP system." & vbCrLf
ErrText = ErrText & "User: " & WinUser
ErrText = ErrText & ", SAP System: " & SAP_System & vbCrLf
ErrText = ErrText & "Data cannot be fetched from SAP." & vbCrLf
a = MsgBox(ErrText, vbOKOnly + vbCritical, ErrTitel)
End If
ReadCatsDataExit:
Set MyWS = Nothing
Set MyWB = Nothing
Exit Function
ReadCatsDataError:
Resume ReadCatsDataExit
End Function