I am trying to fetch CR(change request) status from PTC(MKS) using "im exportissues 123456" query in VBA. but it does open status sheet(A new excel sheet which opens up by query) unless my code ends. below is the snippet of my code.
Sub Query_CR_Status()
shell_output = Shell("im exportissues 123456", 1) 'this should open up a new excel sheet containing CRs)
Application.Wait (Now + TimeValue("0:00:20")) 'waiting 20sec
'here: My code which will read information from the above generated excel sheet
End Sub
But My problem here is the new excel sheet donot open unless it reaches to "End Sub"
Application.Wait() will prevent the application from doing anything for the specified amount of time. So if you shell a command that opens a workbook, but the application is in wait mode then it will be delayed.
You can try and get around this by using something like:
Sub Query_CR_Status()
Dim wbC As byte
wbC = Workbooks.Count
shell_output = Shell("im exportissues 123456", 1)
While Workbooks.Count = wbC
DoEvents '// Process pending messages until workbook count changes
Wend
'// Rest of code
End Sub
Alternatively, Chip Pearson created a ShellAndWait function that might be better suited to this.
Related
First off I'm sorry that i'm very very new to VBS, but i'm trying to create a little script that will complete a series of key strokes then on a website for work then go to another website and complete another series of key strokes.
Whilst on the first website there I need to ask a question like did the action complete. Yes or No.
If No then the script needs to go back to the start of the script. If yes then the script needs to continue.
Later on, on the second website after a few keystrokes I need to ask another question weather to loop the whole process or to stop.
I've googled a few message box solutions but it doesn't seem to work. I have
The first question box.
intSerialNumber = _
Msgbox("Was there a problem?", _
vbYesNo, "Problem?")
If intSerialNumber = vbYes Then
LoopShip
Else
Continue
End If
Continue
The Second question box.
If msgbox("Continue?", vbYesNo) = vbNo Then
WScript.quit
End If
if LoopShip = True Then
LoopShip
End If
Wend
Try using nested loops with functions for readability like this. The user can rerun the code from the first website as many times as they want and can rerun the code from both websites as many times as they want.
Dim problemsOccurred
problemsOccurred = vbYes
Do
Call firstWebsite()
problemsOccurred = secondWebsite()
Loop Until (problemsOccurred = vbNo)
Sub firstWebsite()
Dim firstWebsiteProblem
firstWebsiteProblem = vbYes
Do
'First Website code Goes here
firstWebsiteProblem = Msgbox("Was there a problem?", vbYesNo, "Problem?")
Loop Until (firstWebsiteProblem = vbNo)
End Sub
Function secondWebsite()
'Second WebSite code goes here
secondWebsite = MsgBox("Continue Whole Process?", vbYesNo)
End Function
I'm using VBscript to open Microsoft Excel and convert xls documents to csv.
Here is a quick example that takes an argument and converts the first page
Dim oExcel
Dim oBook
Set oExcel = CreateObject("Excel.Application")
Set oBook = oExcel.Workbooks.Open(Wscript.Arguments.Item(0))
oBook.SaveAs "out.csv", 6
oBook.Close False
oExcel.Quit
If everything works, that's great. But when the script crashes before it can close excel, the process continues to stay around and lock the file until I manually kill the process.
How can I make sure that I perform any clean up routines even when the script fails?
As the question is/was? about closing Excel reliably when the VBScript used to automate it crashes:
If you write
Set oExcel = CreateObject("Excel.Application")
you create a 'simple' variable. VBScript may decrement a ref counter when the variable goes out of scope, but it certainly won't .Quit Excel for you.
If you want a feature like atexit calls or exception handling in VBScript, you'll have to write a class that 'does what I mean' in its Class_Terminate Sub. A simple example:
Option Explicit
Class cExcelWrapper
Private m_oExcel
Public Sub Class_Initialize()
Set m_oExcel = CreateObject("Excel.Application")
End Sub
Public Sub Class_Terminate()
m_oExcel.Quit
End Sub
Public Default Property Get Obj()
Set Obj = m_oExcel
End Property
End Class
Dim oExcel : Set oExcel = New cExcelWrapper
Dim oWBook : Set oWBook = oExcel.Obj.WorkBooks.Add()
oExcel.Obj.Visible = True
oExcel.Obj.DisplayAlerts = False
oWBook.Sheets(1).Cells(1,1) = "Div by Zero"
WScript.Echo "Check TaskManager & Enter!"
WScript.StdIn.ReadLine
WScript.Echo 1 / 0
(meant to be started with "cscript 20381749.vbs")
If you run this script with an open Taskmanager, you'll see Excel popup in the processes list (and on the screen, because of .Visible). If you then hit Enter, the script will abort with an "Division by Zero" error and the Excel process will vanish from the Processes list.
If you remove the .DisplayAlerts setting, Excel will ask you whether to save your work or not - proving thereby that the .Quit from the Class_Terminate() Sub really kicks Excel into byebye mode.
The class needs further work (basic settings, common actions (save?) before .Quit, perhaps a guard against misuse (Set oExcel = Nothing or other cargo cult crap), th .Obj addition isn't nice, and it won't help you if you kill your .vbs in a debugger, but for standard scenarios you won't see Excel zombies anymore.
Add "On Error Goto ErrorHandler" at the top of your script, and at the bottom of it, add "ErrorHandler:". Underneath the ErrorHandler label add code to manage the situation depending on the Err.Number
See Err object on MSDN.
You can also use "On Error Resume Next". Here is an example.
EDIT: My bad. "Goto" does not exist in VBS. The answer below is probably a much tidier approach.
Part of my code copys info from one worksheet in Excell to another. Every time I run this cood it gives me a run time error '1004' for the last line of code (activeSheet.Paste). Does anyone know how to fix it?
Sub CopyData()
ActiveWindow.SmallScroll Down:=-9
Sheets("sponsor & contributions 2012").Select
Range("A1:K93").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("remaining payments").Select
Selection.PasteSpecial Paste:=xlPasteFormats
ActiveWindow.SmallScroll Down:=-12
Range("A1:K93").Select
ActiveSheet.Paste
End Sub
Rather than simulating a user 'copy+paste', it's easier, quicker and more robust to set the value of your target range to that of your source range. e.g.
Public Sub Copy()
Sheet2.Range("A1:K93").Value = Sheet1.Range("A1:K93").Value
End Sub
Determining the cause of a 1004 error can be very difficult without being able to look over the spreadsheet, so I would definitely recommend the above approach
I wrote a VBScript app to open Word and Excel documents and search and replace blocks of text and various sections, pulling the new text from a plain text file. I purposely avoided any error checking, primarily because I couldn't figure it out at the time (and the script ran reliably anyway). Now months later on my local machine, I am inexplicably getting error messages about Normal.dot being changed and a message box asking what I want to do about it (which requires three more dialogs to finally answer). Of course this kills my ability to run the script and simply walk away, as it causes the script to fail. Currently when this happens, I have to open the Task Manager, find Winword.exe (of which the GUI isn't running) and kill it then re-run my script.
What's a reasonable way of catching the error and successfully shutting down Word (or Excel). Based on this question I'm trying this:
Set objDoc = objWord.Documents.Open(curDir1 + "\docs\template_spec.dot")
If Err.Number <> 0 Then
WScript.Echo "Error in Word Open:" & Err.Description
objWord.Quit
Else
Set objSelection = objWord.Selection
'Do replacement activities'
ReplaceText(objSelection)
objDoc.SaveAs(curDir1 + "\docs\mynewdocument.doc")
objWord.Quit
End If
Set objShell = Nothing
Set objWord = Nothing
Set objExcel = Nothing
Of course, as fate would have it, I cannot replicate the problem, so it works like normal. Does this solution seem reasonable? And a side question: How the heck do I get Word to stop complaining about Normal.dot (or get the script to handle it)? It's as if Word leaves itself open in the background after I have closed the GUI in some cases.
have you considered wrapping everything into an 'On Error Resume Next' statement so that your script ignores all the errors and continues to run as much as possible before calling the objWord.quit regardless of success or fail.
if you want more information on the correct use of 'On Error Resume Next' then go over to the msdn article on it!
Hope this helps!
Paul
I'm afraid that
WScript.Echo "..."
if it ever fires, is going to stall your script. Other than that, everything looks right. I'll play with it when I get home.
Edit: Word does hang out in the background, quite frequently. For one thing, if you use Outlook, and use Word as your Outlook editor, Word won't go away until Outlook is gone.
I'd agree with the use of "on error resume next".
If you really need to forcefully terminate Word, you can use WMI and the Win32_Process class to find and kill the process. This should be a last resort if everything else fails.
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
Set colProcess = objWMIService.ExecQuery("Select * from Win32_Process Where Name = 'winword.exe'")
For Each objProcess in colProcess
objProcess.Terminate()
Next
This was a modified example from:
http://www.computerperformance.co.uk/vbscript/wmi_process_stop.htm
Also, make sure all your references to the Word automation object are closed and/or set to nothing before you terminate the process.
The most reliable way to terminate all ActiveX instances, clean up garbage, and release resources is to put the code for that purpose into Sub Class_Terminate() of a dummy class, created instance of the class allows to handle script quit event.
Option Explicit
Dim objBeforeQuitHandler, objWord
' create a dummy class instance
Set objBeforeQuitHandler = New clsBeforeQuitHandler
' create word app instance
Set objWord = CreateObject("Word.Application")
objWord.Visible = True
objWord.Documents.Add.ActiveWindow.Selection.TypeText "80040000 error was raised. About to terminate the script." & vbCrLf & "Word will be quitted without saving before script termination just you close popped up error message."
' your code here...
' raise an error
Err.Raise vbObjectError
Class clsBeforeQuitHandler
' dummy class for wrapping script quit event handler
Private Sub Class_Terminate()
Dim objDoc
On Error Resume Next ' to prevent errors in case of unexpected word app termination
If TypeName(objWord) <> "Object" Then ' word app has not been closed yet
objWord.DisplayAlerts = False
For Each objDoc In objWord.Documents
objDoc.Saved = True ' to prevent save as dialog popping up
objDoc.Close
Next
objWord.Quit
End If
End Sub
End Class
firts excuse me for my English it`s super Freak. Sorry
I have a big problem , i need finish my applicatión in VB6.0 for a test in my High Schooll and i can`t find the solution, My app open a FFmpeg.EXE file which open a cmd window Prompt and start a trascoding process, i need link the last line generated into the Prompt of the CMD window (Or top Bottom) , in this line exists Values what change , in this trascoding process the result are bit Rates , which fluctuates acording to others var.
The idea it´s what into the form of my app i can read this line in real time to bulid a progress bar (File Size/Bitrate average)=time to process.
Can you help me. Thanks for the answer....
Put a reference to Windows Scripting Host Object Model and try this snippet
Option Explicit
Private Sub Command1_Click()
Dim oExec As WshExec
Dim sRow As String
With New WshShell
Set oExec = .Exec("tasklist.exe")
End With
Do While oExec.Status = WshRunning
sRow = oExec.StdOut.ReadLine
If InStr(1, sRow, "vb6.exe", vbTextCompare) > 0 Then
MsgBox sRow, vbExclamation
End If
Loop
End Sub
Basicly try executing FFmpeg.EXE and ReadLine until you find some key text.
Send the output to a textfile then read this textfile.
Should look something like this:
ping >e:\test.txt
Where ping is the FFmpge.EXE and e:\test.txt the output textfile
rdkleine
I read your answer and this is great work very good , only that it shows in the log a death value "text", and i need the value of fluctuates bitrates of conversion , which changes in real time in the prompt of the cmd window. i'm trying now with the source code of wqw , i'm working in there.
Thak's for your answer..