1

I want to know whether WINWORD.EXE is running when I open a Word document embedded in Excel. If it is not already running then I want to use objWord.Quit. It's possible the user is working in Word and I don't want to interfere with that, so in that case objWord.Quit should not be executed.

I have this -sniped- code:

'Variable declaration
Dim objWord As Word.Application
Dim objDoc As Word.Document

objWord is being instantiated like this:

ActiveSheet.OLEObjects(P).Activate 
Set objWord = GetObject(, "Word.Application") 

At end of the procedure:

Set objDoc = Nothing
Set objWord = Nothing

But the WINWORD.EXE instance remains running.

How can I determine whether WINWORD.EXE Is running when the procedure begins?

Cindy Meister
  • 25,071
  • 21
  • 34
  • 43
Tuberose
  • 434
  • 6
  • 24

2 Answers2

1

To have an instance of Word that you can be sure the user is not working in, use the New keyword. Unlike GetObject this will force a new instance to start. Then you can use objWord.Quit.

Set objWord = New Word.Application

However: Rather than starting an instance of Word, or using an existing instance, it seems from your problem description it would make more sense to work with the embedded document object, directly. Here's some sample code:

Sub Test()
    Dim ws As Excel.Worksheet
    Dim currCel As Excel.Range
    Dim oDoc As OLEObject

    'to restore the current selection after activating the Word document
    Set currCel = Application.Selection
    Set ws = ActiveWorkbook.Worksheets("Sheet1")
    'Note: I named the embedded document, using code
    'If you don't want to do that, you need the index value
    'as you have in your code: OLEObjects(P)
    Set oDoc = ws.OLEObjects("WordDoc")
    WorkWithWordDoc oDoc, currCel
    Set oDoc = Nothing
End Sub

Sub WorkWithWordDoc(oDoc As OLEObject, selRange As Excel.Range)
    Dim doc As Word.Document
    Dim wasActivated As Boolean
    Dim cc As Word.ContentControl

    'On first opening the Workbook
    'the OLE interface of the OLEObject
    'isn't accessible, so you need to activate 
    'it if the error occurs
    wasActivated = True
    On Error Resume Next
    Set doc = oDoc.Object
    If Err.Number = 1004 Then
        Excel.Application.ScreenUpdating = False
        oDoc.Activate
        wasActivated = False
        Set doc = oDoc.Object
        Excel.Application.ScreenUpdating = True
    End If
    On Error GoTo 0

    'Code to work with the document comes here

    'Clean up
    If Not wasActivated Then
        'Deactivate the document
        selRange.Select
    End If
    Set doc = Nothing
End Sub
Cindy Meister
  • 25,071
  • 21
  • 34
  • 43
  • I need after ending the procedure The `WINWORD.EXE` been `Quit` if that was not opened before calling the procedure else the `WINWORD.EXE` remain opened, if it was running before procedure calls. – Tuberose Jan 22 '18 at 10:54
  • 2
    If you start a NEW instance then you can QUIT because you can be sure the user has no documents open in that instance of Word. You don't need to know whether the user is working in Word. A NEW instance will be completely independent! If you open the embedded document directly, as the second code sample shows, then Word will end automatically when you re-select the original selection. Again, the user will have nothing open in that instance of Word. It's immaterial whether the user is aleady working in Word - you won't be sharing Word with the user at all using either of the above approaches. – Cindy Meister Jan 22 '18 at 11:07
  • Thank you so much. – Tuberose Jan 27 '18 at 10:09
  • I need using `GetObject` because `OLEObject.Active` do visible the OLE Word application. I need program act do quietly invisible as much as possible. So I will made `ObjWord.Visible=False` after `Set objWord = GetObject(, "Word.Application")` – Tuberose Jan 27 '18 at 12:31
  • Yeah, I finally tracked what you're doing - sorry it took so long! Just posted my answer to the new topic. – Cindy Meister Jan 27 '18 at 13:24
  • Is it possible using `GetObject` because of above reason, and the `ObjWord` been isolated instance which by perform `ObjWord.Quit` the other Word documents been safe. (Pointing this question: [stackoverflow.com/q/](https://stackoverflow.com/q/48475673/9075944) – Tuberose Jan 27 '18 at 13:44
  • @tuberose I'm sorry, I don't understand what you're asking. Are you asking whether you can use SaveAs on any documents opened in the GetObject instance of Word? – Cindy Meister Jan 27 '18 at 13:50
  • I mean the problem of New instance is I cant perform the Activated OLEObject **invisible**. I want the this code working quietly invisible. So I Using `GetObject` to perform `ObjWord.Invisible = True`. **Here** a problem happens. The `ObjWord` which assigned with `GetObject` involves all of other Word documents that are opened with user. Now when Perform `ObjWord.Quit 0`, the Word documents are not opening with the code will closed! – Tuberose Jan 27 '18 at 14:28
  • CindyMeister, I asked a new version of my question.[stackoverflow.com/questions/](https://stackoverflow.com/questions/48495929/add-specific-document-to-specific-word-application) – Tuberose Jan 29 '18 at 06:59
  • I did try the `WorkWithWordDoc` and `Test` (your answer), but the `Clean up` section not `Deactivate` the document and the activated OLEObject Document remains opened. I need the WINWORD.EXE been terminated after the `Test` procedure have ends (If there is no another Word documents are opened). Regards – Tuberose Jan 29 '18 at 19:36
  • CindyMeister, Unfortunately after running the `Test` procedure (above answer) the activated OLE object Document not deactivated and the WINWORD.EXE continued running. – Tuberose Jan 30 '18 at 05:03
  • CindyMeister, What is the use of `Dim cc As Word.ContentControl` in above? – Tuberose Jan 30 '18 at 06:11
0

Using Word.Documents.Count:

Function IsWinwordRunning() As Boolean

    Dim DCount As Integer
    Dim IsWinwordRunning As Boolean

    IsWinwordRunning = False

    On Error Resume Next
    DCount = Word.Documents.Count
    If Err = 429 Then DCount = 0

    If DCount > 0 Then IsWinwordRunning = True

End Function
Tuberose
  • 434
  • 6
  • 24