Search code examples
vbams-wordoffice-automation

Replace text on which comment scope spans (Word)


I have a Word document, with comments

Ms Word Document with comments

I want to programmatically replace a text that is subject to a comment:

Sub ReplaceTextOfComments()
    For Each c In ActiveDocument.Comments
        If c.Range.Text = "BAR" Then
            c.Scope.Text = "H"
        End If
    Next c
End Sub

The result I get is the following:

Ms Word Document with comments

Is there any way to preserve the scope of the comment while replacing the text?


Solution

  • The best I could figure out is to create a new comment around the new text, deleting the previous comment. I did try changing the Start property of the Comment.Scope, but that doesn't appear to have any effect.

    The following code works. What threw me off for quite a while is the fact that Word apparently does not honor a Comment object. If I set a Comment to a variable, then insert a new comment, and the new comment is inserted/indexed before the original, then the new one replaces the original in the object variable. So, in the code below, cmtOrig actually contains the Comment just added, not the original. So doing cmtOrig.Delete actually deletes cmtNew, with the result that the remaining Comment doesn't contain the target Range. But it does appear to work reliably using the Index.

    The one caveat, though, is that you lose any formatting in the Comment.

    Sub ReplaceCommentRangeText()
        Dim rngCommentScope As word.Range
        Dim cmtOrig As word.Comment, cmtNew As Comment
        Dim cmtIndex As Long
        Dim rngTarget As word.Range
    
        Set cmtOrig = ActiveDocument.Comments(1)
        cmtIndex = cmtOrig.index
        Set rngCommentScope = cmtOrig.Scope
        rngCommentScope.Text = "C"
        Set cmtNew = ActiveDocument.Comments.Add(rngCommentScope, cmtOrig.Range.Text)
        'Debug.Print cmtNew.index, cmtIndex
        If cmtNew.index = cmtIndex Then
            ActiveDocument.Comments(cmtIndex + 1).Delete
        Else
            ActiveDocument.Comments(cmtIndex).Delete
        End If
    End Sub