Sap Logon автоматизирует вход в систему с помощью vsbcript
Я использую 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)\SAP\FrontEnd\SAPgui\"
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
Спасибо за помощь!
1 ответ
Вот код VBS, который пытается дождаться, пока SAP войдет в систему и загрузится правильно. До сих пор это работало у меня хорошо.
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)\SAP\FrontEnd\SAPgui\"
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 истинно, параметры user и pass не используются. Тайм-аут также полезен, чтобы избежать бесконечного цикла, если SAP не работает или недоступен. Это решение не требует статического сна в сценарии, чтобы ждать загрузки SAP, что может предотвратить проблемы, если SAP потребует больше, чем ожидалось для загрузки. Кроме того, время не будет потрачено зря, если оно будет загружено раньше, чем ожидалось.
Я использую тот же сценарий, который нашел где-то на справочных форумах 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
И, конечно, хранение имени пользователя и пароля в виде простого текста не является хорошей практикой. Тем не менее, запутывая пароли с помощью VBScript InputBox()
это невозможно. Вам придется использовать командную строку или создать объект IE, который выходит за рамки этого вопроса