PDA

View Full Version : Solved: Is there a way to Disable Events in Word with VBA?



rruckus
03-23-2011, 11:46 AM
I know you can do it in Excel with: Application.EnableEvents = False

But how do you do it with Word?

The event I'm really concerned with is Document_ContentControlOnExit events fires when I'm trying to clean up bookmarks. My document has a bunch of Content Controls and a bunch of bookmarks.

Sub KillEmptyBkMrks()
Dim oBkMk As Bookmark
With ActiveDocument
.Bookmarks.ShowHidden = True
For Each oBkMk In .Bookmarks
If .Bookmarks(oBkMk).Empty = True Then oBkMk.Delete
Next
.Bookmarks.ShowHidden = False
End With
End Sub

Any idea how to stop this?

Thanks!

gmaxey
03-23-2011, 03:54 PM
I don't have an answer to your question and I wasn't able to duplicate the issue. There is a bug in Word2007 content control on exit event. It will often fire when the CC in entered if the Developer tab is not the active tab.

Are you using Word2007? Does making the Developer tab the active tab have any effect?

rruckus
03-24-2011, 07:26 AM
Yes I'm on Word 2007 but I'm aware of the CC exit event bug and this is not the issue. Activating the dev tab doesn't fix it.

To duplicate this you would need to insert a root CC in your document, insert a bunch of paragraphs and wrap CCs as children of the root CC around the text. Now insert bookmarks at the start of each paragraph and try deleting them without the CC events firing.

So there's no general way to stop events?

Paul_Hossler
03-25-2011, 07:36 AM
Can you post an attachment showing the issue?

Paul

rruckus
03-25-2011, 10:30 AM
I attached the sample file. You need to open the VBA editor and run the DeleteBookmarks macro. You will see in the Immediate window that the CC Events get fired when all the code does is delete the bookmarks, it shouldn't change the selection and fire the CC enter and exit events.

To test again, just run the AddBookmarks macro and then DeleteBookmarks.

Thanks for helping out!

gmaxey
03-26-2011, 01:35 PM
I see the issue. It occurs in Word2007 and Word2010. There is no equivelent for .EnableEvents in Word so I can't suggest a fix.

I did notice that it does not occur if you step through the code using the F8 key but I don't know why. Sorry.

Paul_Hossler
03-26-2011, 03:06 PM
Ditto to Greg's observations

I agree that some of thebehavior a little strange, but what is the problem your're having other than the events firing as they should?

Paul

gmaxey
03-26-2011, 06:05 PM
Paul,

I don't follow your "as they should." With his "add" bookmarks procedure yes but I don't see any reason the events should be firing with his "delete" bookmark procedure.

Paul_Hossler
03-27-2011, 06:04 AM
I was just thinking that if you have CC Enter and Exit events, and when deleting a BM in the CC, I'd expect the event to fire

If I create a BM NOT in the CC's range, and running the Delete macro, then the CC events don't fire.

Paul

gmaxey
03-27-2011, 06:36 AM
Paul,

I see your line of thinking, but the CCs are never actually entered or exited with the "delete" code so it seems odd to me that either would fire.

Consider a simple document with three CCs titled A, B and C

Run the following code:

Sub ScratchMacro1()
Sub ScratchMacro()
ActiveDocument.ContentControls(1).Range.Text = "aaa"
ActiveDocument.ContentControls(2).Range.Text = "bbb"
End Sub
Private Sub Document_ContentControlOnExit(ByVal CC as ContentControl, Cancel As Boolean)
Debug.Print CC.Title & " fired"
End Sub


The content of thte CCs A and B are changed but the event doesn't fire.

Now it gets wierd and leading me to believe that when the Exit event fires it is not firing as it should:

Run this code:

Sub ScratchMacro()
ActiveDocument.ContentControls(1).Range.Text = "aaa"
ActiveDocument.ContentControls(2).Range.Text = "bbb"
ActiveDocument.ContentControls(2).Range.Characters(2).Delete
ActiveDocument.ContentControls(3).Range.Characters(2).Delete
End Sub
Private Sub Document_ContentControlOnExit(ByVal CC as ContentControl, Cancel As Boolean)
Debug.Print CC.Title & " fired"
End Sub


Here (similiar to the delete bookmark code) the event fires, but only the event for the CC titled "A"!! We are doing the same thing with "B" but the event for "B" did not fire. It seems to me that if the event should fire then it should fire for both.

Finally run:

Sub ScratchMacro()
ActiveDocument.ContentControls(1).Range.Text = "aaa"
ActiveDocument.ContentControls(2).Range.Text = "bbb"
ActiveDocument.ContentControls(3).Range.Text = "ccc"
ActiveDocument.ContentControls(1).Range.Characters(2).Delete
ActiveDocument.ContentControls(2).Range.Characters(2).Delete
ActiveDocument.ContentControls(3).Range.Characters(2).Delete
End Sub
Private Sub Document_ContentControlOnExit(ByVal CC As ContentControl, Cancel As Boolean)
Debug.Print CC.Title & " fired"
End Sub


