从 SAP 到 Excel 并再次返回的重复脚本

Posted

技术标签:

【中文标题】从 SAP 到 Excel 并再次返回的重复脚本【英文标题】:repeating script that goes from SAP to Excel and back again 【发布时间】:2017-04-05 01:54:01 【问题描述】:

我正在尝试构建一个脚本,该脚本从 SAP 中的大型报告中提取数据,在 Excel 中运行一些清理,然后将其加载到 Access 中。至少,这是我的最终目标。 SAP 中的数据有点污染,这就是为什么我们使用 Access 作为我们部门特定的已清理数据所在的地方。 我是脚本新手(20 年后,我不记得以前知道的很多内容了),但我一直在使用 SAP 和 Excel 中的内置宏生成器,并且已经部分实现了我想要的.我现在遇到的是错误“Microsoft Excel 正在等待另一个应用程序完成 OLE 操作”。这可能是因为我的报告需要很长时间才能运行。它停止了这个过程,这应该是我可以设置并忘记并在早上获得数据的东西。 该脚本以 Excel 中的宏开始,连接到 SAP 并在那里触发报告。报表运行,然后使用 SAP 将其导出回 Excel。鉴于报告的大小,我只能在一两个月内运行它,但我需要获取一整年的数据。我想我可以让脚本重复 6 次,一次 2 个月。超过 2 个月,报告将在生成任何内容之前超时。我曾尝试使用“在 SAP 上后台运行来简化此操作,但生成的输出是如此乱码以至于毫无用处。这是我到目前为止所拥有的。

Sub Experimental1()

' start the SAP portion

Dim SapGuiAuto, application, connection, session, WScript
If Not IsObject(application) Then
   Set SapGuiAuto = GetObject("SAPGUI")
   Set application = SapGuiAuto.GetScriptingEngine
End If
If Not IsObject(connection) Then
   Set connection = application.Children(0)
End If
If Not IsObject(session) Then
   Set session = connection.Children(0)
End If
If IsObject(WScript) Then
   WScript.ConnectObject session, "on"
   WScript.ConnectObject application, "on"
End If
'
' ***the above is key to opening a script in SAP.  SAP must be running for  this to work***
' begin ZSPWAR launch
session.findById("wnd[0]").maximize
session.findById("wnd[0]/tbar[0]/okcd").Text = "zspwar"
session.findById("wnd[0]").sendVKey 0
session.findById("wnd[0]").sendVKey 17
session.findById("wnd[1]/usr/txtENAME-LOW").Text = ""
session.findById("wnd[1]/usr/txtENAME-LOW").SetFocus
session.findById("wnd[1]/usr/txtENAME-LOW").caretPosition = 0
session.findById("wnd[1]").sendVKey 8         session.findById("wnd[1]/usr/cntlALV_CONTAINER_1/shellcont/shell").currentCellRow = 8
session.findById("wnd[1]/usr/cntlALV_CONTAINER_1/shellcont/shell").selectedRows = "8"
session.findById("wnd[1]").sendVKey 2
' adjust the date
session.findById("wnd[0]/usr/ctxtS_DATE-LOW").Text = (Date)
session.findById("wnd[0]/usr/ctxtS_DATE-HIGH").Text = (Date)
session.findById("wnd[0]/usr/ctxtS_LGORT-LOW").SetFocus
session.findById("wnd[0]/usr/ctxtS_LGORT-LOW").caretPosition = 0
session.findById("wnd[0]/tbar[1]/btn[8]").press
'begins save portion of script
'ignore warning from excel and keep going through long task
'application.IgnoreRemoteRequests = True
' end caffeine like behavior
session.findById("wnd[0]").maximize
session.findById("wnd[0]/mbar/menu[0]/menu[3]/menu[1]").Select
session.findById("wnd[1]/usr/cmbG_LISTBOX").Key = "08"
session.findById("wnd[1]/tbar[0]/btn[0]").press
session.findById("wnd[1]/tbar[0]/btn[0]").press
 session.findById("wnd[1]/usr/subSUBSCREEN_STEPLOOP:SAPLSPO5:0150/sub:SAPLSPO5:0150/radSPOPLI-SELFLAG[0,0]").Select
