I came across a bug today to do with the Document_ContentControlOnexit event, bookmarks, and the focus of the ribbon.
Consider you have a document with a Drop Down List content control and a range of text bookmarked. The bookmarked text range needs to be formatted depending on the selection made in the drop down. For the most part the following code should work fine:
Private Sub Document_ContentControlOnExit(ByVal ContentControl As ContentControl, Cancel As Boolean) Select Case ContentControl.Tag Case "EntityOption" Select Case ContentControl.Range.Text Case "Single entity" FormatBookmark "MultipleClients", False FormatBookmark "SingleEntity", True Case "Multiple entities" FormatBookmark "SingleEntity", False FormatBookmark "MultipleClients", True Case Else FormatBookmark "SingleEntity", True FormatBookmark "MultipleClients", True End Select End Select End Sub
However, when and only when the Home tab is selected I see a problem. Word kind of drops into an infinite loop. You see the hourglass flickering on screen a whole lot but you can still eventually click out of the content control and stop it, thats why I say kind of.
The first part of the problem is that when the Home tab has focus the content control exit event breaks and triggers both on enter and exit. This seems to be a fairly well known bug.
The second part of the problem and the infinite loop manifests itself when that incorrectly triggered exit event does something like manipulating a bookmarked range. The change in the document seems to trigger yet another content control exit event. Thus the loop begins. I think the exit event again is being triggered like an enter event, but I’m not sure.
So I did some Googling and found it had been noticed before by a PeterHS on microsoft.public.word.vba.general as posted here. He cried for help but no one seemed to have an intelligent answer. The common suggestion is to activate the developer tab as soon as the event is triggered. A solution that works, but interferes with the tabs, and I don’t like that.
My solution, while not perfect, is to check how quickly the events are being triggered. I’m assuming that human triggered events will probably be spaced by at least half a second. After all you need to click the drop down, find the correct item in the list, click on that, then click out of the content control (actually I hate that there is no on change event but that’s another story).
Private msngLastRun As Single Private Sub Document_ContentControlOnExit(ByVal ContentControl As ContentControl, Cancel As Boolean) If msngLastRun = 0 Or Timer - msngLastRun > 0.5 Then msngLastRun = Timer Select Case ContentControl.Tag Case "EntityOption" Select Case ContentControl.Range.Text Case "Single entity" FormatBookmark "MultipleClients", False FormatBookmark "SingleEntity", True Case "Multiple entities" FormatBookmark "SingleEntity", False FormatBookmark "MultipleClients", True Case Else FormatBookmark "SingleEntity", True FormatBookmark "MultipleClients", True End Select End Select End If End Sub
The event will still trigger once or twice, once on entering the content control when the home tab is active and a second time if the timer variable hadn’t been set before. But at least the loop is avoided.