1
votes

I have one .xlsm workbook and one .docx document open.
The code is Excel VBA.

I want to display the name of the Word file in MsgBox.
How do I reference the Word document in Excel VBA?

I found code here https://excel-macro.tutorialhorizon.com/vba-excel-get-the-instance-of-already-opened-word-document/

After I've rewritten it, it is giving me this error:

activex component can't create object 429.

Sub Get_Opened_Doc_Instance()
    'Variables declaration
    'Dim WordApp As Object
    Dim WordApp As Word.Application
    'Dim WordDoc As Object
    Dim WordDoc As Word.Document
    'Dim Text As String             
    'this variable is here because later I'm going to search this file.
    Set WordApp = GetObject(, Word.Application)
    'Set WordDoc = GetObject(, Word.Document)
    WordApp.Visible = True          'this line or the next one returns the error
                                    'activex component can't create object 429
    MsgBox WordApp.ActiveDocument.Name
End Sub

My Excel VBA editor tools->references screenshot.
enter image description here

2
Word.Application must be "Word.Application" in order to create the object of the open Word session... No need of any reference. Except the case you need the intellisense to offer you suggestion about the object properties when you use it.FaneDuru

2 Answers

2
votes

GetObject and CreateObject both accept a String parameter representing a ProgID - that's a literal string value present in the Windows Registry, associating a class with a specific type library.

Hence, you want that argument to be enclosed in double quotes, which delimit a string literal:

Set WordApp = GetObject(, "Word.Application")

The reason you're getting an error is because there's an implicit default member call in Word.Application that's returning the value of Word.Application.Name, i.e. the string value "Microsoft Word", and "Microsoft Word" is not a valid, registered ProgID.

Having the reference to the Word object model in your project means you can do this:

Dim WordApp As Word.Application
Set WordApp = GetObject(, "Word.Application")

And then every member call made against this WordApp object variable will be compile-time validated (that's what early-bound means). It also means you can do this:

Dim WordApp As Word.Application
Set WordApp = New Word.Application

Instead of this:

Dim WordApp As Word.Application
Set WordApp = CreateObject("Word.Application")

With the reference to the Word object library, all wdXxxxx constants are defined and usable. The counterpart of that, is that your users must have the exact same version of the referenced library on their machines.

If your users are on different versions of Word / Office than you, consider late binding instead.

You'll lose the ability to use wdXxxxx constants directly (you'll need to use their underlying values, or define them as Const identifiers or Enum members yourself). You'll also lose compile-time validation, intellisense/autocompletion, the ability to New up any class from the Word library, and Option Explicit will not be able to protect you from a typo in any of the late-bound member calls you make (expect run-time error 438 if you do something wrong), but you'll also shed the dependency on a specific version of Word/Office.

To use late binding, you need to declare things As Object, like this:

Dim WordApp As Object
Set WordApp = GetObject(, "Word.Application")

Note that this cannot work, even with the double quotes:

'Set WordDoc = GetObject(, "Word.Document")

Because you can't create a Word.Document - only Word can do that, for the same reason you can't create an Excel.Worksheet, only Excel can do that. To create a Word.Document, you need to invoke a member of WordApp that will create a new document (and return a reference to it that you can capture in a local variable):

Dim WordDoc As Object 'early-bound: As Word.Document
'Set WordDoc = WordApp.ActiveDocument
Set WordDoc = WordApp.Documents.Add

MsgBox WordDoc.Name
1
votes

You don't need the first two lines in your above macro - you can obtain what you're looking for with just these 3 lines:

Set objWord = GetObject(, "Word.Application")

objWord.Visible = True

MsgBox objWord.ActiveDocument.Name