I have combined some of my codes into the below:
Option Explicit
Dim oShell : Set oShell = WScript.CreateObject ("WScript.Shell")
Dim FSO : set FSO = CreateObject("Scripting.FileSystemObject")
Dim StartTime,Elapsed
'msgBox(oShell.CurrentDirectory)
'MsgBox(FSO.GetFile(Wscript.ScriptFullName).ParentFolder )
oShell.CurrentDirectory = FSO.GetFile(Wscript.ScriptFullName).ParentFolder
StartTime = Timer
oShell.run "ParentChildLinkFinal.vbs", 1, True
oShell.run "Parent_Child_Merge_final.vbs", 1, True
oShell.run "CycleTime.vbs", 1, True
oShell.run "Baddata.vbs", 1, True
oShell.run "Matrixrefresh.vbs", 1, True
Elapsed = Timer - StartTime
MsgBox("Total time taken to finish this task:" & Elapsed & "in Seconds")
Now one concern here is- Suppose an error occurs in the any of the CycleTime.vbs file,but the control then going to the next Baddata.vbs file,without killing the Main.vbs file.So how to handle this,If error occurs stop the main.vbs there itself or let the execution to continue.
As Per Daniel
"IF NOT oShell.run( "CycleTime.vbs", 1, True) = 0 then Wscript.Quit would replace the line you are currently using to call "CycleTime.vbs" within Main.vbs
IF oShell.run( "CycleTime.vbs", 1, True) = 99 then Wscript.Quit Would also replace the line you are currently using to call "CycleTime.vbs".
The difference is that you didn't specify how CycleTime.vbs could error out.
If it could fail in such a way that it has a run-time error and simply stops executing, you would want to use the 1st option.
If an error occurs, that you trap with error trapping, you can quit with a code. Like WScript.Quit 99. Then you could check to see if the script ended with that code via the 2nd version that I provided to you.
It really comes down to how you want to handle the failure of your script that you are calling."
WHY SUCH APPROACH
#Daniel True helps the script to suspend its execution until the current .vbs finished. But I am looking for any special value if I can return a special value from each of the .vbs by which main.vbs will get to know that its current .vbs completed successfuly,let's start the next .vbs . But yes iff only success then the next would start. Currently I am seing that suppose an error occurs from any of the .vbs,then as soon as i closed the error window next script started to run. So I am trying atleast thinking iff any success full communication can be sent to the main.vbs. So is it possible?
To expand on what Hiten indicated, you would need to do some checking in your Main.vbs for the return value from your called .vbs files. You do this by utilizing the return value of Run.
For example:
Instead of doing oShell.run "CycleTime.vbs", 1, True do
IF NOT oShell.run( "CycleTime.vbs", 1, True) = 0 then Wscript.Quit
This will exit your current thread of execution if CycleTime.vbs halted due to a run-time error (the call to run the script will return false).
Now if you are able to handle errors gracefully within CycleTime.vbs, you can send a message when you close it by using Wscript.Quit code as explained in the other answer.
So if you want to handle errors gracefully in CycleTime.vbs, you can still indicate an error occurred. Simply check for the return code in your main script with something like this:
IF oShell.run( "CycleTime.vbs", 1, True) = 99 then Wscript.Quit
This way your script will end if CycleTime.vbs ends with code 99. This would happen if within CycleTime.vbs it had code like this:
If err then
'Exit script with code 99 to indicate an error occurred.
Wscript.Quit 99
End if
Use vbscript error handling in main.vbs to stop the code and exit the main.vbs
for more detial click this link:
VBScript -- Using error handling
Sample:
On Error Resume myErrCatch
'Do step 1
'Do step 2
'Do step 3
myErrCatch:
'log error
Resume Next
Create an Exist code from .VBS then exit Main.vbs
DIM returnValue
returnValue = 99
WScript.Quit(returnValue)
Related
I am sharing an Excel workbook with multiple users who are executing a macro that executes the following WinSCP batch script:
"C:\Program Files (x86)\WinSCP\WinSCP.com" ^
/command ^
"open ftp://user:pass#ftp.website.org/" ^
"cd /incoming/data" ^
"put ""%~dp0file.txt""" ^
"exit"
set WINSCP_RESULT=%ERRORLEVEL%
if %WINSCP_RESULT% equ 0 (
echo Success
) else (
echo Error
)
exit /b %WINSCP_RESULT%
The script is executed from VBA as follows:
Call Shell("C:\Users\" & Environ("username") & "\Sharepoint - Library Folder\FTP\ftpupload.bat")
When executed, the command window appears for 1-2 seconds and goes away. Is there a way to leave it up with the Success/Error result or even better would be to pass it back to VBA so I can display the result in an Ok-Window?
Note: I'd like to avoid having to register the WinSCP COM in VBA as this workbook is being used by multiple people and I need to keep it simple with as little prerequisites as possible.
Your batch file already returns exit code indicating an error/success.
So all you need is to capture the code and act accordingly.
For that, see Is it possible to return error code to VBA from batch file?
Set oSHELL = VBA.CreateObject("WScript.Shell")
Dim exitCode As Integer
exitCode = oSHELL.Run("""C:\Users\" & Environ("username") & "\Sharepoint - Library Folder\FTP\ftpupload.bat""", 0, True)
If exitCode <> 0 Then
MsgBox "Failed", vbOKOnly, "Failure"
Else
MsgBox "Succeeded", vbOKOnly, "Success"
End If
my VBS:
Dim WshShell, strCurDir
Set objExcel = CreateObject("Excel.Application")
Set WshShell = CreateObject("WScript.Shell")
strCurDir = WshShell.CurrentDirectory
Set objworkBook = objExcel.Workbooks.Open(strCurDir & "\MasterSheetFetchJob.xlsm")
objworkBook.Fullflow
objExcel.ActiveWorkbook.Close
objExcel.Application.Quit
WScript.Quit
Fullflow:
Sub Fullflow()
Dim Host
Set Host = CreateObject("BZWhll.WhllObj")
Retval = Host.Connect("A")
If (Retval) Then
'Host.MsgBox "Error connecting to session A!", 48
End If
Host.ReadScreen localorvpn, 28, 2, 2
'Enter Command in the TPXA or L TPX based on the connection Type
If localorvpn = "PLEASE ENTER 'Command' TO LOGON" Then
Host.WriteScreen "tpx", 3, 4
Else
Host.ReadScreen vpn, 13, 17, 5
If vpn = "L application" Then
Host.WriteScreen "L TPX", 24, 7
Else
'MsgBox ("Already logged in")
Exit Function
End If
End If
Host.SendKey "<ENTER>"
'Waitfor UserId Text to appear in Login screen
WaitForScreen "Userid", 11, 5
Host.SendKey Username
Host.SendKey "<TAB>"
Host.SendKey mfp
Host.WaitReady 10, 1000
Host.SendKey "<ENTER>"
WaitForScreen "MSGID", 1, 2
Host.SendKey "<ENTER>"
'TPXMenu....
WaitForScreen "Sessid", 6, 6
End Sub
It is properly working when all good.. but during execution if host has some issue.. it stopped the execution thats fine.. but if we open excel it is shwoing it is ready only and not opening.. if we run again without killing excel.. workbook is getting corrupted and not usable..
so everytime we are killing excel before it starts the execution.. but problem is if we have some other not saved workbook also getting closed.. Is this the only to handle this error?
Any suggestion?
I would firstly call the FullFlow Sub (in the script code) in a different way:
I would change
objworkBook.Fullflow
with
objExcel.Application.Run "'" & strCurDir & "\MasterSheetFetchJob.xlsm" & "'!Fullflow"
Then, isn't it any other possibility to avoid sending keys to the 'Host' application? I mean, using API (FindWindow, FindWindowEx and SendMessage). Using Spy++ to see the window child three and find an appropriate way to determine the controls handlers... I do not use this application. Otherwise, I could help with some specific code...
Just from curiosity: why do you use Excel to run that function which does not return anything on a sheet (from what I could see) and not write the function directly in VBScript? It will not be much different, I think... Except the case when you need APIs and VBScript has a problem with this aspect.
I have found similar questions, but for other issues, seems that Excel is called from another application and process is left after Excel application closes.
In my case, I have a macro in my Excel file, and I try to close the application when an error occurs.
I have my error handling set this way:
'Code code code
CleanExit:
Logger.LogData LOG_DEBUG, MODULE_NAME, "Initialize", "Some module initialized!"
Exit Function
ErrorExit:
Logger.LogData LOG_ERROR, MODULE_NAME, "Initialize", "Error found! Description: " & err.description
Main.HandleError err, MODULE_NAME, "Initialize"
GoTo CleanExit
End function
I want my macro to stop running when error occurs in some module and not to stop if it's in another module (hence the GoTo CleanExit).
Error handler is set-up in this way:
Public Function HandleError(ByRef err As ErrObject, ByVal moduleOrgin As String, ByVal methodOrgin As String)
Dim wbk As Workbook
'Do something if module origin meets my parameters and exit function right here if my conditions are met
MsgBox "Some message to the user about the problem"
If GetSetting(SETTING_HIDE_APPLICATION, False) = True Then
For Each wbk In addinWorkbook.Application.Workbooks
wbk.Saved = True
Next wbk
addinWorkbook.Application.Quit
End If
End Function
After this code runs I assume that all further code running stops, as my Excel workbook, which hosts my macro code is closed with the application.
In reality I get a cascade of errors, where the error message is shown 3 times until it closes for good. How can I avoid code any code running after Application.Quit method?
Code workflow when error occurs and what runs after Application.Quit:
Main method to initialize my form
Call to loader method which throws error (Application should quit here)
Main method continues after loader method is finished
Subsequent method is called from main method which also throws an error (because first loader failed)
Lastly my main method throws an error
In total I receive 3 msgboxes with error descriptions.
I must note, that I use the same error handling procedure in all methods, but I would like the code to stop executing, so further code does not trigger any errors.
How can I avoid code any code running after Application.Quit method?
If you want to stop everything, write End after Application.Quit. It stops every piece of VBA and kills all variables you have assigned. This is not considered a good practice (At all!), but it will work exactly as you want.
The question is this: i've been inspecting kaspersky gadget and found out it uses a COM object as i can see declared in the gadget's main html file, so i looked in the registry by the CLSID and got to the "gadget.dll" located in the kaspersky instalation folder.
Mi interest is to invoke specific kaspersky's app tab just the same way they do. Examining the .js files on the gadget's folder i could see the syntax of the method i would need to use which is "OpenWindow(WindowID)" and the WindowID's are also specified in another file.
I've been trying this from a simple VisualBasic Script:
Set kavCOM = WScript.CreateObject("KISGadgetCOM.COMClass.1")
kavCOM.OpenWindow(1)
that should invoke the Main Window, also tried a AutoHotKey Script:
^!k::
{
kavCOM := ComObjCreate("{ED6E691B-E662-4aae-AECC-705C9B014C75}")
kavCOM.OpenWindow(1)
}
they both result in the error: 80004004 (Operation aborted) at the line with "kavCOM.OpenWindow(1)
what's wrong?
Ok, the problem was the Object instantiation delay, i solved it by adding
WScript.Sleep 1000
just before calling the "OpenWindow" method.
My final(finer) solution so that it doesn't wait more than needed:
Dim kavCOM, Cnt
Cnt = 0
Set kavCOM = CreateObject("KISGadgetCOM.COMClass.1")
On Error Resume Next
Do
Cnt = Cnt + 1
kavCOM.OpenWindow(1)
If Err = 0 Then
Exit Do
Else
Err.Clear
End If
WScript.Sleep 10
Loop
On Error Goto 0
MsgBox "It took " & 10*Cnt & " miliseconds."
Set kavCOM = Nothing
I want to know what is the return type when I call the below function in my vba project.
Ret = wsshellobj.Run(application_filepath, True)
I need to incorporate error handling at this point. what I have done is
If Err.Number <> Ret Or Err.Number = 0 Then
'Error Handler code
End If
But this doesn't seem to work
Thanks,
Gana
Hope this helps?
TOPIC: Method: WshShell.Run
LINK: http://www.devguru.com/technologies/wsh/quickref/wshshell_run.html
EXTRACT FROM THE ABOVE LINK:
The Run method creates a new process and runs the command specified by strCommand. The optional parameter intWindowStyle is used to set the window style of the program being run. If the optional parameter bWaitOnReturn is set to True (default is False), then Run will return the return value returned by strCommand. Otherwise it returns 0. Also, if bWaitOnReturn is set to True, then the script will suspend its execution until strCommand finishes.