2
votes

I have a Normal.dotm file that contains an AutoNew macro. This macro is automatically executed each time a new document is created using any other template.

Is there any way I can prevent this automatic behavior for a specific template? I have a Word VSTO add-in running, so I can hook into Word's events, but so far I havn't found a way to prevent this.

I do know that I can prevent macro execution when using templates programmatically, for example like this:

' Disable auto-macros before opening document
wordApplication.WordBasic.DisableAutoMacros(1)

' Open document
newWordDocument = wordApplication.Documents.Open(template.FullName, ConfirmConversions:=False, [ReadOnly]:=True, AddToRecentFiles:=False, Revert:=True)

' Re-enable auto-macros
wordApplication.WordBasic.DisableAutoMacros(0)

But this solution doesn't work when the user uses a Word template from Windows explorer or the Open-dialog in Word, since in those cases I can't execute code before it's too late already.

Or can I? I hope someone has a trick for me :-)

-

Edit: While trying different solutions, I discovered something that might help others in similar situations, though unfortunately it doesn't help me. It seems that if a template contains a module containing an AutoNew (or AutoOpen for that matter), that local macro is executed instead of the one in Normal.dotm.

Example:

Normal.dotm contains the following macro:

Sub AutoNew()
    MsgBox "Normal.dotm"
End Sub

Test.dotm contains the following macro:

Sub AutoNew()
    MsgBox "Test.dotm"
End Sub

When executing Test.dotm the message "Test.dotm" is displayed, while the message "Normal.dotm" is not displayed.
If the AutoNew macro is removed from the Test.dotm template, the message "Normal.dotm" is indeed displayed.

So it is possible to easily override the auto-macros.
The local versions of AutoNew and AutoOpen can even be empty subs that do nothing. It still works.

This is not possible in my case though, since the template I use is generated by code, and cannot contain macros (because adding macros to templates programmatically requires the user to manually activate the option "Trust access to the VBA project object model", and that's something I cannot ask my customers to do for all users. It's also a security risk.)

2
Note: I can't edit the mentioned AutoNew macro in Normal.dotm in this case.Gertsen
If you can't edit and you must use the user's instance of Word then, no, I don't think there's any way around this. What does the macro do that's a problem?Cindy Meister
Okay, I was hoping there was some event before the macro is executed, so I could prevent it. Part of the problem is that this macro modifies the page header and footer, making the documents generated by my template look very wrong.Gertsen
@Gertsen, is there some reason your code cannot delete the offending header and footer and replace it with one that's acceptable? You could also change the AttachedTemplate to make future housekeeping easier. Apologies if you understood this possibility and asked your question simply to make your code more efficient, but blowing away content and rebuilding it is often the only course of action when dealing with the Word object model.joeschwa
Gertsen, given the additional information you posted there may be a way since your project is .NET and not VBA. You could create the template - or at least attach the macro part of it - using the Open XML SDK. That does not run in the user environment, so the user settings won't affect it. If this is an option I can write out more details in an "Answer"...Cindy Meister

2 Answers

1
votes

Within the AutoNew macro you can check the AttachedTemplate property. Only if it is a template where you want to apply the cleaning you can execute the respective macros.

Sub AutoNew()

    If ActiveDocument.AttachedTemplate <> "Normal.dotm" Then
        Exit Sub
    End If

    ' rest of the macro

End Sub

If you don't control the Normal.dotm you can put an empty AutoNew macro in your own templates. As Word only executes the auto macro in the closest context, the macro in the Normal.dotm file would not be executed.

If you don't control the other templates either, you can tell your users to hold down the SHIFT key while creating a document. This prevents the execution of the auto macro.

Probably it is best, however, if you ask the owner of the other system to find another solution that does not rely on polluting the Normal.dotm file.

1
votes

Based on the workaround described in the "Edit" part of the question - providing a template with "empty" Auto-macros - it's possible to use the Open XML SDK to create a template and add the VBA project to it in order to provide this functionality. This approach avoids the user needing to allow access to the VBA project on his installation. The only "macro security" that could be triggered is that for not allowing macros to run. But since the client uses macros, anyway, this should not be a major obstacle.

The simplest method is to create as much of the basic template as possible in the Word UI and use this as a starting point.

Since you're unfamiliar with the Open XML SDK, the next step would be to create one (or more) templates in the Word UI using the basic template as the starting point, saving under a different file name.

You can then use Open XML SDK Productivity Tool to see the code required to generate any one of these files, as well as, using the Compare tool, the code for converting the basic template to the derived version. This should give you a decent start with the SDK and it's object model. Once you get a feel for how the Open XML SDK works, if you're familiar with Word's object model, using that provided by the SDK is relatively straight-forward as an effort was made to make it correspond as closely as possible to the "COM" object model.

The VBA project can be added later, but you can also include it in the basic template. That would be the simplest approach.

Include this "starting point" basic template as part of your solution, installing it as part of the solution.