0

I'm trying to do a little .vbs-scripting to ease my SAP-workload. I'm starting easy and so first I want to see how many sessions are opened on a specific connection.

This is my code:

Set SapGuiAuto  = GetObject("SAPGUI")
Set application = SapGuiAuto.GetScriptingEngine
iConnections = application.Connections.Count


If iConnections > 0 Then
    For i = 0 to iConnections - 1 
    iSessions = application.Connections.Item(i).Sessions.Count
    msgbox iSessions & "   Sessions for Connection " & i + 1
    Next
End If

Problem is:
I get an error in line 3

Bad index type for collection access.

If I just put a 0 or a 1 in there instead of the i it works perfectly fine. But I cant find the Item with a variable.

Can any of you help me out? I don't know what to do.

Sandra Rossi
  • 11,934
  • 5
  • 22
  • 48
Tom K.
  • 1,020
  • 1
  • 12
  • 28
  • 1
    Looks like your using a custom class of some sort but without the definitions it's hard to advise. What is `application` where is it created, expecting a `Set application = ...` something somewhere. It can't be `Application` object in Classic ASP because that doesn't have a `Connections` collection so what is it? We aren't mind readers you know, you've posted what I believe is custom class code so we need all the parts not a snippet that tells us nothing. – user692942 Jan 22 '16 at 12:12
  • Arf, sorry. I'll add it in in a second. – Tom K. Jan 22 '16 at 12:18

4 Answers4

0

It may be that the Connections collection is indexed beginning with 1, instead of 0. You could try:

If iConnections > 0 Then
    For i = 1 to iConnections
    iSessions = application.Connections.Item(i).Sessions.Count
    msgbox iSessions & "   Sessions for Connection " & i 
    Next
End If

If that doesn't work, then instead of referring to the connections by index, you could try to enumerate them using For..Each, like so

If iConnections > 0 Then
    For Each con in Application.Connections
    i = i + 1
    iSessions = con.Sessions.Count
    msgbox iSessions & "   Sessions for Connection " & i 
    'EDIT: The next line can't explicitly use Next con in VB-script, so I've commented out con
    Next 'con
End If
ThunderFrame
  • 9,352
  • 2
  • 29
  • 60
  • Nah, I already tried version 1, they start with 0 and work perfectly fine when I put in the index by hand. I'm not quite sure what you intend with your second solution and I also dont get that "con" variable you use there. Either way, I want to refer to the connections and sessions one by one later on. So I will need a kind of index in the future. – Tom K. Jan 22 '16 at 11:49
  • This is complete guess work where have you ever seen an inbuilt object `Application.Connections` in VBScript? I know I haven't. – user692942 Jan 22 '16 at 12:17
  • Not guess work at all. It's VBScript, so there is no default Application object, but you can declare "Application to be anything you want, and if that object has a Connections method, then it's perfectly valid. For example, this uses the Application.Folders method to confirm the C Drive exists.... Dim Application Set Application = CreateObject("Scripting.FileSystemObject") Msgbox Application.FolderExists("C:") – ThunderFrame Jan 22 '16 at 12:23
  • Plus, the OP clearly states the code works when the index is hard-codes with a number, so the application object and the connections collection must exist. – ThunderFrame Jan 22 '16 at 12:26
  • It's is still guess work, you said it yourself *"Application to be anything you want"* exactly the OP didn't specify so you are guessing, my point was ask for the information needed to formulate a meaningful answer before jumping in head first. – user692942 Jan 22 '16 at 13:30
  • 1
    You should edit out the first loop solution as it didnt work. But the second works just fine. :) – Tom K. Jan 22 '16 at 13:31
0

Further to Tom's comment in my answer above. My first answer will work with the For Each..Next approach, but I did spot a syntax error in the Next statement (see my edits to that line, above.

However, if you really don't want to use the For Each method, or it's not working for you, then you should be able to get the index approach working.

