SAP GUI Scripting "Invalid use of property" Error in VBA - vba

Hello I am using SAP GUI Scripting tool which uses Excel VBA functionality to complete the task. I am getting Invalid use of property at Set Application = SapGuiAuto.GetScriptingEngine line of code:
If Not IsObject(Application) Then
Set SapGuiAuto = GetObject("SAPGUI")
Set Application = SapGuiAuto.GetScriptingEngine
Why do I get this error?

I suggest you to rename the variable Application to another name.
Application is here used like a variable, but it is also a pre-defined read-only object in Excel.

Related

SAP Logon 760 via VBA

since the SAP update my vba application fails to connect to the sap system.
My previous code does not work anymore. I guess it is because of the new subfolder. The subfolder "All Urt SAP Systems" and "01 Test System" did not exist in the past.
However this code worked in the past without the new subfolders:
Set rotentry = GetObject("SAPGUI")
Set App = rotentry.GetScriptingEngine
App.Application.DisplayAlerts = False
Set Connection = App.OpenConnection("TE1 (Test - Development System)") '<-- Here comes the error
Set Session = Connection.Children(0)
Does anybody know what I am missing here? I tried a few SAP forums without success.
I am getting the following error message:
SAP Logon connection entry not found

Does anyone know how to automate SAP Login in Automation Anywhere 11

enter image description hereI am using Vb script to launch SAP logon application and successfully able to launch and login into SAP, but the issue, the next line of code is not getting executes until the application is closed.
Any approach how to achieve please suggest.
VB Script Code
[set WshShell = CreateObject("WScript.Shell")
Set fs = CreateObject("Scripting.FileSystemObject")
Set proc = WshShell.Exec("C:\Program Files (x86)\SAP GUI_7.40_P10_LITE (VMware ThinApp)\saplogon.exe")
Do While proc.Status = 0
WScript.Sleep 100
Loop
Set SapGui = GetObject("SAPGUI")
Set Appl = SapGui.GetScriptingEngine
Set Connection = Appl.Openconnection("connectioname", True)
Set session = Connection.Children(0)
session.findById("wnd\[0\]/usr/txtRSYST-BNAME").Text = "username"
session.findById("wnd\[0\]/usr/pwdRSYST-BCODE").Text = "password"
session.findById("wnd\[0\]/usr/txtRSYST-LANGU").Text = "EN"
session.findById("wnd\[0\]").sendVKey 0][1]
Please refer https://botstore.automationanywhere.com/bot/sap-utilities/ , it is free. Just install it and you will be able to use the metabot.
I'd suggest not to use VBScript so extensively for SAP Automation. Metabots are highly compatible and reliable when it comes to SAP Automation. I can provide you SAP DLL (if you need), you can just import it and start using it. In this case, steps to Login to SAP would be as below.
Launch SAP (Program/File Command)
Wait for Window
The rest could be easily done with Metabot DLLs
Also, "the next line of code is not getting executes until the application is closed.", which line of code are you referring to exactly? Is it session.findById("wnd[0]").sendVKey 0][1]
Please try session.findById("wnd[0]").sendVKey [1] or session.findById("wnd[0]").sendVKey [0][1]
you will need the SAP DLL metbot if you are using v11 of AA
doc: https://docs.automationanywhere.com/bundle/enterprise-v11.3/page/enterprise/topics/aae-client/bot-creator/commands/using-bapi-to-automate-task.html

Get Window Instance/Object From Handle (hWnd)

