Word VBA事件仅针对基于模板的文档触发一次

时间:2011-03-11 03:34:27

标签: vba ms-word word-vba

我有一个启用宏的模板,其中包含一个侦听内容控件退出事件的事件侦听器。我们的想法是,当编辑文档标题页上的“标题”或“日期”内容控件时,我们会自动更新标题中的“标题”和“日期”内容控件,以便作者不必两次输入相同的内容。

我的问题是,当我根据我的模板打开一个新文档时(右键单击template => new,或者只是双击它),这些事件仅针对退出的内容控件的第一个实例触发。我在CC内部单击,在CC外部单击,获取一个MsgBox,指示我的事件已被触发。然后我再次尝试:在CC内部单击,在CC外单击并执行获取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中仍然定义了我的事件处理程序对象(而不是“Nothing”),只是它没有得到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个事件,并且我的所有代码都能正常运行。

如果有帮助,我在Windows 7 Professional 64位上使用Word 2010(Office Professional Plus)。我还确认在Word 2007下会出现同样的问题。

修改

我刚刚尝试将事件处理程序对象设置为在NewMacros中调用“ReincarnateEventHandler”,然后将原始事件处理程序对象设置为Nothing,然后实例化新的事件处理程序。这导致了无限循环的事件处理程序处理第一个事件,然后设置一个新的事件处理程序,然后处理相同的(原始)事件。使用Application.OnTime延迟转世1秒修复了无限循环,但没有解决原始问题 - 即丢弃我的第一个事件处理程序然后实例化一个新的事件处理程序不让我在第一个事件之后捕获后续事件

1 个答案:

答案 0 :(得分:2)

这是一个快速解决方案。在ThisDocument例程中将ActiveDocument更改为SetUp。实际上,ThisDocument指的是模板本身。 ActiveDocument适用于AutoNew创建的Set eventHandler.doc = ActiveDocument。所以它应该是.AttachedTemplate

它不会干扰未使用“so_template.dotm”创建的其他文档,因为从该模板创建的文档将具有AutoNew“so_template.dotm”和{{1}}(如果存在) ,将控制他们。

相关问题