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

Shodan picture Shodan · Jul 9, 2016 · Viewed 12.4k times · Source

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

Answer

Anonygreat picture Anonygreat · Aug 22, 2016

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