locked
Add macro to normal.dotm through VBA RRS feed

  • Question

  • Hi

    I need to add a macro to all our users normal.dotm. I have created a macro that opens every normal.dotm file but how do I add the macro through VBA?

    Lasse


    /Lasse
    Tuesday, October 26, 2010 1:26 PM

Answers

  • Sorry, I didn't connect this question to your earlier thread (it might have been better just to continue that thread). Yes, this is a special case.

    Probably the most difficult part of this is that you must get each user to allow programmatic access to the Normal.dotm macro storage on that computer. This must be done manually before running your "installer" macro; there is -- by design -- no way to do this automatically. It's a security measure to prevent a malicious installer from creating a malicious macro. To to this, each user must:

    - Open the Word Options dialog.
    - Click the Trust Center tab and then click the Trust Center Settings button.
    - Check the box for "Trust access to the VBA project object model".
    - Click OK in both open dialogs.

    After your installer has run, the user should return to the Trust Center and uncheck the box.

    To create the AutoOpen macro in a form that can be installed:

    - First write the AutoOpen macro in some template (your own Normal.dotm or any other template), as the only macro in a standard module. Name the module as something that won't occur elsewhere, maybe including your initials or a random number.
    - Right-click that module and export it to a file with a .bas extension. (It's really just a text file with a specific format.) The name of the module will be suggested as the name of the file, but you can choose anything you want -- the name of the module is stored inside the .bas file, and that will be used to create a new module in Normal.dotm.
    - Decide what path you're going to use on the target computer, where you'll tell the user to save the template containing your installer plus the .bas file. Let's assume it's %appdata%\Microsoft\Templates which is the default location for the User Templates path.

    Now to create the installer:

    - Make a template just to contain the installer, and create a standard module in it.
    - In the VBA editor, click Tools > References and check the box for "Microsoft Visual Basic for Applications Extensibility". That will make available the methods and properties needed to modify the macros in Normal.dotm (or anywhere else).

    - Add code like this, modifying the path and filename in the Import statement as necessary:

    Sub ImportModuleToNormal()
      Dim vbp As VBProject
      Set vbp = NormalTemplate.VBProject
      vbp.VBComponents.Import _
        Options.DefaultFilePath(wdUserTemplatesPath) _
        & "autoopen.bas"
    End Sub

    - Create a Quick Access Toolbar button to run the macro.
    - Write instructions in the body of the template to tell the user how to set the Trust Center setting as described above, click the button to run the macro, and then unset the Trust Center setting.
    - Package the template and the .bas file into a zip file, or possibly a self-extracting zip executable. Instruct users to unzip the file to %appdata%\Microsoft\Templates, start Word, open the template, and follow the instructions inside it.

    It is possible to use the Extensibility object model to write a macro that will "write" code into a module in Normal.dotm, but the import mechanism is much simpler (assuming the AutoOpen code doesn't need to be modified for each user).


    Jay Freedman
    MS Word MVP  FAQ: http://word.mvps.org
    • Marked as answer by Jennifer Zhan Monday, November 1, 2010 2:50 AM
    Tuesday, October 26, 2010 2:52 PM
  • Whilst I have absolute faith in Jay's instructions, I wouldn't do it that way at all.
     
    I would create a template in the Startup folder with Application DocumentOpen event code.
     
    In a new template, insert a new Class Module, and in it add code like this:
     
        Option Explicit
     
        Private WithEvents WordApp As Word.Application
     
        Private Sub Class_Initialize()
            Set WordApp = Application
        End Sub
     
        Private Sub WordApp_DocumentOpen(ByVal Doc As Document)
            ' Your code will go here
        End Sub
     
    Then, in the THisDocument module, put code like this:
     
        Option Explicit
     
        Dim EventModule As Class1
     
        Sub AutoExec()
            Set EventModule = New Class1
        End Sub
    Save it as a macro-enabled template in the Word StartUp folder.

    Enjoy,
    Tony
    www.WordArticles.com
    • Marked as answer by Jennifer Zhan Monday, November 1, 2010 2:50 AM
    Tuesday, October 26, 2010 3:55 PM

All replies

  • Please do not tinker with other users' Normal templates. It's ultimately a very bad idea. Instead, put your macros into a separate template that you distribute (manually or automatically) to store in each user's Startup folder, as described at
    http://www.word.mvps.org/FAQs/MacrosVBA/DistributeMacros.htm


    Jay Freedman
    MS Word MVP  FAQ: http://word.mvps.org
    Tuesday, October 26, 2010 1:38 PM
  • I know that it's a very bad idea.

    I need to add a AutoOpen macro and I have been doing some tests, and I can only get it to run if it's located in normal.dotm. I have tried creating a dotm template with the AutoOpen macro and adding the file to the Startup folder, but the AutoOpen macro is never run.


    /Lasse
    Tuesday, October 26, 2010 1:45 PM
  • Sorry, I didn't connect this question to your earlier thread (it might have been better just to continue that thread). Yes, this is a special case.

    Probably the most difficult part of this is that you must get each user to allow programmatic access to the Normal.dotm macro storage on that computer. This must be done manually before running your "installer" macro; there is -- by design -- no way to do this automatically. It's a security measure to prevent a malicious installer from creating a malicious macro. To to this, each user must:

    - Open the Word Options dialog.
    - Click the Trust Center tab and then click the Trust Center Settings button.
    - Check the box for "Trust access to the VBA project object model".
    - Click OK in both open dialogs.

    After your installer has run, the user should return to the Trust Center and uncheck the box.

    To create the AutoOpen macro in a form that can be installed:

    - First write the AutoOpen macro in some template (your own Normal.dotm or any other template), as the only macro in a standard module. Name the module as something that won't occur elsewhere, maybe including your initials or a random number.
    - Right-click that module and export it to a file with a .bas extension. (It's really just a text file with a specific format.) The name of the module will be suggested as the name of the file, but you can choose anything you want -- the name of the module is stored inside the .bas file, and that will be used to create a new module in Normal.dotm.
    - Decide what path you're going to use on the target computer, where you'll tell the user to save the template containing your installer plus the .bas file. Let's assume it's %appdata%\Microsoft\Templates which is the default location for the User Templates path.

    Now to create the installer:

    - Make a template just to contain the installer, and create a standard module in it.
    - In the VBA editor, click Tools > References and check the box for "Microsoft Visual Basic for Applications Extensibility". That will make available the methods and properties needed to modify the macros in Normal.dotm (or anywhere else).

    - Add code like this, modifying the path and filename in the Import statement as necessary:

    Sub ImportModuleToNormal()
      Dim vbp As VBProject
      Set vbp = NormalTemplate.VBProject
      vbp.VBComponents.Import _
        Options.DefaultFilePath(wdUserTemplatesPath) _
        & "autoopen.bas"
    End Sub

    - Create a Quick Access Toolbar button to run the macro.
    - Write instructions in the body of the template to tell the user how to set the Trust Center setting as described above, click the button to run the macro, and then unset the Trust Center setting.
    - Package the template and the .bas file into a zip file, or possibly a self-extracting zip executable. Instruct users to unzip the file to %appdata%\Microsoft\Templates, start Word, open the template, and follow the instructions inside it.

    It is possible to use the Extensibility object model to write a macro that will "write" code into a module in Normal.dotm, but the import mechanism is much simpler (assuming the AutoOpen code doesn't need to be modified for each user).


    Jay Freedman
    MS Word MVP  FAQ: http://word.mvps.org
    • Marked as answer by Jennifer Zhan Monday, November 1, 2010 2:50 AM
    Tuesday, October 26, 2010 2:52 PM
  • Whilst I have absolute faith in Jay's instructions, I wouldn't do it that way at all.
     
    I would create a template in the Startup folder with Application DocumentOpen event code.
     
    In a new template, insert a new Class Module, and in it add code like this:
     
        Option Explicit
     
        Private WithEvents WordApp As Word.Application
     
        Private Sub Class_Initialize()
            Set WordApp = Application
        End Sub
     
        Private Sub WordApp_DocumentOpen(ByVal Doc As Document)
            ' Your code will go here
        End Sub
     
    Then, in the THisDocument module, put code like this:
     
        Option Explicit
     
        Dim EventModule As Class1
     
        Sub AutoExec()
            Set EventModule = New Class1
        End Sub
    Save it as a macro-enabled template in the Word StartUp folder.

    Enjoy,
    Tony
    www.WordArticles.com
    • Marked as answer by Jennifer Zhan Monday, November 1, 2010 2:50 AM
    Tuesday, October 26, 2010 3:55 PM
  • Hi Jay and Tony

    Thanks for taking the time to answer. I am really not interested in doing this, but our management has decided to change our font and font size, a lot of our users complain about it and say they can't read it. So I am just trying to be nice and change their default zoom to 130% instead of 100%.

    I will take a look at both your replies later. Thanks again.

    Lasse


    /Lasse
    Wednesday, October 27, 2010 5:51 AM