SAP GUI Scripting: new session from VBA - vba

I am searching for macro script that opens new session when current session is running.
Problem is that macro opens new session when it's only opened, but not makes new session when current session is running example transaction after pressing execute button.
My macro below:
Private Sub nextSession()
Dim nSessions As Integer
Set SapGuiAuto = GetObject("SAPGUI")
Set SAPApp = SapGuiAuto.GetScriptingEngine
Set sapCon = SAPApp.Children(0)
Set session = sapCon.Children(0)
nSessions = sapCon.Sessions.Count
session.CreateSession
Do
Application.Wait (Now() + 500 * ms)
If sapCon.Sessions.Count > nSessions Then Exit Do
Loop
Set sapSession = sapCon.Sessions.Item(CInt(sapCon.Sessions.Count - 1))
End Sub

Related

SAP GUI Script (VBA) - Variable Not defined

I have this script below copied from a video tutorial somewhere. I recorded the SAP GUI script in 'development' system and tested. It worked fine for me. Now, when other users are trying to use the script using the 'production' system, they get
Compile error: variable not defined
in this line:
Set objConn = objGui.Children(0)
Option Explicit
Public SapGuiAuto, WScript, msgcol
Public objGui As GuiApplication
Public objConn As GuiConnection
Public session As GuiSession
Sub COGS_Report()
Set SapGuiAuto = GetObject("SAPGUI")
Set objGui = SapGuiAuto.GetScriptingEngine
Set objConn = objGui.Children(0)
Set session = objConn.Children(0)
Any tip what to modify in the code?
Regards
I had almost the same issue, where some code needed to be commented away
Try using this code that should only start IE02 transaction (Change equipment). Depending on our system and your user, SAP should respond that a Script is trying to access the Scripting object of SAP. And if you have a Session open it should pick this to use.
SystemName = "KO3" 'change as needed or use a variable
Transaction = "SESSION_MANAGER" 'change as needed or use a variable
On Error GoTo ErrorHandler:
If Not IsObject(Sap_Applic) Then
Set SapGuiAuto = GetObject("SAPGUI")
Set Sap_Applic = SapGuiAuto.GetScriptingEngine
End If
On Error GoTo 0
koniec:
qConnections = Sap_Applic.Connections.Count
If qConnections = 0 Then
MsgBox "No connection to SAP"
End
End If
'MsgBox Sap_Applic.Children(0).info.SystemName
bSession = False
For iConnectionCounter = 0 To qConnections - 1
Set Connection = Sap_Applic.Children(Int(iConnectionCounter))
'MsgBox Connection.Description
'If Not Connection.Description = "" Then
qSessions = Connection.Children.Count
For iSessionCounter = 0 To qSessions - 1
Set Session = Connection.Children(Int(iSessionCounter))
'MsgBox Session.info.SystemName
If Session.info.SystemName <> SystemName Then Exit For
If Session.info.Transaction = Transaction Then
bSession = True
Exit For
End If
Next
'End If
If bSession Then Exit For
Next
If Not bSession Then
MsgBox SystemName & " not available or free session not available"
End
End If
'Stop
Session.findById("wnd[0]").resizeWorkingPane 154, 24, False
Session.findById("wnd[0]/tbar[0]/okcd").Text = "ie02"
Session.findById("wnd[0]").sendVKey 0
Exit Sub
ErrorHandler:
MsgBox "No connection to SAP"
End

SAP connection in VBA - Error 424 Object Required

