Search code examples
vbacheckboxms-wordword-contentcontrol

Word Macro to Deselect a content control after macro


My current project is making a list for a coworker and since I like to over-complicate everything, I'm running macros for him to check off as he completes work. The description of work will change from a header style to normal when he's completed it, then update the ToC. All of this is working, but I have trouble with the content control staying selected sometimes. I can usually check and uncheck it once or twice with no problem, but eventually the cursor doesn't move out of the check box for some reason so subsequent clicks don't fire the OnEnter.

Private Sub Document_ContentControlOnEnter(ByVal CCtrl As ContentControl)
With CCtrl
  If .Type = wdContentControlCheckBox Then
    If .Checked = True Then
      .Range.Paragraphs.First.Style = wdStyleNormal
      ActiveDocument.TablesOfContents(1).Update
      Selection.Collapse direction:=wdCollapseEnd
    Else
      .Range.Paragraphs.First.Style = wdStyleHeading2
      ActiveDocument.TablesOfContents(1).Update
      Selection.MoveRight 1
    End If
  End If
End With
End Sub

Is there a way to force word to deselect the content control and move the cursor somewhere on the same line?

I tried Selection.MoveDown 1, Selection.Collapse direction:=wdCollapseEnd, and also Selection.MoveEnd but none work.


Solution

  • You can leverage the fact that, through the Content Control's Range the objects which contain it can be accessed. For example, you can "drill up" to the paragraph in which the content control is located:

    CCtrl.Range.Paragraphs(1).Range.Characters.Last.Select
    

    This could also be any character in the paragraph. The following (in my test) puts the selection immediately after the content control:

    CCtrl.Range.Paragraphs(1).Range.Characters(4).Select
    

    Incorporated into your code:

    Private Sub Document_ContentControlOnEnter(ByVal CCtrl As ContentControl)
      With CCtrl
        If .Type = wdContentControlCheckBox Then
          If .Checked = True Then
            .Range.Paragraphs.First.Style = wdStyleNormal
            ActiveDocument.TablesOfContents(1).Update
            Selection.Collapse direction:=wdCollapseEnd
          Else
            .Range.Paragraphs.First.Style = wdStyleHeading2
            ActiveDocument.TablesOfContents(1).Update
            Selection.MoveRight 1
          End If
    
          'Select the last character in the paragraph (the paragraph mark)
          CCtrl.Range.Paragraphs(1).Range.Characters.Last.Select
          'Remove the selection, so the cursor blinks at the end of the paragraph
          Selection.Collapse
    
        End If
      End With
    End Sub