Working in VB/VBA, I have a window handle and I need to convert it to a window object/instance which I can use to access the window object's properties.
AccessibleObjectFromWindow has not proven useful.
How do I do this?
Update
Below is additional detail.
I am working with a window created using mshta.exe and configured with some scripts:
CreateObject("WScript.Shell").Run "%systemroot%\syswow64\mshta.exe about:""<head><script>moveTo(-32000,-32000);document.title='" & x86WindowSignature & "'</script><hta:application showintaskbar=no /><object id='shell' classid='clsid:8856F961-340A-11D0-A96B-00C04FD705A2'><param name=RegisterAsBrowser value=1></object><script>shell.putproperty('" & x86WindowSignature & "',document.parentWindow);</script></head>""", 0, False
For Each Window In CreateObject("Shell.Application").Windows
On Error Resume Next
Set Getx86Window = Window.GetProperty(x86WindowSignature)
Error = Err.Number
On Error GoTo 0
If Error = 0 Then Exit For
Pause 0.01, True
Next Window
' Configure the window environment - global object variables are defined, one for each scripting object - they are instantiated by calling the Initialize routine
Getx86Window.execScript "var VBScript, JScript;"
Getx86Window.execScript "Sub Initialize() : Set VBScript = CreateObject(""MSScriptControl.ScriptControl"") : VBScript.Language = ""VBScript"" : Set JScript = CreateObject(""MSScriptControl.ScriptControl"") : JScript.Language = ""JScript"" End Sub", "VBScript"
' Initialize the window environment
Getx86Window.Initialize
x86WindowSignature is a function that returns a unique string or key.
I'm going through this process because Microsoft doesn't provide 64-bit versions of the VBScript and JScript engines and this process allows me to create 32-bit versions and use them from a 64-bit world.
To reuse this scripting container I need to look at the existing windows and query one of the properties I created:
Set Getx86Window = Window.GetProperty(x86WindowSignature)
Normally I use this logic to find the window of interest:
' Look for an existing window
For Each Window In CreateObject("Shell.Application").Windows
On Error Resume Next
Set Getx86Window = Window.GetProperty(x86WindowSignature)
Error = Err.Number
On Error GoTo 0
If Error = 0 Then Exit Function
Next Window
But, if the application crashes or otherwise fails to close the scripting window, it remains open but is not listed with CreateObject("Shell.Application").Windows.
But I can find it using FindWindow:
WindowHandle = API_FindWindow("HTML Application Host Window Class", x86WindowSignature)
I'm stuck trying to convert the window handle to a VB/VBA "Window" object variable.
I tried a simple copy memory from the handle variable to the object variable but that failed.
It turns out I made an incorrect observation in my initial work. I thought that I was not getting all the windows returned to me that I had created. That is not true. This line:
CreateObject("Shell.Application").Windows
always returns all the windows that were created by Shell.Application. So I had at my disposal all the windows my application had created in the past.
When I posed my question, I thought that I could only get those "lost" window objects by using lower level Windows SDK calls and then somehow convert those hWnds into Shell.Application window object references. I never did figure out how to do that or if it is even possible but that need is no longer required.

application run method "error application-defined or object-defined error"

I'm trying to run a sub for access using the Access.application.run method. It keeps on bringing up error:
40351 "error application-defined or object-defined error"
The code is very basic:
Dim objAccess, wsh As Object
Set wsh = VBA.CreateObject("WScript.Shell")
Set objAccess = CreateObject("Access.Application")
With objAccess
.OpenCurrentDatabase ("c:\coxi\Documents\Personnal\investment\5334_2.accdb")
.Run "test"
Set .CurrentProject = Nothing
End With
the routine errors on the .run line
Root cause: Your code is trying to open un-trusted access DB "5334_2.accdb"
Fix:
Open access application
Goto Trusted center settings under options.
Add the location of the Access DB file.
Retry executing the code.
Thanks a lot !
I had the same hidden problem and could resolve it this way!
I edited code in an .accdb database on the C: drive (C:\…\…\…) and signed the Word templates. Everything worked well, including some Word integration in both directions (Word calling Access procedures and conversely).
When I copied the Access database and the Word templates onto my standard database path (D:\…\…), both the Access database and the Word templates performed well, with the exception of error 40351 in Word on the AccessObj.run "Myproc" …
A pity that neither Word nor Access display a dialog to enable the Access code or at least a sound error message.

What type of object is returned by GetObject("SAPGUI")?

