首先,我想通过VBA进行检查,然后在SAP中进行一些事务处理,如果SAP已经打开。我无法第二次登录,所以我需要保持相同的连接。第二,我想再开一次会。如果我假设SAP已经打开,那么第二个问题已经解决了。但我不太确定。因此,我需要找到一种方法来访问当前的SAPGUI以及应用程序和连接,如果它们存在的话。如果不是,If Not IsObject(SAPGUI) Then…
的标准代码是可以的。但是,如何正确地定义这些变量以检查它们是否“填充”对象?
谢谢你帮忙!
发布于 2022-03-26 07:12:56
基于S.Schnell的脚本,您可以使用follwing函数找到一个空闲会话
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
附加备注:(希望在评论中回答一些问题)
SAP连接__:https://help.sap.com/viewer/b47d018c3b9b45e897faf66a6c0885a8/770.00/en-US/8093f712d0ed4092a463b7edee5792cb.html表示SAP与应用服务器之间的连接。连接可以从SAP打开,也可以从GuiApplication的openConnection和openConnectionByConnectionString方法打开
因此,换句话说,gui连接是对SAP系统的一种登录。通常,您的组织中有多个SAP系统。如果您遵循指导原则,那么对于给定的系统环境,您有一个DEV、QUAL和PROD。这个系统的每一个都是由一个SID标识的。
什么是SID? https://help.sap.com/viewer/2c1988d620e04368aa4103bf26f17727/2.0.01/en-US/7672838aa9c44c7ab9d10188531669f3.html是每个R/3安装( system)的唯一标识代码,由一个数据库服务器和几个应用服务器组成。SID代表SAP系统识别。SAPSID --一个三字符的代码,如C11、PRD、E56等)
SID在组织中是唯一的。通常,SAP许可证只允许用户登录一次生产系统,也就是说,您不能在不同的计算机上使用同一个用户,甚至不能在同一台计算机上使用同一用户登录到SAP系统两次。
话虽如此:人们可能会倾向于使用guiApplication.Children(0)
,而不是像在findGuiSession
中那样循环所有连接。只要您能够确保您只登录到一个SAP系统,并且它是正确的,这将是有效的。但根据我的经验,情况往往并非如此。
SID
中的参数findGuiSession
告诉要查找哪个系统的函数。如前所述,SID是唯一的,因此可以标识您想要使用的系统。
在tCode
中使用findGuiSession
是可选的,只是强制用户使用已经启动的给定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")
https://stackoverflow.com/questions/71624238
复制相似问题