2

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.

Community
  • 1
  • 1
Adam
  • 433
  • 5
  • 11

4 Answers4

2

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

Community
  • 1
  • 1
Paul Harris
  • 5,769
  • 1
  • 25
  • 41
  • is this a standard practice method to do this, I have a longish script that works from a excel workbook. any error in the script that casues it to bomb out and it leaves the work book open. Can you have mutiply nested on error statments? – DevilWAH Jun 22 '11 at 14:57
  • having looked at that link actuly I tyhink I get it now :) cheers – DevilWAH Jun 22 '11 at 15:02
0

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
omegastripes
  • 12,351
  • 4
  • 45
  • 96
0

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.

Adrien
  • 3,130
  • 22
  • 17
0

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.

Chris Sears
  • 6,502
  • 5
  • 32
  • 35