TL;DR ---------------
If I properly declare the variables in the initialisation script, I can't attach to the "connection" objects of a SAPFEWSELib.GuiApplication .
The collection MyApplication.Children(0), is empty but if I comment out the declaration block, it just works !?
TL;DR ---------------
I am trying to create a more reliable connection between my SAP client and my excel application.
My current issue is with the establishing of the connection. The SAP client provides a sample vbscript when using its script recording function.
If Not IsObject(MyApplication) Then
Debug.Print "yep"
Set SapGuiAuto = GetObject("SAPGUI")
Set MyApplication = SapGuiAuto.GetScriptingEngine
End If
If Not IsObject(Connection) Then
Set Connection = MyApplication.Children(0)
End If
If Not IsObject(session) Then
Set session = Connection.Children(0)
End If
This other question on stackoverflow came close to answer, but fell short
stackoverflow.com/questions/24738998/vba-using-variables-that-were-not-declared
The original code is here, I have modified slightly so it would work in excel/vba.
(I dropped the IsObject(Wscript) and I had to replace Application with MyApplication)
First thing I want to do is explicitly declare all variables.
Using code I got at the following address
stackoverflow.com/questions/19783180/get-list-of-all-properties-for-an-object
I used the "TypeLib Information" and the function TypeName() to determine each object type. I tried declaring as follows
Dim session as GuiSession
Dim MyApplication as GuiApplication
Dim Connection as ISapConnectionTarget
Dim SapGuiAuto as object
I'm getting the User-defined type not defined error.
After a bit of searching, I found the partial answer at this address.
scn.sap.com/thread/3254335
I feel manual adding the "C:\Program Files (x86)\SAP\FrontEnd\SAPgui\sapfewse.ocx" reference will break easily. If there's a better way to do this please let me know.
Ok now I can declare like this and it works.
Dim MyApplication As SAPFEWSELib.GuiApplication
Dim Connection As SAPFEWSELib.GuiConnection
Dim session As SAPFEWSELib.GuiSession
Dim SapGuiAuto As Object
I don't like the SapGuiAuto As Object as it doesn't really say what it is and I can't use CTRL+SPACE to view available properties and functions of this object (one of the VB features I can't live without now !)
All I know about this object is that it has a .GetScriptingEngine function (method ?).
While doing the research to write this question I came across this thread on the sap.com forums.
scn.sap.com/thread/3448120
Here it is mentioned that "GetScriptingEngine is a method of the class GuiApplication".
So I tried the following declarations and it seems to work.
Dim MyApplication As SAPFEWSELib.GuiApplication
Dim Connection As SAPFEWSELib.GuiConnection
Dim session As SAPFEWSELib.GuiSession
Dim SapGuiAuto As SAPFEWSELib.GuiApplication
Now if I type "session." the list of possible properties appear.
But there is a problem !
If I type the following line
Debug.Print session.FindById("wnd[0]").Text
It gives an error (while it used to work just fine !).
The error is "Object variable or With bock variable not set".
If I comment out the variable declarations, it works just fine !
Using the TLI function while session is undeclared I get the following members
DumpProperties session.FindById("wnd[0]")
output here -> pastebin.mozilla.org/8882551
but if I run the same command with session properly declared I get.. the same error
So after a bit more research, it turns out that the beginning of the script doesn't work the same now.
If Not IsObject(MyApplication) Then
Will not execute if MyApplication has been declared with Dim MyApplication As SAPFEWSELib.GuiApplication
So I tried executing the commands without the IFs.
Set MyApplication = SapGuiAuto.GetScriptingEngine
Set Connection = MyApplication.Children(0)
Set session = Connection.Children(0)
This fails with the "Object variable or With bock variable not set" error on Set MyApplication = SapGuiAuto.GetScriptingEngine
The solution to this issue was to create a new instance of SapGuiAuto like this.
Set SapGuiAuto = New SAPFEWSELib.GuiApplication
Now the above code executes, until it fails at Set Connection = MyApplication.Children(0)
The error : "The enumerator of the collection cannot find en element with the specified index"
A quick test with the following line reveals, the .Children collection is empty.
For Each chld In MyApplication.Children: Debug.Print "one exists": Next
This is the same error I would normally get if I am currently disconnected from SAP, but I am connected and commenting out the declaration block, fixes the issue.
This answer on stackoverflow is ominous
stackoverflow.com/questions/36751819/sap-gui-scripting-error-the-enumerator-of-the-collection-cannot-find-an-elemen
I'm not an administrator, it's 10 PM on a Friday and asking IT anything is a nightmare. Hopefully I don't have to resort to that.
I will try on another computer.
Just tried, I get the same thing. At this point I have to throw in the towel, I can't get this to work without some help or at least a good night's rest !
Thanks for any advice or comments
Some extra links I found very useful for the people on the same path as I am.
SAP GUI Scripting API PDF
Using the VBA debugger to discover SAP GUI properties and functions
scn.sap.com/docs/DOC-39696
SAP GUI Scripting API Documentation (I couldn't open this file but it's full of good stuff)
www.sdn.sap.com/irj/scn/go/portal/prtroot/docs/library/uuid/a034a16b-3bfe-2a10-e2bb-8bd880db0b3c
SAP GUI Scripting API : How to Automate User Interaction (unfortunately my system lacks the "Script development tools")
scn.sap.com/docs/DOC-4614
Also the BIBS function might be helpful to you, however it was not working on my system
scn.sap.com/docs/DOC-4612
When I use this I also get 0 children as if not connected to SAP:
Set sapCon = New SAPFEWSELib.GuiApplication
By using this instead it's actually working:
Set sapCon = GetObject("SAPGUI").GetScriptingEngine
As per this: https://answers.sap.com/questions/12487790/what-are-the-differences-in-vba-methods-to-connect.html?childToView=12494892
I just came accross this issue myself, and found a solution for the "enumerator" error. Also posted it in the referenced stackoverflow post you mentioned.
Change this:
Set Connection = Sap_Application.Children(0)
Into this:
Set Connection = Sap_Application.Children(1)
As I explained there, not sure why this happens, or what it means, I just messed with the numbers and it worked.
Hope it's not too late, or maybe it will help someone else.
Regards