对于基于模板的文档,Word VBA事件仅触发一次 [英] Word VBA events only fire once for documents based on a template

查看:213
本文介绍了对于基于模板的文档,Word VBA事件仅触发一次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个启用了宏的模板,该模板带有一个事件侦听器,用于侦听内容控件退出事件.这个想法是,当编辑文档标题页上的标题"或日期"内容控件时,我们会自动更新标题中的标题"或日期"内容控件,这样作者就不必输入两次相同的内容.

I have a macro enabled template with an event listener that listens for content control exit events. The idea is that when the "title" or "date" content controls on the title page of the document are edited, we automatically update the "title" and "date" content controls in the header so that the author doesn't have to enter the same content twice.

我的问题是,当我基于模板打开一个新文档时(右键单击模板=>新建,或双击它),这些事件仅在退出内容控件的第一个实例时触发.我在抄送内部单击,在抄送外部单击,得到一个MsgBox,指示我的事件已触发.然后,我第二次尝试:在CC内单击,在CC外单击,然后获取MsgBox.

My problem is that, when I open a new document based on my template (right click template => new, or just double click it), these events only fire for the very first instance of a content control being exited. I click inside the CC, click outside the CC, get a MsgBox indicating that my event has fired. I then try that a second time: click inside the CC, click outside the CC and do not get a MsgBox.

事件处理程序类中的代码:

Code from my event handler class:

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事件,或者正在忽略它们.

I've checked and found that my event handler object is still defined (not "Nothing") in my NewMacros, it's just that it isn't getting ContentControlOnExit events, or is ignoring them.

如果我更改了上面的代码,以至于我实际上并未对事件主体内的内容控件执行任何操作,则问题已解决-我的理论是,在ContentControlOnExit事件内触摸任何内容控件都是触发递归ContentControlOnExit事件,并以某种方式引起问题.显然,如果不允许我在其中使用内容控件执行任何操作,则ContentControlOnExit事件将毫无用处.

If I change the above code such that I'm not actually doing anything with the content control inside the event body, the problem is fixed - my theory is that touching any sort of content control while inside the ContentControlOnExit event is triggering recursive ContentControlOnExit events and somehow causing a problem. Obviously a ContentControlOnExit event is pretty useless if I'm not allowed to do anything with content controls while inside it.

即如果我将代码更改为以下内容,则接收到ContentControlOnExit事件不会破坏"将来的ContentControlOnExit事件:

i.e. receiving a ContentControlOnExit event doesn't "break" future ContentControlOnExit events if I change my code to:

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,以防出现问题,但这没有帮助.我用于此的代码如下:

I've tried using an eventsEnabled boolean to try and guard against doc_ContentControlOnExit being called recursively in case that's the problem, but it didn't help. The code I used for that was like:

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中似乎没有该属性.

Excel has an Application.EnableEvents property, but this doesn't seem to be present in Word.

有趣的是,在编辑模板本身时,它们都可以正常工作,但不适用于基于该模板的文档.编辑模板时,每次退出内容控件时都会得到一个ContentControlOnExit事件,并且我的所有代码都可以正常工作.

The interesting thing is that this all works fine when editing the template itself, just not for documents based on that template. When editing the template, I get a ContentControlOnExit event every time I exit a content control, and all of my code works fine.

如果有帮助,我正在Windows 7 Professional 64位上使用Word 2010(Office Professional Plus).我也已经确认在Word 2007下也会发生同样的问题.

If it helps, I'm using Word 2010 (Office Professional Plus) on Windows 7 Professional 64 bit. I've also confirmed that the same problem occurs under Word 2007.

修改:

我刚刚尝试在NewMacros中设置事件处理程序对象以调用"ReincarnateEventHandler",这又将原始事件处理程序对象设置为Nothing,然后实例化了一个新的事件处理程序.这导致事件处理程序无限循环处理第一个事件,然后设置一个新的事件处理程序,然后再处理相同(原始)事件.使用Application.OnTime将轮回延迟1秒修复了无限循环,但未解决原始问题—即删除第一个事件处理程序,然后实例化一个新的事件处理程序不会让我在第一个事件后捕获后续事件.

I just tried setting the event handler object to call "ReincarnateEventHandler" in NewMacros, which in turn set the original event handler object to Nothing and then instantiated a new event handler. This resulted in an infinite loop of event handlers handling the first event and then setting up a new event handler which then handled the same (original) event. Using Application.OnTime to delay the reincarnation by 1 sec fixed the infinite loop, but didn't fix the original problem — i.e. dropping my first event handler and then instantiating a new event handler doesn't let me catch subsequent events after the first event.

推荐答案

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

It's a quick fix. Change ThisDocument to ActiveDocument in your SetUp routine. As it is, ThisDocument refers to the template itself. ActiveDocument is for the one created from AutoNew. So it should read Set eventHandler.doc = ActiveDocument.

它不会干扰未使用"so_template.dotm"创建的其他文档,因为从该模板创建的文档的.AttachedTemplate为"so_template.dotm",并且AutoNew(如果存在)将对其进行控制

It won't interfere with other documents not created with "so_template.dotm" as the ones created from that template will have an .AttachedTemplate of "so_template.dotm" and the AutoNew, if present, will control them.

这篇关于对于基于模板的文档,Word VBA事件仅触发一次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