session.findById("wnd[1]/usr/subSUBSCREEN_STEPLOOP:SAPLSPO5:0150/sub:SAPLSPO5:0150/radSPOPLI-SELFLAG[0,0]").SetFocus
session.findById("wnd[1]/tbar[0]/btn[0]").press
session.findById("wnd[1]/tbar[0]/btn[0]").press

'Ends Save portion

'back into Excel

  ChDir _
         "G:\Warranty\Strategy's\Special Projects\001 Process and Procedure      Documentation\Databases\Core Return Database"
     ActiveWorkbook.SaveAs Filename:= _
         "G:\Warranty\Strategy's\Special Projects\001 Process and Procedure      Documentation\Databases\Core Return Database\ZSPWAR test1.xlsx" _
    , FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False

这就是我想要的,除了我必须通过 excel 错误消息来照看,而且我不知道如何让焦点回到 SAP

感谢您提供的任何帮助或文章。

【问题讨论】:

尝试:File->Options->Advanced,然后在General下勾选Ignore other applications that use DDE Application.DisplayAlerts = False 当我创建一个单独的宏首先运行该行然后将主宏合并为子例程时似乎工作。 【参考方案1】:
sub test
    Dim wsh
    Set wsh = VBA.CreateObject("WScript.Shell")
    wsh.Run ("cscript ""C:\your path\s1.vbs""")
    wsh.Run ("cscript ""C:\your path\s2.vbs""")
    wsh.Run ("cscript ""C:\your path\s3.vbs""")
    wsh.Run ("cscript ""C:\your path\s4.vbs""")
    wsh.Run ("cscript ""C:\your path\s5.vbs""")
    wsh.Run ("cscript ""C:\your path\s6.vbs""")
end sub

【讨论】:

代码可能是答案,但最好添加一些解释【参考方案2】:

在 SAP 中,您最多可以运行 6 个会话:

    创建 6 个会话

    将您的持续时间分成 6 天(例如每个 10 天)

    创建 s1.vba,s2.vbs,s3.vbs,s4.vbs,s5.vbs,s6.vbs(将您的代码复制到此文件中)

    在 vba 编辑器中使用以下命令同时运行所有 6 个会话

【讨论】:

【参考方案3】:

感谢大家的帮助!

问题的最终解决方案是将脚本分解为更小的模块,然后依次运行它们,使用

application.DisplayAlerts = false

是整个程序的第一行。 现在我在excel中总共有3个宏。第一个是我的初始代码,底部的最后几行试图开始保存。这留下了一个坚实的、运作良好的核心。我创建了一个单独的保存宏,它工作得很好。第三个宏运行首先终止警报的行,然后依次运行其他宏,中间有 1 分钟的强制暂停,因为在我工作的机器上来回传递控制所需的时间不一致,因为哎呀。

如果有人想看实际代码,我会把它放上来,但它很长。我只是想分享构建块的一般技术,然后像这样将它们分开串在一起。它为我做了很多项目,我不知道为什么我没有先尝试。

再次感谢大家,我希望这对以后的其他人有所帮助。

【讨论】:

【参考方案4】:

我为您提供解决问题的方法。

例如:

Sub Experimental1()

' start the SAP portion

