• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 2149
  • Last Modified:

How to programmatically add a macro to a Word document

I need to know how to programmatically add a macro to a Word document. The macro is custom-generated for each document. Therefore, I cannot ask a user to manually add and run the macro each time a document is opened.

The macro needs to start upon document opening and will basically perform final processing on the document itself.

Consequently, I think I need, from another programming language, a way to merge a macro to an existing word document. Maybe another way would be to tell word to run an external macro, stored on the disk.

Is that feasible?
1 Solution

     You can use VBA from ANY of the Office Applications, and control any other application, as long as you reference the correct Object Library.  Since the Macro needs to run on each document that the user is working in, but you don't want the user to have to create it, I would suggest creating the macro somewhere else, like MS Access, where you could have it hooked to a command button on a form.  When the user clicks on the command button, it could reach out and process the word document.  You could use a text box (where the user filled in their path and filename) to tell it what document to open and process.

Here is some sample code to do something in Word from Access:
Private Sub cmdFixWordDoc_Click()
' this procedure uses Word Objects, and requires a reference to
' the Microsoft Word Object Library, under Tools, References
' from any module
On Error GoTo cmdFixWordDoc_Error
' variables for our User Input
Dim strPath As String

strPath = Me!txtPath

' Word Object Variables
Dim wdApp As Word.Application
Dim wdDoc As Word.Document
Dim r As Word.Range

Set wdApp = New Word.Application
  With wdApp
    Set wdDoc = .Documents.Open strPath
    With wdDoc


      .SaveAs "C:\Practice\MyFinishedBillOfSale.doc"
        ' the following line will automatically send your results to the printer
        ' comment out if not needed
    End With
    ' this would let you see the document.  Comment out if not needed
    .Visible = True
  End With
  ' this is for testing, comment out when done
' close object variables and release memory
Set wdDoc = Nothing
Set wdApp = Nothing

Exit Sub

MsgBox "There was an error processing your Document!  Error No: " & Err.Number & vbCrLf & Err.Description
Resume cmdFixWordDoc_Exit

End Sub

Hope this helps!

ClaudeMartelAuthor Commented:
I know I can automate Word from a lot of applications. I currently automate Word from a Delphi program. The problem is that performance is poor.

Typically, a Word macro will run 5 times faster than the equivalent automation program.

This is why I want my macro to reside in the Word document.
ClaudeMartel, Macros in Word can reside in documents and you can have them run upon immediately upon opening the document. We can give you more details on that if you want.

As for running an external macro, all macros in Word have to live in either a document or a template. So, for example, you could have a macro in a template in Word (say Normal or another global template) that then iterates through a series of documents to be named and performs certain processes on each of those documents.

Does that answer your question?
Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

ClaudeMartelAuthor Commented:
Well... my question being "How can I programmatically add a macro to a Word document?", I do not think I am getting an answer (By the way, I cannot be done is a valid answer)

But it can be done :)

I suppose you already created an instance of a Document object right? Very well, Document has a property VBProject that represents the VBA Project associated with the document. You just have to add VBComponents (aka modules) to it or edit the ones it already has. What would you prefer? You can look at the help for reference and post your doubts here or ask for some code snippets to help you. Just say which option you prefer.

As to making code run on opening the document you can trap the Open event of the document and perform the actions you want. On your document module just define the sub Document_Open like so:

Private Sub Document_Open()

End Sub

Hope this helps

What the heck, here's an example:

Sub NewDocWithCode()
    Dim doc As Document
    Set doc = Application.Documents.Add
    doc.VBProject.VBComponents("ThisDocument").CodeModule.AddFromString _
            "Sub Document_Open()" & vbLf & _
            "   MsgBox ""It works""" & vbLf & _
            "End Sub"
End Sub

If you prefer you can also import a whole module from a file. Like so:

    doc.VBProject.VBComponents.Import FileName

Hope this helps

ClaudeMartelAuthor Commented:
Thanks a lot.

I was just about to figure it out myself. The sample (Delphi code) I was testing is:

  W := TWordApplication.Create(self);

  Macro := W.ActiveDocument.VBProject.VBComponents.Add(1);
  Macro.CodeModule.AddFromString('Sub ShowHello()' + #13 + 'MsgBox("Hello")' + #13 + 'End Sub');

Glad to help. Thanks for the points :)
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

Tackle projects and never again get stuck behind a technical roadblock.
Join Now