События Word VBA запускаются только один раз для документов на основе шаблона - PullRequest
1 голос
/ 11 марта 2011

У меня есть шаблон с поддержкой макросов с прослушивателем событий, который прослушивает события выхода управления контентом.Идея заключается в том, что при редактировании элементов управления «title» или «date» на титульном листе документа мы автоматически обновляем элементы управления «title» и «date» в заголовке, чтобы автору не приходилосьвведите один и тот же контент дважды.

Моя проблема в том, что когда я открываю новый документ на основе моего шаблона (щелкните правой кнопкой мыши шаблон => новый или просто дважды щелкните по нему), эти события запускаются только для самого первогоЭкземпляр управления контентом выходит.Я щелкаю внутри CC, нажимаю вне CC, получаю MsgBox, указывающий, что мое событие сработало.Затем я пробую это второй раз: щелкните внутри CC, щелкните вне CC и выполните not , чтобы получить MsgBox.

Код из моего класса обработчика событий:

Public WithEvents doc As Word.Document

Private Sub doc_ContentControlOnExit(ByVal ContentControl As ContentControl, Cancel As Boolean)
    MsgBox ContentControl.Range.Text    
End Sub

Я проверил и обнаружил, что мой объект-обработчик событий все еще определен (а не «Ничто») в моем NewMacros, просто он не получает ContentControlOnExit событий или игнорирует их.

Если я изменю приведенный выше код так, что я на самом деле ничего не делаю с элементом управления содержимым внутри тела события, проблема будет исправлена ​​- моя теория состоит в том, что касание любого вида элемента управления содержимым, когда внутри события ContentControlOnExit запускается рекурсивно ContentControlOnExit событий и как-то вызывающих проблему.Очевидно, что событие ContentControlOnExit довольно бесполезно, если мне не разрешено что-либо делать с элементами управления содержимым внутри него.

, т.е. получение события ContentControlOnExit не "нарушает" будущие события ContentControlOnExit, еслиЯ изменяю свой код на:

Public WithEvents doc As Word.Document

Private Sub doc_ContentControlOnExit(ByVal ContentControl As ContentControl, Cancel As Boolean)
    MsgBox "Content Control exit event"
End Sub

Я пытался использовать логическое значение eventsEnabled, чтобы попытаться предотвратить рекурсивный вызов doc_ContentControlOnExit на случай, если это проблема, но это не помогло.Код, который я использовал для этого, был такой:

Sub Class_Initialize()
    pEventsEnabled = True
End Sub

...

' in the doc_ContentControlOnExit sub:
If pEventsEnabled Then
    ' obvious race condition...
    pEventsEnabled = False
    ' Fiddle around with some content controls
    pEventsEnabled = True
End If

В Excel есть свойство Application.EnableEvents, но его, похоже, нет в Word.

Интересно то, что все это прекрасно работает при редактировании самого шаблона , только не для документов, основанных на этом шаблоне.При редактировании шаблона я получаю событие ContentControlOnExit каждый раз, когда выхожу из элемента управления контентом, и весь мой код работает нормально.

Если это помогает, я использую Word 2010 (Office профессиональный плюс) наWindows 7 Профессиональная 64 битная.Я также подтвердил, что та же проблема возникает в Word 2007.

edit :

Я только что попытался настроить объект обработчика событий для вызова "ReincarnateEventHandler" в NewMacros,который в свою очередь устанавливает исходный объект обработчика событий в Nothing, а затем создает экземпляр нового обработчика событий.Это привело к бесконечному циклу обработчиков событий, которые обрабатывают первое событие, а затем устанавливают новый обработчик событий, который затем обрабатывает то же (исходное) событие.Использование Application.OnTime для задержки реинкарнации на 1 секунду исправило бесконечный цикл, но не устранило исходную проблему - т.е. удаление моего первого обработчика событий и создание нового обработчика событий не позволяет мне перехватывать последующие события после первого события.

1 Ответ

2 голосов
/ 17 марта 2011

Это быстрое решение.Измените ThisDocument на ActiveDocument в вашей программе SetUp.Как таковой, ThisDocument относится к самому шаблону.ActiveDocument для того, что создано из AutoNew.Поэтому он должен читать Set eventHandler.doc = ActiveDocument.

. Он не будет мешать другим документам, не созданным с помощью «so_template.dotm», поскольку документы, созданные из этого шаблона, будут иметь .AttachedTemplate «so_template.dotm»AutoNew, если присутствует, будет управлять ими.

...