Dim SapGuiAuto, application, connection, session, WScript
Set SapGuiAuto = GetObject("SAPGUI")
Set SAPapplication = SapGuiAuto.GetScriptingEngine
Set connection = SAPapplication.Children(0)
Set session = connection.Children(0)
'
' ***the above is key to opening a script in SAP.  SAP must be running for  this to work***
' begin ZSPWAR launch
session.findById("wnd[0]").maximize
session.findById("wnd[0]/tbar[0]/okcd").Text = "zspwar"
session.findById("wnd[0]").sendVKey 0
session.findById("wnd[0]").sendVKey 17
session.findById("wnd[1]/usr/txtENAME-LOW").Text = ""
session.findById("wnd[1]/usr/txtENAME-LOW").SetFocus
session.findById("wnd[1]/usr/txtENAME-LOW").caretPosition = 0
session.findById("wnd[1]").sendVKey 8
session.findById("wnd[1]/usr/cntlALV_CONTAINER_1/shellcont/shell").currentCellRow = 8
session.findById("wnd[1]/usr/cntlALV_CONTAINER_1/shellcont/shell").selectedRows = "8"
session.findById("wnd[1]").sendVKey 2
' adjust the date
session.findById("wnd[0]/usr/ctxtS_DATE-LOW").Text = (Date)
session.findById("wnd[0]/usr/ctxtS_DATE-HIGH").Text = (Date)
session.findById("wnd[0]/usr/ctxtS_LGORT-LOW").SetFocus
session.findById("wnd[0]/usr/ctxtS_LGORT-LOW").caretPosition = 0
session.findById("wnd[0]/tbar[1]/btn[8]").press
'begins save portion of script
'ignore warning from excel and keep going through long task
'application.IgnoreRemoteRequests = True
' end caffeine like behavior
session.findById("wnd[0]").maximize
session.findById("wnd[0]/mbar/menu[0]/menu[3]/menu[1]").Select
session.findById("wnd[1]/usr/cmbG_LISTBOX").Key = "08"
session.findById("wnd[1]/tbar[0]/btn[0]").press
session.findById("wnd[1]/tbar[0]/btn[0]").press
 session.findById("wnd[1]/usr/subSUBSCREEN_STEPLOOP:SAPLSPO5:0150/sub:SAPLSPO5:0150/radSPOPLI-SELFLAG[0,0]").Select
session.findById("wnd[1]/usr/subSUBSCREEN_STEPLOOP:SAPLSPO5:0150/sub:SAPLSPO5:0150/radSPOPLI-SELFLAG[0,0]").SetFocus
session.findById("wnd[1]/tbar[0]/btn[0]").press
session.findById("wnd[1]/tbar[0]/btn[0]").press

'Ends Save Portion

'for the SAP German version
'SAP_Workbook = "Tabelle von Basis (1)"

'for the SAP English version (?)
SAP_Workbook = "Worksheet in ALVXXL01 (1)"
EXCEL_Path = "G:\Warranty\Strategy's\Special Projects\001 Process and Procedure Documentation\Databases\Core Return Database"
myWorkbook = "ZSPWAR test1.xlsx"


On Error Resume Next
Do
Err.Clear
Set xclapp = GetObject(, "Excel.Application")
If Err.Number = 0 Then Exit Do
'msgbox "Wait for Excel session"
wscript.sleep 2000
Loop


Do
Err.Clear
Set xclwbk = xclapp.Workbooks.Item(SAP_Workbook)
If Err.Number = 0 Then Exit Do
'msgbox "Wait for SAP workbook"
wscript.sleep 2000
Loop


On Error GoTo 0


Set xclsheet = xclwbk.Worksheets(1)

xclapp.Visible = True
xclapp.DisplayAlerts = False

xclapp.ActiveWorkbook.SaveAs EXCEL_Path & "\" & myWorkbook
xclapp.ActiveWorkbook.Close


Set xclwbk = Nothing
Set xclsheet = Nothing
'xclapp.Quit
Set xclapp = Nothing

'only if an information on the display
session.findById("wnd[1]/tbar[0]/btn[0]").press

问候, 脚本人

【讨论】:

以上是关于从 SAP 到 Excel 并再次返回的重复脚本的主要内容,如果未能解决你的问题,请参考以下文章

关于excel中lookup函数,当要查找的值出现重复时,是按啥原则返加结果?

将 SAP 脚本与 Microsoft Excel 宏组合

使用 Excel 宏从 SAP 中提取数据

jQuery Ajax Post,将它们添加到数据库,返回数据并再次重复该过程

116SAP导出表结构并保存到Excel,方便写代码时复制粘贴

116SAP导出表结构并保存到Excel,方便写代码时复制粘贴