Accessing Microsoft Word Comments
Created: July 2000
Applies to: Microsoft Word 2000
Summary: Attempting to access comments in a range or selection of a Microsoft® Word document returns all the comments in the entire document. This article shows you how to access comments by using the Comments collection with the help of additional code.
The ability to add comments to a document is a useful feature of Microsoft® Word. You can add review feedback, write notes to others or yourself, and add other annotations to a document. However, accessing these comments programmatically may require more code than you'd expect. For example, suppose you want to display a list of comments and arrange them by the paragraphs they appear in. One method that you could use is to analyze each paragraph of the document and, for paragraphs that contain comments, display all comments in the paragraph. In the following Visual Basic® for Applications (VBA) example for Word, the strRemarks variable is initialized at the start of processing for each paragraph, and contains a comma-delimited list of comments found in a particular paragraph range. The list is displayed in the Immediate window of the Visual Basic Editor.
To display comments in a document
- Create a document containing several paragraphs.
- Insert one or more comments into each paragraph.
- Open the Visual Basic Editor (ALT+F11).
- Type or paste the following code (the DisplayComments subroutine) in the code window (in the Projects window, under Microsoft Word Object, click ThisDocument).
Sub DisplayComments() Dim objPara As Paragraph Dim objComment As Comment Dim strRemarks As String For Each objPara In ActiveDocument.Paragraphs strRemarks = "" For Each objComment In objPara.Range.Comments If Len(strRemarks) = 0 Then strRemarks = objComment.Range.Text Else strRemarks = strRemarks & ", " & _ objComment.Range.Text End If Next objComment If Len(strRemarks) <> 0 Then _ Debug.Print strRemarks Next objPara End Sub
- Now run the subroutine (press F5). You will notice that something is terribly wrong. The complete set of comments in the document is listed for each paragraph!
To determine whether a comment is within a range or selection, use the InRange method. The InRange method returns True if the range or selection to which the method is applied is contained in the range specified by its Range argument. In the following example, a condition was added to the main loop. The InRange method is used to determine if the scope of the comment is in the range of the paragraph.
Sub DisplayComments() Dim objPara As Paragraph Dim objComment As Comment Dim strRemarks As String For Each objPara In ActiveDocument.Paragraphs strRemarks = "" For Each objComment In objPara.Range.Comments If objComment.Scope _ .InRange(Range:=objPara.Range) Then If Len(strRemarks) = 0 Then strRemarks = objComment.Range.Text Else strRemarks = strRemarks & ", " & _ objComment.Range.Text End If End If Next objComment If Len(strRemarks) <> 0 Then _ Debug.Print strRemarks Next objPara End Sub
Now copy the corrected DisplayComments subroutine into the module in the document you created earlier, and run it. (Clear the Immediate window first!) Note that the comments are now correctly listed by paragraph.
However, for a document that contains a large number of paragraphs and comments, the subroutine can spend a significant amount of time analyzing comments that are outside the range of each paragraph. We can easily reduce the amount of processing that takes place. Note that in these examples, we are analyzing the paragraphs of the document in the order in which they appear. Because the comments are also arranged in the Comments collection in the order of appearance, all we need to do is keep track of the comments that have already been analyzed. In the following code, we've modified both loops to use index counters that contain the paragraph and comment index. The intCommentIndex variable is used to keep track of the comments that have been analyzed, and to signal when all comments have been analyzed.
Sub DisplayComments() Dim objPara As Paragraph Dim strRemarks As String Dim intParaIndex As Integer Dim intCommentIndex As Integer Dim intIndex As Integer intCommentIndex = 1 For intParaIndex = 1 To _ ActiveDocument.Paragraphs.Count strRemarks = "" For intIndex = intCommentIndex To _ ActiveDocument.Comments.Count ' Start from the first comment that has not ' been checked already. With ActiveDocument.Comments(intIndex) If .Scope _ .InRange(Range:=ActiveDocument _ .Paragraphs(intParaIndex).Range) Then If Len(strRemarks) = 0 Then strRemarks = .Range.Text Else strRemarks = strRemarks & ", " _ & .Range.Text End If If intCommentIndex < ActiveDocument _ .Comments.Count Then ' Point to the next comment, ' if any. intCommentIndex = intIndex + 1 Else ' Specify that there are no ' more comments to process. intCommentIndex = 0 End If Else Exit For End If End With Next intIndex If Len(strRemarks) <> 0 Then _ Debug.Print "Paragraph: " & intParaIndex & _ ", comments: " & strRemarks ' Exit the loop if there are no more comments. If intCommentIndex = 0 Then Exit For Next intParaIndex End Sub
Now run the DisplayComments subroutine on the document you created earlier. The subroutine takes less time to complete when there are a large number of paragraphs and comments.
Although the previous examples used ranges, you can easily use the Selection object in the code instead. See "Working with Microsoft Word Objects" in the Microsoft Office 2000/Visual Basic Programmer's Guide to learn more about working with the Range and Selection objects.