I was able to edit this code and make VBA connect with SAP.
When I make the call the code stops working on the first line of second code - Session.findById... and gives the error
Run time error 424: Object Required
Follow the codes and the error occurs on the commented line in the second code.
Full code of the SAP connection module:
Global Session
Sub SAP_Login(ByVal Transacao As String)
Dim SapGui
Dim Applic
Dim Connection
Dim Session
Dim WshShell
Dim mensagem As String
On Error GoTo DESLOGADO
Set Session = GetObject("SAPGUI").GetScriptingEngine.Children(0).Children(0)
GoTo LOGADO
DESLOGADO:
'Abre o Sap instalado na sua máquina
Shell "C:\Program Files (x86)\SAP\FrontEnd\SAPgui\saplogon.exe", vbNormalFocus
'inicia a variável com o objeto SAP
Set WshShell = CreateObject("WScript.Shell")
Do Until WshShell.AppActivate("SAP Logon ")
Application.Wait Now + TimeValue("0:00:01")
Loop
Set WshShell = Nothing
Set SapGui = GetObject("SAPGUI")
Set Applic = SapGui.GetScriptingEngine
Set Connection = Applic.OpenConnection("NEA Dow Prod - ERP Central Component (ECC) (SSO) (001)", True)
Set Session = Connection.Children(0)
Session.findById("wnd[0]").maximize
'DADOS PARA FAZER O LOGIN NO SISTEMA
'On Error Resume Next
'Session.findById("wnd[0]/usr/txtRSYST-MANDT").Text = "800" 'client do sistema
Session.findById("wnd[0]").sendVKey 0
LOGADO:
With Session
.findById("wnd[0]/tbar[0]/okcd").Text = "/o"
.findById("wnd[0]").sendVKey 0
.findById("wnd[0]/tbar[0]/okcd").Text = "/n"
.findById("wnd[0]").sendVKey 0
.findById("wnd[0]/tbar[0]/okcd").Text = Transacao
.findById("wnd[0]").sendVKey 0
'possivel texto de erro sap vai aparecer no excel
mensagem = .findById("wnd[0]/sbar").Text
If mensagem <> Empty Then
Application.StatusBar = mensagem
End If
End With
'ESSA PARTE SAI DO SISTEMA POS A EXECUÇÃO DO CÓDIGO
'Set session = Nothing
'Application.Wait Now + TimeValue("0:00:05")
'connection.CloseSession ("ses[0]")
'Set connection = Nothing
'Set sap = Nothing
End Sub
Second code that makes the call and continues the SAP script (it's on a button):
Private Sub EXTRAIR_Click()
Call SAP_Login("coois")
Session.findById("wnd[0]/mbar/menu[2]/menu[0]/menu[0]").Select 'THIS IS WHERE THE ERROR BEGINS!!!
Session.findById("wnd[1]/usr/txtENAME-LOW").Text = "nd87309"
Session.findById("wnd[1]").sendVKey 8
Session.findById("wnd[0]/usr/tabsTABSTRIP_SELBLOCK/tabpSEL_00/ssub%_SUBSCREEN_SELBLOCK:PPIO_ENTRY:1200/ctxtS_ECKST-LOW").Text = "07062022"
Session.findById("wnd[0]/usr/tabsTABSTRIP_SELBLOCK/tabpSEL_00/ssub%_SUBSCREEN_SELBLOCK:PPIO_ENTRY:1200/ctxtS_ECKST-HIGH").Text = "07062022"
Session.findById("wnd[0]").sendVKey 8
Session.findById("wnd[0]/usr/cntlCUSTOM/shellcont/shell/shellcont/shell").SetCurrentCell -1, ""
Session.findById("wnd[0]/usr/cntlCUSTOM/shellcont/shell/shellcont/shell").SelectAll
Session.findById("wnd[0]/usr/cntlCUSTOM/shellcont/shell/shellcont/shell").ContextMenu
Session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell").SelectContextMenuItemByPosition "0"
Range("A2").PasteSpecial
MsgBox "Copiado com Sucesso"
End Sub
You have
Dim Session
inside SAP_Login: that variable will "hide" the Global variable with the same name, so when that sub exits the Global is still Nothing. Remove the local variable declaration so only the Global one remains.

How to execute SAP GUI Macro from VBA in Excel or Visual Studio?

I want to edit and launch SAP macros from either the VBA editor in Excel or from a Windows Form Application.
I cannot get my code to "connect" to the current SAP session when the script is used in a compiler. The only time it works is when I open the original VBScript that the macro recorder creates.
The way SAP is set up on my system we are automatically logged in to SAP Logon and launch a new sap GUI window via a web portal saplogon.com/irj/portal, I don't need to physically log on before I interact with the GUI.
When I copy the macro script verbatim I get runtime errors:
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/subSA_0100_1:SAPMZCX_CSDSLSBM5001_OFS_OTS:2410/subSA_2410_1:SAPMZCX_CSDSLSBM5001_OFS_OTS:2510/ctxtKUWEV-KUNNR").text = "I033"
session.findById("wnd[0]/usr/subSA_0100_1:SAPMZCX_CSDSLSBM5001_OFS_OTS:2410/subSA_2410_1:SAPMZCX_CSDSLSBM5001_OFS_OTS:2510/ctxtKUWEV-KUNNR").caretPosition = 4
session.findById("wnd[0]").sendVKey 0
session.findById("wnd[1]/usr/lbl[12,3]").setFocus
session.findById("wnd[1]/usr/lbl[12,3]").caretPosition = 16
session.findById("wnd[1]").sendVKey 2
session.findById("wnd[0]/shellcont/shell/shellcont[1]/shell").setCurrentCell 1,"MAKTX2"
session.findById("wnd[0]/shellcont/shell/shellcont[1]/shell").doubleClickCurrentCell
session.findById("wnd[1]/tbar[0]/btn[0]").press`
The way I have been trying to go about this is to add the sapfewselib reference into the project and then declare the SAP GUI object.
All the examples I can find are on how to log on to a new SAP session. I can't understand why the code will execute when a notepad is saved as a VBScript file but not when attached to a button in a Windows Form Application or an Excel Spreadsheet even though I have added the reference.
So I still can't find an example in c# which doesn't include log in but for the VBA editor in Excel the following works, but note in Visual Studio 'set' and 'let' keywords have been retired. Just in case anyone else has the same issue, this is what you need to assign to a button:
Sub Button1_Click()
Dim SapGuiAuto
Dim SetApp
Dim Connection
Dim Session
Set SapGuiAuto = GetObject("SAPGUI")
Set SetApp = SapGuiAuto.GetScriptingEngine
Set Connection = SetApp.Children(0)
Set Session = Connection.Children(0)
Session.findById("wnd[0]").maximize
//Then your script to control gui below this://
Session.findById("wnd[0]/usr/subSA_0100_1:SAPMZCX_CSDSLSBM5001_OFS_OTS:2410/subSA_2410_1:SAPMZCX_CSDSLSBM5001_OFS_OTS:2510/ctxtKUWEV-KUNNR").Text = "I033"
Session.findById("wnd[0]/usr/subSA_0100_1:SAPMZCX_CSDSLSBM5001_OFS_OTS:2410/subSA_2410_1:SAPMZCX_CSDSLSBM5001_OFS_OTS:2510/ctxtKUWEV-KUNNR").caretPosition = 4
Session.findById("wnd[0]").sendVKey 0
Session.findById("wnd[1]/usr/lbl[12,3]").SetFocus
Session.findById("wnd[1]/usr/lbl[12,3]").caretPosition = 16
Session.findById("wnd[1]").sendVKey 2
Session.findById("wnd[0]/shellcont/shell/shellcont[1]/shell").setCurrentCell 1, "MAKTX2"
Session.findById("wnd[0]/shellcont/shell/shellcont[1]/shell").doubleClickCurrentCell
Session.findById("wnd[1]/tbar[0]/btn[0]").press
End Sub

SAP Logon connection with VBA automation error

I have the following code for connecting SAP logon with VBA
Private Sub CommandButton1_Click()
Dim SAPapplication, Connection, session As Object
Set SAPGUIAuto = GetObject("SAPGUI")
Set SAPapplication = SAPGUIAuto.GetScriptingEngine
Set Connection = SAPapplication.Children(0)
Set session = Connection.Children(0)
session.findById("wnd[0]").maximize
session.findById("wnd[0]").sendVKey 0
session.findById("wnd[0]/tbar[0]/okcd").Text = "******"
session.findById("wnd[0]").sendVKey 0
THe code works perfectly if I have login through my credentials in the SAP system.
But it gives following error, when I try login through other credentials.
What is the problem here?

VBA SAP createsession

Maybe someone can help me with creating new SAP session using VBA Excel
Some code to understand the problem
If Not IsObject(sap) Then
Set SapGuiAuto = GetObject("SAPGUI")
Set sap = SapGuiAuto.GetScriptingEngine
End If
If Not IsObject(Connection) Then
Set Connection = sap.Connections.Item(0)
End If
If Not IsObject(session) Then
Set session = Connection.Children(0)
End If
Most cases this one work fine. But sometimes this part doesn't work
Set session = Connection.Children(0)
it happens for example when SAP timeout occur (auto logoff after some idle time).
In that case I have
sap.Connections.Count
= 2
but
Connection.Sessions.Count
= 0
Looks like the timeouted connection still hangs somewhere in SAP. So when I try to connect to first session of first connection I got an error couse there is no session in first connection.
What I want to do is to create new session.
I can do this by
Dim sapSession As SAPFEWSELib.GuiSession
Dim sapCon As SAPFEWSELib.GuiConnection
Set sapCon = sap.Connections.Item(0)
Set sapSession = Connection.sessions.Item(0)
sapsession.createsession
This one works ok but it doesn't help couse I still need to set the session first
Is there a way to create session after setting the connection?
Something like sapCon.createsession
And does anyone know how can I use specific session using variable?
Set sapSession = Connection.sessions.Item(0)
This works ok but when I try
Dim SessionNumber as integer
....
SessionNumber = 0
Set sapSession = Connection.sessions.Item(SessionNumber)
it throws an error "Bad index type for collection access"
Excel requires that the session number is an integer, so you can use the type conversion from Cint(). Strange that this is advised/required even when SessionNumber is defined as an integer.
Dim SessionNumber
....
SessionNumber = 0
Set sapSession = Connection.sessions.Item(Cint(SessionNumber))
The CreateSession command executes quickly and returns to Excel, but SAP takes a while to finish opening the new session. Thus, you'll need to make your Excel code wait.
Here's an example:
Const ms as Double = 1.15740741E-08 ' one millisecond, in days = 1/(1000*24*60*60)
Dim sapCon As SAPFEWSELib.GuiConnection
Dim sapSession As SAPFEWSELib.GuiSession
Dim nSessions As Integer
Set sapCon = sap.Connections(0)
Set sapSession = sapCon.Sessions(0)
nSessions = sapCon.Sessions.Count
sapSession.createsession
Do
Application.Wait (Now() + 500*ms)
If sapCon.Sessions.Count > nSessions Then Exit Do
Loop
Set sapSession = sapCon.Sessions.Item(CInt(sapCon.Sessions.Count - 1))