"connection.Children(0)"触发"The enumerator of the collection cannot find en element with the specifi



我正在使用VBScript自动登录到SAP GUI。 它会自动打开 SAP GUI 窗口,加载 SAP 服务器,但不会自动填充用户和密码字段(保持空白(。

它还在第 52 行第 4 个字符上给出了一个脚本错误:

集合的枚举器找不到具有指定索引的 en 元素。

代码如下:

REM The following script was written to log into the SAP server automatically.
REM To view historical information and credit for this script please see
REM the following thread on the SAP Community Network:
REM http://scn.sap.com/thread/3763970
REM This script was last updated by Paul Street on 7/1/15
REM Directives
Option Explicit
REM Variables!  Must declare before using because of Option Explicit
Dim WSHShell, SAPGUIPath, SID, InstanceNo, WinTitle, SapGuiAuto, application, connection, session
REM Main
Set WSHShell = WScript.CreateObject("WScript.Shell")
If IsObject(WSHShell) Then
REM Set the path to the SAP GUI directory
SAPGUIPath = "C:Program Files (x86)SAPFrontEndSAPgui"
REM Set the SAP system ID
SID = "eaiserver.domain.com"
REM Set the instance number of the SAP system
InstanceNo = "38"
REM Starts the SAP GUI
WSHShell.Exec SAPGUIPath & "SAPgui.exe " & SID & " " & _
InstanceNo

REM Set the title of the SAP GUI window here
WinTitle = "SAP"

While Not WSHShell.AppActivate(WinTitle)
WScript.Sleep 250
Wend

Set WSHShell = Nothing
End If

REM Remove this if you need to test the above script and want a message box at the end launching the login screen.
REM MsgBox "Here now your script..." 

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
session.findById("wnd[0]").maximize
session.findById("wnd[0]/usr/txtRSYST-MANDT").Text = "100"
session.findById("wnd[0]/usr/txtRSYST-BNAME").text = "I'veInsertedtheCorrectUsernameHere"
session.findById("wnd[0]/usr/pwdRSYST-BCODE").text = "I'veInsertedtheCorrectPassHere"
session.findById("wnd[0]/usr/txtRSYST-LANGU").Text = "PT"
session.findById("wnd[0]/usr/pwdRSYST-BCODE").setFocus
session.findById("wnd[0]/usr/pwdRSYST-BCODE").caretPosition = 10
session.findById("wnd[0]").sendVKey 0

感谢您的帮助!

我使用的是完全相同的脚本,这是我在SAP帮助论坛上的某个地方找到的。

当我之前遇到此问题时,通常是因为SAP GUI窗口是在行之后加载

session.findById("wnd[0]/usr/txtRSYST-BNAME").text = "username"
session.findById("wnd[0]/usr/pwdRSYST-BCODE").text = "password"

有两种方法可以修复此特定脚本。 一种是添加一个MsgBox,该将暂停脚本,但给 SAP GUI 足够的时间来加载。 另一种是添加WScript.Sleep(<a few seconds>)以允许加载 SAP GUI。 这样。。。

请注意,下面的代码包含两个示例,但只需要 1。 我更喜欢.Sleep(),因为它不需要用户的外部输入。

If IsObject(WSHShell) Then
' Removed for clarity
End If
MsgBox "Click OK to continue" ' <-- MsgBox to pause script
WScript.Sleep(5000) ' <--- Wait 5 seconds for SAP GUI to load
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
session.findById("wnd[0]").resizeWorkingPane 164,40,false
session.findById("wnd[0]/usr/txtRSYST-BNAME").text = "username"
session.findById("wnd[0]/usr/pwdRSYST-BCODE").text = "password"
session.findById("wnd[0]/usr/pwdRSYST-BCODE").setFocus
session.findById("wnd[0]/usr/pwdRSYST-BCODE").caretPosition = 14
session.findById("wnd[0]").sendVKey 0

当然,以纯文本形式存储用户名和密码不是一个好的做法。 但是,无法使用 VBScriptInputBox()混淆密码。 您将必须使用命令行,或创建一个超出此问题范围的IE对象

下面是一些尝试等待 SAP 登录并正确加载的 VBS 代码。到目前为止,它对我来说效果很好。

Function SAP_start_and_login(connection_string, use_sso, user, pass)
WScript.Echo "executing function SAP_start_and_login()"
REM Variables!  Must declare before using because of Option Explicit
Dim WSHShell, SAPGUIPath
REM Main
Set WSHShell = WScript.CreateObject("WScript.Shell")
If IsObject(WSHShell) Then
REM Set the path to the SAP GUI directory
SAPGUIPath = "C:Program Files (x86)SAPFrontEndSAPgui"
REM Starts the SAP GUI
if use_sso then
WSHShell.Exec SAPGUIPath & "sapshcut.exe -client={your_client} -sysname=whatevah -gui=" & connection_string & " -snc_name={your_snc_name} -snc_qop={your_snc_qop}"
else
WSHShell.Exec SAPGUIPath & "sapshcut.exe -client={your_client} -sysname=whatevah -gui=" & connection_string & " -user=" & user & " -pw=" & pass
end if
REM WSHShell.Exec SAPGUIPath & "saplogon.exe """ & system & """"
Set WSHShell = Nothing
WScript.Echo "{waiting for SAP to finish loading..}"
SAP_start_and_login = WaitForSAP(connection_string, 50)
WScript.Sleep 1000  
End If
End Function
Function CheckSapIsRunning(connection_string)
Running = False
Ready = False
If Not IsObject(application) Then
On Error Resume Next
Set SapGuiAuto  = GetObject("SAPGUI")
If (Err.Number <> 0) Then
WScript.Echo "SAPGUI object not found yet"
' Error raised, object not found.
' Restore normal error handling.
On Error GoTo 0
Else
'WScript.Echo "einai ok"
' Object found.
' Restore normal error handling.
On Error GoTo 0
Set application = SapGuiAuto.GetScriptingEngine
If application.Connections.Count() > 0 Then
For i = 0 To (application.Connections.Count()-1)
REM WScript.Echo i
Set Connection = application.Children(0+i)
Conn = Connection.ConnectionString()
REM WScript.Echo Conn
If InStr(Conn, connection_string) Then
Running = True
Exit For
End If
Next
End If
If Running Then
REM WScript.Echo connection_string + " is running!"
REM WScript.Echo "sessions="+CStr(connection.Children.Count)
If Not IsObject(session) Then
if connection.Children.Count > 0 then
Set session = connection.Children(0)
If IsObject(WScript) Then
WScript.ConnectObject session,     "on"
WScript.ConnectObject application, "on"
End If
If not session.Busy then
Ready=True
REM WScript.Echo connection_string + " session is ready!"
Dim sapWindow
set sapWindow = session.findById("wnd[0]", False)
if sapWindow is Nothing then
WScript.Echo connection_string + " sap window element not there yet"
else
WScript.Echo connection_string + " is loaded and visible!"
end if
Else
WScript.Echo connection_string + " session is busy!"
end if
else
WScript.Echo connection_string + " session not loaded yet!"
end if
End If
else
WScript.Echo connection_string + " not running!"
End If
End If
End If
REM WScript.Echo application.Connections.Count()
CheckSapIsRunning = Ready
End Function
Function WaitForSAP(connection_string, timeout)
counter = 0
returnValue = False
While NOT CheckSapIsRunning(connection_string) AND counter < timeout
counter = counter + 1
WScript.Sleep 1000
REM WScript.Echo connection_string + " is not ready"
WEnd
if counter = timeout then
WScript.Echo "timeout of " + CStr(timeout) + " seconds reached."
else
returnValue = True
end if
WaitForSAP = returnValue
End Function

这可以像这样使用

If SAP_start_and_login(connection_string, use_sso, username, password) Then
If Not IsObject(application) Then
Set SapGuiAuto  = GetObject("SAPGUI")
Set application = SapGuiAuto.GetScriptingEngine
End If
...{the rest of your recorded script}
Else
WScript.Echo "Could not get a functioning SAP session"
WScript.Quit 1
End If

我正在使用 sapshcut.exe因为以类似的方式同时拥有 SSO 和非 SSO 很容易。连接字符串对于区分和标识要在脚本的其余部分中使用的 SAP 实例非常重要。可以从当前快捷方式以及可能正在使用的 SSO 参数中找到它。如果 SSO 为 true,则不使用用户和传递参数。超时对于避免在 SAP 关闭或无法访问时出现无限循环也很有用。 此解决方案不需要在脚本中设置静态睡眠状态即可等待 SAP 加载,这可以防止在 SAP 加载时间超过预期时出现问题。如果加载时间比预期早,也不会浪费时间。

相关内容

最新更新