Search code examples
vbatemplateseventsms-wordword-contentcontrol

Word Global Template VBA: ContentControlOnExit event not firing when placed in the Startup folder


The code below is placed in the ThisDocument word object in a .dotm template file. When the file is opened directly, the event below fires as intended, each time a content control in the active document is exited. However, when the template is placed in the Startup folder and opens automatically, the event does not fire.

Any ideas as to how this should be modified to work as intended from the Startup folder?

Private Sub Document_ContentControlOnExit(ByVal ContentControl As _
ContentControl, Cancel As Boolean)
    MsgBox ("Fired")
End Sub

Solution

  • I have already faced this issue in the past as well. You won't get it to work like that, it will only fire the event for the ContentControlOnExit event on your loaded "*.dotm"-file itself.

    To react to changes occuring outside of your macro-document, you have to use a rather complicated construct, which I will briefly explain to you.

    You have to create a Class clsDocument in which you have a variable Public WithEvents p_Document as Word.Document. Inside of your class, you then listen to the Event ContentControlOnExit of your p_Document and put your code in there (in your case MsgBox ("Fired").

    Next, you have to listen to the general events "AutoExec" and "AutoOpen" as well as the "Application_DocumentChange". In all of those events you basically just set the global variable p_Document to the value of either the document passed to the event or (if there is no document passed to the eventhandler) the active document. Since all of those event-reactions do more or less the same thing, create a new procedure in a module of your macro like that:

    Public g_clsWordDocument                     As clsDocument
    
    Public Sub SetUpDocumentEvents(Optional ByRef a_Document As Word.Document = Nothing)
    
    If Application.Documents.Count > 0 Then
       If a_Document Is Nothing Then Set a_Document = ActiveDocument
       Set g_clsDocument = New clsDocument
       Set g_clsDocument.p_Document = a_Document
    End If
    
    End Sub
    

    Then, create the following procedures in your ThisDocument of your macro-file.

    Option Explicit
    
    Private g_clsWordApplication            As clsApplication
    
    
    Public Sub AutoExec()
    
    Set g_clsWordApplication = New clsApplication
    Set g_clsWordApplication.WordApplication = Word.Application
    
    Call modYourModule.SetUpDocumentEvents
    
    End Sub
    
    Private Sub Document_New()
       Call modYourModule.SetUpDocumentEvents
    End Sub
    
    Private Sub Document_Open()
       Call modYourModule.SetUpDocumentEvents
    End Sub
    
    Public Sub AutoOpen()
       Call modYourModule.SetUpDocumentEvents
    End Sub
    

    Like that, you can catch the document events. As you see in the AutoExec function, it is the same for the application object, just create a new clsAplication that with an WithEvents WordApplication as Word.Application and you can react to the events. All of this code goes into your dotm-file, so the global template file.

    In this way, you can react to the event that you wanted to. Although I haven't found another way to solve this problem, I am still not satisfied with how it has to be implemented. If there is another option to solve your problem, I strongly suggest to try and do it another way.