Find where ContentControl is located

J

John

Hi,

I have a content control in a table and am using the
Document_ControlControlOnExit event to do some post processing. Can anyone
tell me how I can get a reference to the table or better, the row, that the
control is sitting in? I thought the Parent property might return the table
but it only returns the Document.

Any clues?

Thanks

John
 
G

Greg Maxey

John,

Can you provide details on what specifically you are trying to do?

General you can use the CC.ID or CC.Title to perform processing regarless of
where the CC is physically located.

To get the unique ID of a CC you can select it in the document and then run
this bit of code:

Option Explicit
Sub GetUniqueID()
Dim i As Long
Dim currentCC As Word.ContentControl
Dim oCC As Word.ContentControl
'You have to click the CC tab to select a specific control
Set currentCC = Selection.ContentControls(1)
MsgBox currentCC.ID
End Sub

You can then work with the CC by ID as follows:

Sub WorkWithCCByID()
Dim oCC As ContentControl
Set oCC = ActiveDocument.ContentControls("59279876") 'the number is the
unique ID found above
oCC.Range.Text = "Some text here"
End Sub

Or if you have assigned a title to a CC you can work with it like this:

Sub WorkWithCCbyTitle()
Dim oCC As ContentControl
Set oCC =
ActiveDocument.SelectContentControlsByTitle("CC_ClientName").Item(1)
oCC.Range.Text = "Some text here"
End Sub

You can use the ContentControl (abreviated to CC here) argument in the
onexit event to work with any CC as follows:

Private Sub Document_ContentControlOnExit(ByVal CC As ContentControl, Cancel
As Boolean)
'Work by referencing ID
Select Case CC.ID
Case Is = "59279876"
CC.Range.Text = "Some New Text here"
Case Else
MsgBox CC.ID
End Select
'Work by referencing Title
Select Case CC.Title
Case Is = "CC_ClientName"
If CC.Range.Text = "Some text here" Then
CC.Range.Text = "Some new text here"
End If
Case Else
MsgBox CC.ID
End Select
End Sub

Note that there is a very annoying bug in the CCOnExit event. It will
commonly fire twice (on entry and on exit) if the Developer tab is not the
active ribbon tab. The only suitable work around that I have found so far
is to ensure that the Developer tab is the active tab when navigating
through CCs. You can do this with the Windows API keybd_event and the
ContentControlOnEnter event as follows. Basically this just an automated
way of pressing Alt, L, Alt to call the Developer tab.

Option Explicit
Private Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal _
bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)
Private Const KEYEVENTF_KEYUP = &H2
Private Const VK_MENU = &H12
Private Const VK_L = &H4C

Private Sub Document_ContentControlOnEnter(ByVal ContentControl As
ContentControl)
MakeDevTabActive
End Sub

Public Sub MakeDevTabActive()
keybd_event VK_MENU, 0, 0, 0 'Press ALT
keybd_event VK_MENU, 0, KEYEVENTF_KEYUP, 0 'Release ALT
keybd_event VK_L, 0, 0, 0 'Press L
keybd_event VK_L, 0, 2, 0 'Release L
keybd_event VK_MENU, 0, 0, 0 'Press ALT
keybd_event VK_MENU, 0, KEYEVENTF_KEYUP, 0 'Release ALT
End Sub











Hi,

I have a content control in a table and am using the
Document_ControlControlOnExit event to do some post processing. Can
anyone tell me how I can get a reference to the table or better, the
row, that the control is sitting in? I thought the Parent property
might return the table but it only returns the Document.

Any clues?

Thanks

John

--
Greg Maxey - Word MVP

My web site http://gregmaxey.mvps.org


McCain/Palin '08 !!!
 
J

John

Hello Greg,

Thanks very much for the comprehsive reply. I'm particularly interested in
the OnExit event firing twice.

With my current issue I have a table with a drop down content control in
each row. I'm trying to get the row that the respective content control
OnExit event was fired in so that I can then change the row backround color,
hence my looking at the Pernet property. Is that possible do you think?

Best regards

John
 
G

Greg Maxey

So you want to change the current row background color based on what user
selects in that rows CC.

Private Sub Document_ContentControlOnExit(ByVal CC As ContentControl, Cancel
As Boolean)
Dim i As Long
i = CC.Range.Information(wdEndOfRangeRowNumber)
Select Case CC.Range.Text
Case Is = "Red"
Selection.Tables(1).Rows(i).Shading.BackgroundPatternColor = wdColorRed
Case Is = "Blue"
Selection.Tables(1).Rows(i).Shading.BackgroundPatternColor = wdColorBlue
Case Is = "Green"
Selection.Tables(1).Rows(i).Shading.BackgroundPatternColor =
wdColorGreen
End Select
End Sub

Note: that the event will fire twice because of the bug, but in this case it
is transparent.



Hello Greg,

Thanks very much for the comprehsive reply. I'm particularly
interested in the OnExit event firing twice.

With my current issue I have a table with a drop down content control
in each row. I'm trying to get the row that the respective content
control OnExit event was fired in so that I can then change the row
backround color, hence my looking at the Pernet property. Is that
possible do you think?
Best regards

John

--
Greg Maxey - Word MVP

My web site http://gregmaxey.mvps.org


McCain/Palin '08 !!!
 
J

John

Hi Greg,

This all worked out fine, with one exception - I found that if, after
selecting the control, your next click was outside of the table, the
Selection.Tables(1) ... returned a different table. I guess by the time the
event has fired the Selection no longer refers to the table that housed the
control?

In the end I've gone for CC.Range.Tables(1). and although this appears to
work and returns the CC's table I'm mildly puzzled that the CC.Range
property has any tables at all. After all, I embedded the CC in a table
cell, not the other way around.

Anyway, no doubt there's a good reason for it somewhere :)

Thanks again

John
 
G

Greg Maxey

John,

You are right. This does seem to work correctly:

Private Sub Document_ContentControlOnExit(ByVal CC As ContentControl, Cancel
As Boolean)
Dim i As Long
i = CC.Range.Information(wdEndOfRangeRowNumber)
Select Case CC.Range.Text
Case Is = "Red"
CC.Range.Tables(1).Rows(i).Shading.BackgroundPatternColor = wdColorRed
Case Is = "Blue"
CC.Range.Tables(1).Rows(i).Shading.BackgroundPatternColor = wdColorBlue
Case Is = "Green"
CC.Range.Tables(1).Rows(i).Shading.BackgroundPatternColor = wdColorGreen
End Select
End Sub

I don't have a technical explanation. But then I suppose it makes as much
sense as Selection.Tables(1). After all the selection is in the table and
not the other way around ;-)



Hi Greg,

This all worked out fine, with one exception - I found that if, after
selecting the control, your next click was outside of the table, the
Selection.Tables(1) ... returned a different table. I guess by the
time the event has fired the Selection no longer refers to the table
that housed the control?

In the end I've gone for CC.Range.Tables(1). and although this
appears to work and returns the CC's table I'm mildly puzzled that
the CC.Range property has any tables at all. After all, I embedded
the CC in a table cell, not the other way around.

Anyway, no doubt there's a good reason for it somewhere :)

Thanks again

John

--
Greg Maxey - Word MVP

My web site http://gregmaxey.mvps.org


McCain/Palin '08 !!!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top