苏州网络自学网站建设,工程分包网,正规百度推广,优化方案生物总体来说#xff0c;SAP Scripting 与 BDC 类似#xff0c;因为是屏幕录制#xff0c;就可能碰到不同的情况#xff0c;比如每个录入的数据不同#xff0c;可能出现一个对话框#xff0c;或者出现一个状态栏消息。这种任何有变化的情况#xff0c;在 Scripting 中没有考…总体来说SAP Scripting 与 BDC 类似因为是屏幕录制就可能碰到不同的情况比如每个录入的数据不同可能出现一个对话框或者出现一个状态栏消息。这种任何有变化的情况在 Scripting 中没有考虑到就会导致操作失败。本文以导入 MR21 物料价格为例演示如何处理组件/控件不存在的情况。
基于连续性如何使用 SAP SAP Scripting 的要点请参考本人之前的博文
SAP Scripting Tracker基本使用技巧-CSDN博客 SAP Scripting Tracker基本使用技巧续_sap tracker-CSDN博客 SAP Scripting Tracker基本使用技巧 - VBA 示例-CSDN博客
首先使用 SAP Scripting Tracker 基于 Basic 录制 MR21 修改物料价格得到下面的代码
session.findById(wnd[0]).resizeWorkingPane(116, 39, vbFalse)
session.findById(wnd[0]/tbar[0]/okcd).text MR21
session.findById(wnd[0]).sendVKey(0)session.findById(wnd[0]/usr/ctxtMR21HEAD-BUDAT).text 2024.12.31
session.findById(wnd[0]/usr/ctxtMR21HEAD-BUKRS).text 3600
session.findById(wnd[0]/usr/ctxtMR21HEAD-WERKS).text 3601
session.findById(wnd[0]/usr/txtMR21HEAD-XBLNR).setFocus
session.findById(wnd[0]/usr/txtMR21HEAD-XBLNR).caretPosition 0
session.findById(wnd[0]).sendVKey(0)session.findById(wnd[0]/usr/tabsMR21_TABSTRIP/tabpTAB1/ssubMR21_SUB:SAPRCKM_MR21:0250/tblSAPRCKM_MR21MR21_TABCONTROL/ctxtCKI_MR21_0250-MATNR[0,0]).text 20000239
session.findById(wnd[0]/usr/tabsMR21_TABSTRIP/tabpTAB1/ssubMR21_SUB:SAPRCKM_MR21:0250/tblSAPRCKM_MR21MR21_TABCONTROL/ctxtCKI_MR21_0250-MATNR[0,0]).caretPosition 8
session.findById(wnd[0]).sendVKey(0)session.findById(wnd[0]/usr/tabsMR21_TABSTRIP/tabpTAB1/ssubMR21_SUB:SAPRCKM_MR21:0250/tblSAPRCKM_MR21MR21_TABCONTROL/txtCKI_MR21_0250-NEWVALPR[4,0]).text 100
session.findById(wnd[0]/usr/tabsMR21_TABSTRIP/tabpTAB1/ssubMR21_SUB:SAPRCKM_MR21:0250/tblSAPRCKM_MR21MR21_TABCONTROL/txtCKI_MR21_0250-NEWVALPR[4,0]).setFocus
session.findById(wnd[0]/usr/tabsMR21_TABSTRIP/tabpTAB1/ssubMR21_SUB:SAPRCKM_MR21:0250/tblSAPRCKM_MR21MR21_TABCONTROL/txtCKI_MR21_0250-NEWVALPR[4,0]).caretPosition 3
session.findById(wnd[0]).sendVKey(0)session.findById(wnd[0]/usr/tabsMR21_TABSTRIP/tabpTAB1/ssubMR21_SUB:SAPRCKM_MR21:0250/tblSAPRCKM_MR21MR21_TABCONTROL/txtCKI_MR21_0250-NEWVALPR[4,0]).setFocus
session.findById(wnd[0]/usr/tabsMR21_TABSTRIP/tabpTAB1/ssubMR21_SUB:SAPRCKM_MR21:0250/tblSAPRCKM_MR21MR21_TABCONTROL/txtCKI_MR21_0250-NEWVALPR[4,0]).caretPosition 4
session.findById(wnd[0]/tbar[0]/btn[11]).press录制过程中为方便后续对代码的理解可以在关键点插入空行或插入空行并加上注释。因为最终需要从 Excel 的单元格导入数据所以接下来对代码进行微调将写死的部分替换为单元格。我一般先定义一个起始的单元格然后其他单元格都替换为基于起始单元格的 offset:
Dim leftCell As Range
Set leftCell Sheet1.Range(A i)session.findById(wnd[0]).resizeWorkingPane(116, 39, vbFalse)
session.findById(wnd[0]/tbar[0]/okcd).text MR21
session.findById(wnd[0]).sendVKey(0)session.findById(wnd[0]/usr/ctxtMR21HEAD-BUDAT).text leftCell.Offset(0, 2).Value 过账日期
session.findById(wnd[0]/usr/ctxtMR21HEAD-BUKRS).text leftCell.Value 公司代码
session.findById(wnd[0]/usr/ctxtMR21HEAD-WERKS).text leftCell.Offset(0, 1).Value 工厂
session.findById(wnd[0]/usr/txtMR21HEAD-XBLNR).setFocus
session.findById(wnd[0]/usr/txtMR21HEAD-XBLNR).caretPosition 0
session.findById(wnd[0]).sendVKey(0)session.findById(wnd[0]/usr/tabsMR21_TABSTRIP/tabpTAB1/ssubMR21_SUB:SAPRCKM_MR21:0250/tblSAPRCKM_MR21MR21_TABCONTROL/ctxtCKI_MR21_0250-MATNR[0,0]).text leftCell.Offset(0, 3).Value 物料编码
session.findById(wnd[0]/usr/tabsMR21_TABSTRIP/tabpTAB1/ssubMR21_SUB:SAPRCKM_MR21:0250/tblSAPRCKM_MR21MR21_TABCONTROL/ctxtCKI_MR21_0250-MATNR[0,0]).caretPosition 8
session.findById(wnd[0]).sendVKey(0)session.findById(wnd[0]/usr/tabsMR21_TABSTRIP/tabpTAB1/ssubMR21_SUB:SAPRCKM_MR21:0250/tblSAPRCKM_MR21MR21_TABCONTROL/txtCKI_MR21_0250-NEWVALPR[4,0]).text leftCell.Offset(0, 4).Value 新价格
session.findById(wnd[0]/usr/tabsMR21_TABSTRIP/tabpTAB1/ssubMR21_SUB:SAPRCKM_MR21:0250/tblSAPRCKM_MR21MR21_TABCONTROL/txtCKI_MR21_0250-NEWVALPR[4,0]).setFocus
session.findById(wnd[0]/usr/tabsMR21_TABSTRIP/tabpTAB1/ssubMR21_SUB:SAPRCKM_MR21:0250/tblSAPRCKM_MR21MR21_TABCONTROL/txtCKI_MR21_0250-NEWVALPR[4,0]).caretPosition 3
session.findById(wnd[0]).sendVKey(0)session.findById(wnd[0]/usr/tabsMR21_TABSTRIP/tabpTAB1/ssubMR21_SUB:SAPRCKM_MR21:0250/tblSAPRCKM_MR21MR21_TABCONTROL/txtCKI_MR21_0250-NEWVALPR[4,0]).setFocus
session.findById(wnd[0]/usr/tabsMR21_TABSTRIP/tabpTAB1/ssubMR21_SUB:SAPRCKM_MR21:0250/tblSAPRCKM_MR21MR21_TABCONTROL/txtCKI_MR21_0250-NEWVALPR[4,0]).caretPosition 4
session.findById(wnd[0]/tbar[0]/btn[11]).press正常情况下这个脚本就可以用了。本来 MR21 是一个表格式界面可以处理多条记录但 Scripting 是通过位置索引来表达某个单元格因为项目物料不是很多所以采取简单的方式每一条记录保存之后再录入下一个物料就解决了这个问题。
但物料本身的数据存在差异录入的时候会碰到不同的情况比如有些物料本身已经有将来或当前的价格有些物料在修改的时候如果新价格等于老价格SAP就会在状态栏有一个提示对于XXX物料价格没有变化。对这种的情况如果不处理VBA 会抛出异常所以需要处理。
我们先来讲怎样通过 Scripting Tracker 查看这个控件。在查看之前需要制造出抛出异常的情景。 然后刷新 Scripting Tracker显示控件的 ID: 有了这个 ID 之后我们可以通过两个方法来处理推荐的是第二个方法。
方法1
Dim msg As String
On Error Resume Next
msg session.FindById(/app/con[0]/ses[0]/wnd[1]/usr/txtMESSTXT1) 价格没有修改对话框
If Err.Number 0 ThenleftCell.Offset(0, 5).Value session.FindById(/app/con[0]/ses[0]/wnd[1]/usr/txtMESSTXT1).Text
End If方法2
第二个参数为 False。
Public Function FindById( _ByVal Id As String, _Optional ByVal Raise As Variant _
) As GuiComponent在对象的子对象中搜索给定的 ID。如果参数是完全限定的 ID函数将首先检查容器对象的 ID 是否是 ID 参数的前缀。如果是这种情况这个前缀将被截断。如果找不到具有给定 ID 的后代除非将可选参数 raise 设置为 False否则函数将引发异常。(Search through the object’s descendants for a given id. If the parameter is a fully qualified id, the function will first check if the container object’s id is a prefix of the id parameter. If that is the case, this prefix is truncated. If no descendant with the given id can be found the function raises an exception unless the optional parameter raise is set to False.) API 可以参考GuiContainer Object | SAP Help Portal If Not session.FindById(/app/con[0]/ses[0]/wnd[1]/usr/txtMESSTXT1, False) Is Nothing Then 价格没有修改对话框leftCell.Offset(0, 5).Value session.FindById(/app/con[0]/ses[0]/wnd[1]/usr/txtMESSTXT1).Text
Else 读取返回值leftCell.Offset(0, 5).Value session.FindById(wnd[0]/sbar).Text
End If最后给出 Excel 界面和完整的代码。 SapSesion.bas
Option ExplicitPublic Function GetSession() As ObjectDim SapGuiAuto As ObjectDim app As SAPFEWSELib.GuiApplicationDim connection As SAPFEWSELib.GuiConnectionDim session As SAPFEWSELib.GuiSessionIf app Is Nothing ThenSet SapGuiAuto GetObject(SAPGUI)Set app SapGuiAuto.GetScriptingEngineEnd IfIf connection Is Nothing ThenSet connection app.Children(0)End IfIf session Is Nothing ThenSet session connection.Children(0)End IfSet GetSession session
End FunctionPublic Sub returnEasyAccess(sess As Object)sess.FindById(wnd[0]/tbar[0]/okcd).Text /nsess.FindById(wnd[0]).SendVKey (0)
End SubPublic Sub test()Dim s As ObjectSet s GetSessionreturnEasyAccess s
End Sub
DataImport.bas
Option ExplicitPublic Sub DataImport()Dim session As ObjectSet session GetSession 确认If Not msgbox(脚本将对当前打开的SAP系统进行更改物料价格更改请不要随意点击执行。是否继续, vbYesNo vbExclamation) vbYes ThenExit SubEnd IfDim pwd As Stringpwd InputBox(请输入密码)If pwd ThenExit SubEnd IfIf pwd stonestone Thenmsgbox 密码不正确Exit SubEnd IfCall returnEasyAccess(session) 执行Dim i As LongFor i 4 To Sheet1.UsedRange.CountIf Sheet1.Range(A i).Value EOF Then Exit Sub 每次先回到Easy Access 界面Call returnEasyAccess(session)Dim leftCell As RangeSet leftCell Sheet1.Range(A i)session.FindById(wnd[0]).Maximize 功能代码session.FindById(wnd[0]/tbar[0]/okcd).Text MR21session.FindById(wnd[0]).SendVKey (0)session.FindById(wnd[0]/usr/ctxtMR21HEAD-BUDAT).Text leftCell.Offset(0, 2).Value 过账日期session.FindById(wnd[0]/usr/ctxtMR21HEAD-BUKRS).Text 3600 公司代码session.FindById(wnd[0]/usr/ctxtMR21HEAD-WERKS).Text leftCell.Offset(0, 1).Value plantsession.FindById(wnd[0]/usr/ctxtMR21HEAD-WERKS).SetFocussession.FindById(wnd[0]/usr/ctxtMR21HEAD-WERKS).CaretPosition 4session.FindById(wnd[0]).SendVKey (0)session.FindById(wnd[0]/usr/tabsMR21_TABSTRIP/tabpTAB1/ssubMR21_SUB:SAPRCKM_MR21:0250/tblSAPRCKM_MR21MR21_TABCONTROL/ctxtCKI_MR21_0250-MATNR[0,0]).Text leftCell.Offset(0, 3).Value 物料编码session.FindById(wnd[0]/usr/tabsMR21_TABSTRIP/tabpTAB1/ssubMR21_SUB:SAPRCKM_MR21:0250/tblSAPRCKM_MR21MR21_TABCONTROL/ctxtCKI_MR21_0250-MATNR[0,0]).CaretPosition 8session.FindById(wnd[0]).SendVKey (0)如果物料有将来价格则存在对话框If Not session.FindById(wnd[1]/tbar[0]/btn[0], False) Is Nothing Thensession.FindById(wnd[1]/tbar[0]/btn[0]).PressEnd Ifsession.FindById(wnd[0]/usr/tabsMR21_TABSTRIP/tabpTAB1/ssubMR21_SUB:SAPRCKM_MR21:0250/tblSAPRCKM_MR21MR21_TABCONTROL/txtCKI_MR21_0250-NEWVALPR[4,0]).Text leftCell.Offset(0, 4).Value 新价格session.FindById(wnd[0]/usr/tabsMR21_TABSTRIP/tabpTAB1/ssubMR21_SUB:SAPRCKM_MR21:0250/tblSAPRCKM_MR21MR21_TABCONTROL/txtCKI_MR21_0250-NEWVALPR[4,0]).SetFocussession.FindById(wnd[0]/usr/tabsMR21_TABSTRIP/tabpTAB1/ssubMR21_SUB:SAPRCKM_MR21:0250/tblSAPRCKM_MR21MR21_TABCONTROL/txtCKI_MR21_0250-NEWVALPR[4,0]).CaretPosition 4session.FindById(wnd[0]).SendVKey (0) Savesession.FindById(wnd[0]/tbar[0]/btn[11]).Press Save之后可能提示物料价格没有更改If Left(session.FindById(wnd[0]/sbar).Text, 4) 对于物料 Thensession.FindById(wnd[0]).SendVKey (0)End IfIf Not session.FindById(/app/con[0]/ses[0]/wnd[1]/usr/txtMESSTXT1, False) Is Nothing Then 价格没有修改对话框leftCell.Offset(0, 5).Value session.FindById(/app/con[0]/ses[0]/wnd[1]/usr/txtMESSTXT1).TextElse 读取返回值leftCell.Offset(0, 5).Value session.FindById(wnd[0]/sbar).TextEnd If 保存If i Mod 5 0 ThenThisWorkbook.SaveEnd If 滚动If i 25 ThenActiveWindow.SmallScroll down:1End IfNext
End Sub