Here you should see that the event fires for A and B but not C.

IMO something is cleary not right.

Paul_Hossler
03-27-2011, 11:05 AM
but the CCs are never actually entered or exited with the "delete" code so it seems odd to me that either would fire.


One could take the approach that the act of deleting a BM in a CC range constitutes 'entering' the CC

As to your other findings ....

One of the many mysteries of Word :dunno


Option Explicit

Sub ScratchMacro1()
ActiveDocument.ContentControls(1).Range.Text = "aaa"
ActiveDocument.ContentControls(2).Range.Text = "bbb"
End Sub

Sub ScratchMacro2()
ActiveDocument.ContentControls(1).Range.Text = "123456"
ActiveDocument.ContentControls(2).Range.Text = "ABCDEF"

ActiveDocument.ContentControls(1).Range.Characters(2).Delete
ActiveDocument.ContentControls(2).Range.Characters(2).Delete
End Sub

Sub ScratchMacro3()
ActiveDocument.ContentControls(1).Range.Text = "123456"
ActiveDocument.ContentControls(2).Range.Text = "ABCDEF"
ActiveDocument.ContentControls(3).Range.Text = "987654"

ActiveDocument.ContentControls(1).Range.Characters(2).Delete
ActiveDocument.ContentControls(2).Range.Characters(2).Delete
ActiveDocument.ContentControls(3).Range.Characters(2).Delete
End Sub


Expanded a bit and added a OnEnter event

In Scratch3, I get a Enter-A, Exit-A, Enter-B, Exit-B, Enter-C but no Exit-C when I run the macro

When I click in the CC's manually, I get the expected In/Out Pairs BUT with the C-Exit happening only when I click outside of the C CC

There may be some Word rule that makes sense, but it's not obvious to me

Paul

gmaxey
03-27-2011, 11:11 AM
Paul,

Nor me.

If the "Exit" (or "Enter") events fire when you "delete" a part of the range (or a bookmark) then it seems that they should also fire when your "alter" the range and they don't.

rruckus
03-29-2011, 08:51 AM
Thanks guys, great discussion, and thanks for the time you put in. It's been my experience that CC events should NOT fire if you are working with the range object, but obviously from your tests it's different for the .delete method. My logic and experience is that CC events should only fire when the actual selection is moved in and out of a given CC. I don't see why the .delete method behaves differently here. If you change my AddBookmarks function to use the p.range instead of moving the selection, you'll see that NO events fire as I would expect. So they fire for ".delete" but not ".add" ??? Seems inconsistant and I think it's a bug. Example:

'Selection.SetRange p.Range.Start, p.Range.Start
'Selection.Bookmarks.Add "TestBookmark" + CStr(i)
p.Range.Bookmarks.Add "test" + CStr(i)

And now events don't fire!

If you accept that Word needs to move the selection to perform a delete, the fact that your last event doesn't fire the exit event actually makes sense to me because that ghost selection doesn't ever leave the CC. To see what I mean, just try this instead:

ActiveDocument.ContentControls(1).Range.Characters(2).Select
ActiveDocument.ContentControls(2).Range.Characters(2).Select

Whether the events are SUPPOSED to fire or not is unfortuntaley irrelevant now, I just need to find a way to stop them from firing or skip them. When I use a loop to edit text in a CC, I just use ActiveDocument.ContentControls(1).Range.Text = "" instead of ActiveDocument.ContentControls(1).Range.Delete and the event doesn't fire.

But how do I do something similar to get rid of my bookmark without the event firing??? I can't use ActiveDocument.Bookmarks(1).Range.Text = "" because it leaves the bookmark and deletes text.

gmaxey
03-30-2011, 04:26 AM
Maybe by moving the bookmarks out of the CC then deleting them. Put the cursor outside your CC and try running:

Public Sub DeleteBookmarks()
Dim oTmpRange As Range
Dim oBM As Bookmark
Set oTmpRange = Selection.Range
ActiveDocument.Bookmarks.ShowHidden = True
Dim b As Bookmark
For Each b In ActiveDocument.Bookmarks
Set oBM = ActiveDocument.Bookmarks.Add(b.Name, oTmpRange)
oBM.Delete
Next b
Set oBM = Nothing
Set oTmpRange = Nothing
End Sub

rruckus
03-30-2011, 07:47 AM
Wow, thanks Greg! That works. I owe you a beer!

gmaxey
03-30-2011, 03:37 PM
A beer would just make me thirsty. How about a six pack?

You're welcome and I am glad you have a solution.

Paul_Hossler
03-30-2011, 04:24 PM
Pretty slick :bow:

Paul