VBScript is not strongly typed, so you can't Dim variables with exact numeric types like Integer, Long or Byte. However, the Type Library that you're working with is probably expecting a strongly typed argument to the Connections method. Normally, VBScript, or the method you're calling would handle this, but you did mention that you're working with SAP (which I've automated in the past), so I'll assume that this is the cause of the problem.

Like I said, VBScript doesn't offer strongly typed declarations, but it does let you coerce values into specific types. You stated that you managed to get the code working when you provided a numeric literal like 0 or 1, so it seems that your connections method will accept an Integer, but your i variable might implicitly be a Long, given how it is declared.

You could check this by assigning a numeric literal (which will default to an Integer type) to i, like this:

i = 0
iSessions = application.Connections.Item(i).Sessions.Count
msgbox iSessions & "   Sessions for Connection " & i 

Sometimes, a COM object doesn't let you access a child member without having a full handle to the parent first, so a more elaborate test would be:

i = 0
Set con = application.Connections.Item(i)
iSessions = con.Sessions.Count
msgbox iSessions & "   Sessions for Connection " & i 

If either of the above work, then you have a clue that the Connections.Item method is requiring an Integer. So you could potentially get this to work:

Set SapGuiAuto  = GetObject("SAPGUI")
Set application = SapGuiAuto.GetScriptingEngine

'The connections.Count method might coerce a Long or an Integer, or even a Byte
iConnections = application.Connections.Count

If iConnections > 0 Then
    'Convert iConnections to an Integer, and i should then be an Integer too
    For i = 0 to CInt(iConnections) - 1
    set con = application.Connections.Item(i)
    iSessions = con.Sessions.Count
    msgbox iSessions & "   Sessions for Connection " & i + 1
    Next
End If
ThunderFrame
  • 9,352
  • 2
  • 29
  • 60
  • Sorry to tell you, but none of the above work. It's still the same error message. BUT I got your "For..Each"-solution to work. Big mistake on my side regarding that. Thank you so much and especially thanks for your dedication on this! – Tom K. Jan 22 '16 at 13:30
  • Can you elaborate @Tom ?, for some reason you seem to struggle with that. Ideally would like to know what the mistake was, just saying *"Big mistake on my side regarding that."* doesn't help others who come across this question with a similar error looking for an answer. – user692942 Jan 22 '16 at 13:36
  • Easy there. I just didn't implement ThunderFrame's bit of code correctly, although it's pretty easy. That's the reason why I thought, that it doesn't work. – Tom K. Jan 22 '16 at 13:44
  • And to further further elaborate: It seems that you need to have an integer data type but I(!) don't know how (and especially not with those two solutions mentionend first) to assign an integer value to a variable. to conclude: It did work with numerics but did not with variables. – Tom K. Jan 22 '16 at 13:47
0

The only way I managed to avoid the bad index error is when I manipulate the index value while it's the same by adding +1+0-1 after each variable.

Below am counting the number of session in 1 connection using early binding

Sub Session_count()
        
Dim sapAuto As Object
        Dim sapGUI As SAPFEWSELib.GuiApplication
        Dim con As SAPFEWSELib.GuiConnection
        Dim sapSession As SAPFEWSELib.GuiSession
        Dim i As Long
        Dim iSessions As Long
        Dim IConnections As Long
        
        Set sapAuto = GetObject("sapgui")
        Set sapGUI = sapAuto.GetScriptingEngine
        
        IConnections = sapGUI.Connections.Count
        
        If IConnections > 0 Then
                Set con = sapGUI.Connections.Item(IConnections - 1 + 1 - 0 - 1)
                iSessions = con.Sessions.Count - 1
                If iSessions > 0 Then
                        i = 0
                        Do
                                Set sapSession = con.Children.Item(i + 1 + 0 - 1)
                                With sapSession
                                        Debug.Print .Name, .Type, .ID
                                End With
                                i = i + 1 + 1 - 0 - 1 'Here am still incementing i by 1 but for some reason SAP won't give you a bad index
                                Set sapSession = Nothing
                        Loop While i + 0 + 1 - 1 < iSessions + 1
                End If
        End If
End Sub
Mo Zakkut
  • 1
  • 1
  • ses[0] GuiSession /app/con[0]/ses[0] ses[1] GuiSession /app/con[0]/ses[1] ses[2] GuiSession /app/con[0]/ses[2] ses[3] GuiSession /app/con[0]/ses[3] ses[4] GuiSession /app/con[0]/ses[4] ses[5] GuiSession /app/con[0]/ses[5] – Mo Zakkut Jul 03 '16 at 16:05
0

As there is still activity in this post, I will post my final code. It's not in use anymore, but I thought, if there are still people looking for an answer to that specific problem, here is a working solution. (Though other answers were really helpful!)

This was written vor a script which runs inside an .hta-file. Thus the listbox. All the sessions are listed with their IDs there.

function SessionInfo    

Dim i as Long

        'clear listbox
        SessionList.innerhtml = ""

        'create listbox
        Set optGroup = Document.createElement("OPTGROUP")
        optGroup.label = "Server"

        'count number of connections
        ConnectionCount = application.Connections.Count

        If ConnectionCount > 0 Then
            Sessionlist.appendChild(optGroup)
        Else 
            optGroup.label = No connection."
            Sessionlist.appendChild(optGroup)           
        End If

        If ConnectionCount > 0 Then
            For Each conn in application.Connections
                SessionCount = conn.Sessions.Count
                Set objOption = nothing
                Set optGroup = Document.createElement("OPTGROUP")
                optGroup.label = conn.Description
                Sessionlist.appendChild(optGroup)
                i = 0
                For Each sess In conn.Sessions
                    i = i + 1
                    Set objOption = Document.createElement("OPTION")
                    objOption.Text = "Session " & i & ": " & sess.ID
                    objOption.Value = sess.ID
                    SessionList.options.add(objOption)
                Next
            Next
        Else
            Exit function
        End If

End function
Tom K.
  • 1,020
  • 1
  • 12
  • 28