VBA SAP GUI 脚本检查 SAP 是否已经打开
VBA SAP GUI Scripting Check if SAP is already open
首先我想通过 VBA 检查,然后再在 SAP 中进行一些交易,SAP 是否已经打开。我无法第二次登录,所以我需要保持同一个连接。其次我想再开一个session。第二个问题已经解决了,如果我假设 SAP 已经打开的话。但我不确定。所以我需要找到一种方法来访问当前的 SAPGUI 和应用程序和连接,如果它们存在的话。如果不是,If Not IsObject(SAPGUI) Then…
的标准代码就可以了。但是我如何正确定义这些变量以检查它们是否“已填充”Objects?
感谢帮助!
基于 S. Schnell 的script,您可以使用以下功能查找免费会话
Function findGuiSession(ByVal sapSID As String, Optional tCode As String) As SAPFEWSELib.GuiSession
' this will find a free session using the systemnam resp. SID
' and optional one can also supply a transaction to
Dim CollCon As SAPFEWSELib.GuiComponentCollection
Dim CollSes As SAPFEWSELib.GuiComponentCollection
Dim guiCon As SAPFEWSELib.GuiConnection
Dim guiSes As SAPFEWSELib.GuiSession
Dim guiSesInfo As SAPFEWSELib.GuiSessionInfo
Dim i As Long, j As Long
Dim SID As String, transaction As String
'On Error GoTo EH
Dim guiApplication As SAPFEWSELib.guiApplication
Set guiApplication = getGuiApplication
If guiApplication Is Nothing Then
Exit Function
End If
Set CollCon = guiApplication.Connections
If Not IsObject(CollCon) Then
Exit Function
End If
' Loop through all existing connections
For i = 0 To CollCon.Count() - 1
Set guiCon = guiApplication.Children(CLng(i))
If Not IsObject(guiCon) Then
Exit Function
End If
Set CollSes = guiCon.Sessions
If Not IsObject(CollSes) Then
Exit Function
End If
' Now loop through all existing sessions
For j = 0 To CollSes.Count() - 1
Set guiSes = guiCon.Children(CLng(j))
If Not IsObject(guiSes) Then
Exit Function
End If
If guiSes.Busy = vbFalse Then
Set guiSesInfo = guiSes.Info
If guiSesInfo.user = "" Or guiSesInfo.user = "SAPSYS" Then
' Logon Screen - cannot be used
Else
If IsObject(guiSesInfo) Then
SID = guiSesInfo.SystemName()
transaction = guiSesInfo.transaction()
' Take the first one - In case one could also use the transactionaction addtionally
If Len(tCode) = 0 Then
If SID = sapSID Then
Set findGuiSession = guiSes
'FindSession = True
Exit Function
End If
Else
If SID = sapSID And transaction = tCode Then
Set findGuiSession = guiSes
'FindSession = True
Exit Function
End If
End If
End If
End If
End If
Next
Next
Exit Function
'EH:
End Function
Function getGuiApplication() As SAPFEWSELib.guiApplication
On Error GoTo EH
Set getGuiApplication = GetObject("SAPGUI").GetScriptingEngine
EH:
End Function
对于此代码 运行 您需要添加对 SAP 库的引用,描述
以下代码使用上述函数连接到名为 P11 的系统,启动事务 MB52 并将结果下载到 Excel 文件
Option Explicit
Sub getMB52_data()
Dim guiSes As SAPFEWSELib.GuiSession
Set guiSes = getGuiSession("P11")
If Not guiSes Is Nothing Then
With guiSes
.StartTransaction "MB52"
.FindById("wnd[0]/usr/ctxtMATNR-LOW").Text = "<MATNR_LOW<" ' replace with a material nr
.FindById("wnd[0]/usr/ctxtMATNR-HIGH").Text = "<MATNR_HIGH<" ' replace with a material nr
.FindById("wnd[0]/usr/ctxtWERKS-LOW").Text = "<WERKS>" ' replace wiht a plant
.FindById("wnd[0]/tbar[1]/btn[8]").Press
.FindById("wnd[0]/tbar[0]/okcd").Text = "&XXL"
.FindById("wnd[0]/tbar[0]/btn[0]").Press
.FindById("wnd[1]/tbar[0]/btn[0]").Press
.FindById("wnd[1]/usr/ctxtDY_PATH").Text = "<xlPath>" ' Pathname
.FindById("wnd[1]/usr/ctxtDY_FILENAME").Text = "<xlFile>" ' filename
.FindById("wnd[1]/tbar[0]/btn[11]").Press
End With
Else
MsgBox "No free SAP Session", vbOKOnly + vbInformation, "SAP Verbindung"
End If
End Sub
Function getGuiSession(sapSID As String, Optional tCode As String) As SAPFEWSELib.GuiSession
Dim guiApp As SAPFEWSELib.guiApplication
Set guiApp = getGuiApplication
If Not guiApp Is Nothing Then
Set getGuiSession = findGuiSession(sapSID, tCode)
End If
End Function
补充说明:(希望能回答评论中的一些问题)
Gui Connection: GuiConnection代表SAP GUI和应用服务器之间的连接。可以从 SAP Logon 或 GuiApplication 的 openConnection 和 openConnectionByConnectionString 打开连接
方法
因此,换句话说,GUI 连接是一种登录 SAP 系统的方式。通常您的组织中有多个 SAP 系统。如果您遵循指南,您将拥有针对给定系统环境的 DEV、QUAL 和 PROD。每个系统都由 SID
标识
什么是 SID?
SID是每个R/3安装(SAP系统)的唯一标识码,由一个数据库服务器和多个应用程序服务器组成。 SID 代表 SAP 系统标识。 SAPSID — three-character 代码,例如 C11、PRD、E56 等)
SID 在组织内是唯一的。通常 SAP 许可证只允许一个用户登录生产系统一次,即你不能在不同的计算机上使用同一个用户,你甚至不能在同一台计算机上用同一个用户登录 SAP 系统两次。
话虽如此:人们可能会想使用 guiApplication.Children(0)
而不是像 findGuiSession
那样遍历所有连接。只要您可以确保您只登录到一个 SAP 系统并且它是正确的,这就会起作用。但根据我的经验,情况通常并非如此。
findGuiSession
中的参数SID
告诉函数要查找哪个系统。如上所述,SID 是唯一的,因此可以识别您要使用的系统。
在 findGuiSession
中使用 tCode
是可选的,只是强制用户在给定的 tCode 已经启动的情况下进行会话。我很少用这个。
OpenConnection:如果你用函数OpenConnection("<SYSTEM>")
打开一个连接,你当然可以使用返回的对象为了使用它。但是,如果您在您的组织中有一种单点登录,这只会登录到系统。否则,您必须提供登录凭据。我不使用它,因为我不想处理它。并且在登录期间请求更改密码也可能发生,我肯定不想编写脚本。
示例代码
Rem Open a connection in synchronous mode
Set Connection = Application.OpenConnection( "U9C [PUBLIC]", True)
Set Session = Connection.Children(0)
Rem Do something: Either fill out the login screen
Rem or in case of Single-Sign-On start a transaction.
Session.SendCommand( "/nbibs")
首先我想通过 VBA 检查,然后再在 SAP 中进行一些交易,SAP 是否已经打开。我无法第二次登录,所以我需要保持同一个连接。其次我想再开一个session。第二个问题已经解决了,如果我假设 SAP 已经打开的话。但我不确定。所以我需要找到一种方法来访问当前的 SAPGUI 和应用程序和连接,如果它们存在的话。如果不是,If Not IsObject(SAPGUI) Then…
的标准代码就可以了。但是我如何正确定义这些变量以检查它们是否“已填充”Objects?
感谢帮助!
基于 S. Schnell 的script,您可以使用以下功能查找免费会话
Function findGuiSession(ByVal sapSID As String, Optional tCode As String) As SAPFEWSELib.GuiSession
' this will find a free session using the systemnam resp. SID
' and optional one can also supply a transaction to
Dim CollCon As SAPFEWSELib.GuiComponentCollection
Dim CollSes As SAPFEWSELib.GuiComponentCollection
Dim guiCon As SAPFEWSELib.GuiConnection
Dim guiSes As SAPFEWSELib.GuiSession
Dim guiSesInfo As SAPFEWSELib.GuiSessionInfo
Dim i As Long, j As Long
Dim SID As String, transaction As String
'On Error GoTo EH
Dim guiApplication As SAPFEWSELib.guiApplication
Set guiApplication = getGuiApplication
If guiApplication Is Nothing Then
Exit Function
End If
Set CollCon = guiApplication.Connections
If Not IsObject(CollCon) Then
Exit Function
End If
' Loop through all existing connections
For i = 0 To CollCon.Count() - 1
Set guiCon = guiApplication.Children(CLng(i))
If Not IsObject(guiCon) Then
Exit Function
End If
Set CollSes = guiCon.Sessions
If Not IsObject(CollSes) Then
Exit Function
End If
' Now loop through all existing sessions
For j = 0 To CollSes.Count() - 1
Set guiSes = guiCon.Children(CLng(j))
If Not IsObject(guiSes) Then
Exit Function
End If
If guiSes.Busy = vbFalse Then
Set guiSesInfo = guiSes.Info
If guiSesInfo.user = "" Or guiSesInfo.user = "SAPSYS" Then
' Logon Screen - cannot be used
Else
If IsObject(guiSesInfo) Then
SID = guiSesInfo.SystemName()
transaction = guiSesInfo.transaction()
' Take the first one - In case one could also use the transactionaction addtionally
If Len(tCode) = 0 Then
If SID = sapSID Then
Set findGuiSession = guiSes
'FindSession = True
Exit Function
End If
Else
If SID = sapSID And transaction = tCode Then
Set findGuiSession = guiSes
'FindSession = True
Exit Function
End If
End If
End If
End If
End If
Next
Next
Exit Function
'EH:
End Function
Function getGuiApplication() As SAPFEWSELib.guiApplication
On Error GoTo EH
Set getGuiApplication = GetObject("SAPGUI").GetScriptingEngine
EH:
End Function
对于此代码 运行 您需要添加对 SAP 库的引用,描述
以下代码使用上述函数连接到名为 P11 的系统,启动事务 MB52 并将结果下载到 Excel 文件
Option Explicit
Sub getMB52_data()
Dim guiSes As SAPFEWSELib.GuiSession
Set guiSes = getGuiSession("P11")
If Not guiSes Is Nothing Then
With guiSes
.StartTransaction "MB52"
.FindById("wnd[0]/usr/ctxtMATNR-LOW").Text = "<MATNR_LOW<" ' replace with a material nr
.FindById("wnd[0]/usr/ctxtMATNR-HIGH").Text = "<MATNR_HIGH<" ' replace with a material nr
.FindById("wnd[0]/usr/ctxtWERKS-LOW").Text = "<WERKS>" ' replace wiht a plant
.FindById("wnd[0]/tbar[1]/btn[8]").Press
.FindById("wnd[0]/tbar[0]/okcd").Text = "&XXL"
.FindById("wnd[0]/tbar[0]/btn[0]").Press
.FindById("wnd[1]/tbar[0]/btn[0]").Press
.FindById("wnd[1]/usr/ctxtDY_PATH").Text = "<xlPath>" ' Pathname
.FindById("wnd[1]/usr/ctxtDY_FILENAME").Text = "<xlFile>" ' filename
.FindById("wnd[1]/tbar[0]/btn[11]").Press
End With
Else
MsgBox "No free SAP Session", vbOKOnly + vbInformation, "SAP Verbindung"
End If
End Sub
Function getGuiSession(sapSID As String, Optional tCode As String) As SAPFEWSELib.GuiSession
Dim guiApp As SAPFEWSELib.guiApplication
Set guiApp = getGuiApplication
If Not guiApp Is Nothing Then
Set getGuiSession = findGuiSession(sapSID, tCode)
End If
End Function
补充说明:(希望能回答评论中的一些问题)
Gui Connection: GuiConnection代表SAP GUI和应用服务器之间的连接。可以从 SAP Logon 或 GuiApplication 的 openConnection 和 openConnectionByConnectionString 打开连接 方法
因此,换句话说,GUI 连接是一种登录 SAP 系统的方式。通常您的组织中有多个 SAP 系统。如果您遵循指南,您将拥有针对给定系统环境的 DEV、QUAL 和 PROD。每个系统都由 SID
标识什么是 SID? SID是每个R/3安装(SAP系统)的唯一标识码,由一个数据库服务器和多个应用程序服务器组成。 SID 代表 SAP 系统标识。 SAPSID — three-character 代码,例如 C11、PRD、E56 等)
SID 在组织内是唯一的。通常 SAP 许可证只允许一个用户登录生产系统一次,即你不能在不同的计算机上使用同一个用户,你甚至不能在同一台计算机上用同一个用户登录 SAP 系统两次。
话虽如此:人们可能会想使用 guiApplication.Children(0)
而不是像 findGuiSession
那样遍历所有连接。只要您可以确保您只登录到一个 SAP 系统并且它是正确的,这就会起作用。但根据我的经验,情况通常并非如此。
findGuiSession
中的参数SID
告诉函数要查找哪个系统。如上所述,SID 是唯一的,因此可以识别您要使用的系统。
在 findGuiSession
中使用 tCode
是可选的,只是强制用户在给定的 tCode 已经启动的情况下进行会话。我很少用这个。
OpenConnection:如果你用函数OpenConnection("<SYSTEM>")
打开一个连接,你当然可以使用返回的对象为了使用它。但是,如果您在您的组织中有一种单点登录,这只会登录到系统。否则,您必须提供登录凭据。我不使用它,因为我不想处理它。并且在登录期间请求更改密码也可能发生,我肯定不想编写脚本。
示例代码
Rem Open a connection in synchronous mode
Set Connection = Application.OpenConnection( "U9C [PUBLIC]", True)
Set Session = Connection.Children(0)
Rem Do something: Either fill out the login screen
Rem or in case of Single-Sign-On start a transaction.
Session.SendCommand( "/nbibs")