1

I have a program in Microsoft Access. I have VBS script files to automate SAP GUI screens ("transactions"). Using VBA in Access opens these different VBS script files using the Scriptcontrol object and performs a transaction in a SAP system.

Now, sometimes there is an error while running the transaction and then the script stops. I have written the error handler in every VBS script files.

My goal is that if there is an error in the SAP while running .VBS then it should close the active SAP session and store the status information in a string called "ScriptStatus". Then I pull this string to the calling vba back and again run the same .vbs script.

Code in the .VBS

    dim ScriptStatus
    
Function (DoWork) 
   
    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
    
    
    
    on error resume Next
    
    'SAP Code
    session.findById("wnd[0]").maximize
    'Furhter SAP Code
    'Change the ScriptStatus to completed
     ScriptStatus = "Script Completed"
    
    If Err.Number <> 0 Then
    'Change ScriptStatus
    ScriptStatus = "Script Error"
    'Close SAP Session
    session.findById("wnd[0]").Close
    End If

End Function

The code in the calling VBA

Sub Foo()
    Dim vbsCode As String, result As Variant, script As Object, ScriptInfo As String
    
    ReRunScript:

    '// load vbs source
    Open "x.vbs" For Input As #1
    vbsCode = Input$(LOF(1), 1)
    Close #1
    
    On Error GoTo ERR_VBS
    
    Set script = CreateObject("ScriptControl")
    script.Language = "VBScript"
    script.AddCode vbsCode
        
    result = script.Run("DoWork")
    ScriptInfo = script.Eval("ScriptStatus")
    If ScriptInfo = "Script Completed" Then 
    Exit Sub
    Elseif ScriptInfo = "Script Error" Then
    Goto ReRunScript
    End if

ERR_VBS:
    MsgBox Err.Description
 
    MsgBox script.Eval("ScriptStatus")
End Sub
Goku
  • 89
  • 7

1 Answers1

3

Rather than running them via cscript you can execute them directly using the ScriptControl (32 bit only) - this would let you catch the errors directly in Access with a standard On Error (As well as allowing you to capture a return value).

Example .VBS file:

function DoWork
    '// do some work
    msgbox 1
    '// error
    x = 100 / 0
    DoWork = "OK"
end function

VBA:

Sub Foo()
    Dim vbsCode As String, result As Variant
    
    '// load vbs source
    Open "x.vbs" For Input As #1
    vbsCode = Input$(LOF(1), 1)
    Close #1
    
    On Error GoTo ERR_VBS
    
    With CreateObject("ScriptControl")
        .Language = "VBScript"
        .AddCode vbsCode
        result = .Run("DoWork")
    End With
    
    Exit Sub

ERR_VBS:
    MsgBox Err.Description
End Sub

Edit - To capture your Status variable make it global in the script (declared outside of a sub/function) and use the .Eval() method to read in in VBA.

Example .VBS file:

dim Status

function DoWork
    '// do some work
    msgbox 1

    Status = "Hello World"
    
    '// error 
    x = 100 / 0
    DoWork = "OK"
end function

VBA:

Sub Foo()
    Dim vbsCode As String, result As Variant, script As Object
    
    '// load vbs source
    Open "x.vbs" For Input As #1
    vbsCode = Input$(LOF(1), 1)
    Close #1
    
    On Error GoTo ERR_VBS
    
    Set script = CreateObject("ScriptControl")
    script.Language = "VBScript"
    script.AddCode vbsCode
        
    result = script.Run("DoWork")
    
    Exit Sub

ERR_VBS:
    MsgBox Err.Description
    '// read VBS global
    MsgBox script.Eval("Status")
End Sub
Alex K.
  • 171,639
  • 30
  • 264
  • 288
  • 2
    There is a third-party 64-bit replacement: [Tablacus Script Control 64](https://tablacus.github.io/scriptcontrol_en.html). – Gustav Sep 16 '21 at 10:26
  • 1
    @Gustav Thanks for the 64-bit information! :) – Goku Sep 16 '21 at 13:22
  • Hi, I have one string in my .vbs file : Status = "Incompleted" . Is it possible to pull this value of string Status in calling VBA with Err.Description? For eg. On error I want to go pull the err.description and this status string. Thanks – Goku Sep 16 '21 at 14:51
  • 1
    Added an example to read `Status`. – Alex K. Sep 17 '21 at 10:37
  • @Alex K. Awesome information and works great but sad part by my side is, I also want to keep error handling in .Vbs file to close the active session of SAP and when this line in .VBS "On error resume next" is on then the Error handling in VBA does not work! Thus I can't pull both error information and the status string! Is it possible to keep the error handling on in .vbs and also pull the String from .VBS file to the calling vba? For eg. On error resume next and If Err.Number <> 0 Then Status = "Script Error" , and close the session. Thanks – Goku Sep 20 '21 at 09:25
  • @AlexK. I have created a new question for this https://stackoverflow.com/q/69252386/15139858 – Goku Sep 20 '21 at 09:53
  • @Goku if the answer doesn't answer the question you are asking don't accept it and create another question, edit the question and explain why it doesn't. Accepting an answer is saying the question has been answered. The [duplicate you have posted](https://stackoverflow.com/q/69252386/15139858) seems no different o this question so clearly it's not been answered. – user692942 Sep 20 '21 at 11:15
  • @user692942 Hi , Sorry for my mistake! When I first tested, it worked great. Then I decided to put the code of closing session in VBA & removed the error handling from .VBS. However, VBA didn't close the exact session, therefore I had to switch back the error handling in .VBS to close the exact session. And thats why I thought to create a new question which will focus on enabling both the error handlings in .VBS and VBA or how to work with it! Thanks – Goku Sep 20 '21 at 11:51