Error 91 is when the Object you are trying to use is set to Nothing. So although that line is throwing an error, there is nothing actually wrong with that line. What does need to be fixed is how we get the session object.
My preference for working with the session object is to setup a Function that takes care of that, then it is only a couple of lines of code in your main Sub/Function. One of our original functions that is not pretty but should do what you need goes like this...
Public session As Object
Function GetSession() As Boolean
Dim IE As InternetExplorerMedium
Dim Created_IE As Boolean
Dim Sh As New Shell32.Shell
Dim ShellWindow As Object
Dim OpenWindows As Integer: OpenWindows = 0
Dim OpenSessions As Integer
Dim LoopCount As Integer: LoopCount = 0
Dim SAPSession_Known As Boolean: SAPSession_Known = False
Dim SAPGuiScripting As Object
Dim SAPApplication As Object
Dim SAPConnection As Object
Dim SAPSession As Object
' Loop through all open windows to bring the SAP Portal into focus
For Each ShellWindow In Sh.Windows
' Find the Window with the desired SAP Portal URL
If InStr(1, LCase$(ShellWindow.LocationURL), "com.sap.portal.appintegrator.sap.Transaction") Then
' Count the number of open SAP Sessions
OpenWindows = OpenWindows + 1
End If
DoEvents
Next ShellWindow
Do Until SAPSession_Known = True Or LoopCount > 100
On Error Resume Next
Set SAPGuiScripting = GetObject("SAPGUI")
Set SAPApplication = SAPGuiScripting.GetScriptingEngine
On Error GoTo 0
If OpenWindows = 0 Then
On Error Resume Next
Set SAPConnection = SAPApplication.Children(0)
On Error GoTo 0
On Error Resume Next
Set SAPSession = SAPConnection.Children(0)
On Error GoTo 0
Else
On Error Resume Next
Set SAPConnection = SAPApplication.Children(Int(OpenWindows - 1))
On Error GoTo 0
On Error Resume Next
Set SAPSession = SAPConnection.Children(Int(OpenWindows - 1))
On Error GoTo 0
End If
DoEvents
On Error Resume Next
OpenSessions = SAPApplication.Children.Count
On Error GoTo 0
If (OpenSessions <> 0) And Not (SAPSession Is Nothing) Then SAPSession_Known = True
Loop
On Error Resume Next
AppActivate ("com.sap.portal.appintegrator.sap.Transaction")
On Error GoTo 0
If SAPSession Is Nothing Then
MsgBox "SAP session not found"
GetSession = False
Else
Set session = SAPSession
GetSession = True
End If
End Function
I would then start my macro by checking if there is a SAP session already set and if not find it before continuing with the rest of the program. Where one doesn't exist it will End the program.
Sub RunScript()
Dim SAPOpen As Boolean
If session Is Nothing Then
SAPOpen = SAPGetSession
If SAPOpen = False Then
MsgBox "No SAP session could be found." & vbNewLine & _
"Open a SAP session and try again."
End
End If
End If
With session
.findById("wnd[0]").maximize
.StartTransaction "ME21N" ' I prefer this for starting new transactions
'.findById("wnd[0]").sendVKey 0 ' and it means we can avoid this line
.findById("wnd[0]/tbar[0]/btn[12]").press
End With
End Sub
I hope this helps and I hope this works. Let us know how you go.