Word 2013 Comments in the Object Model
In my last post I presented some of the new Comment functionality in the Word UI. The new functionality for Comments is also reflected in Word’s object model.
Deprecated Properties and Methods
At the same time, some properties and methods connected with the earlier functionality has been “deprecated”. For reasons of backwards compatibility they are still there and work, for the most part. But they won’t show up in Intellisense and can only be viewed in the VBA Editor’s object browser by turning on the display of Hidden members (in the context menu).
Deprecated members of the Comment object and of the View object where it affects Comments |
New method or property |
Author |
Contact.Name (also .ID , .EmailAddress ) |
Initials |
|
Delete |
DeleteRecursively If a “parent” comment removes the comment and all replies. Otherwise, deletes the single comment. |
ShowTip |
|
View.RevisionsView |
View.RevisionsFilter.Markup Expects a value from theEnumWdRevisionsMode |
View.RevisionsMode |
View.MarkupMode Expects a value from the Enum wdRevisionsMarkup |
View.Reviewers |
View.RevisionsFilter.Reviewers Takes an index number or a string corresponding to the Author information. If a string is specified that is not a valid Reviewer the following error is triggered:Run-time error 5850 The specified range is not from the correct document or story. |
ShowBy Even though it’s not a “hidden member”, this method does not work. See View.RevisionsFilter.ToggleShowAllReviewers |
|
View.RevisionsFilter.ToggleShowAllReviewers Does not work. Update: was fixed in an later beta build |
Overview of the Comments object model
I won’t go into the details of working with the complete Comments object model here. The purpose of this post is to highlight what’s different in 2013.
Sample code that illustrates the use of most properties and methods is available for download as a plain text file. This has been exported from Word’s VBA Editor. If you want to use it in VBA, rename the extension from txt to bas then use File/Import to create a new module in the current project in the VBA Editor. For other programming languages you can copy the content into your code and adapt it.
The first procedure in the code lists various methods affecting how Comments (and Revisions) are displayed. These correspond to various controls in the Review tab of the Ribbon; which ones are noted in the comments in the code. Comment out the line of code you’d like to test.
The second procedure calls a third, a function that returns a string of information about all the Comments in the document. In the sample, it is written out to a new document but it can be used any way you like.
Displaying Comments from certain or all Reviewers
As noted in the table, above, View.RevisionsFilter.Reviewers
replaces View.Reviewers
and also applies to Comments. It corresponds to the list in Review/Tracking/Show Markup/Specific people. It lets the user choose whose comments should be displayed. There’s also an entry “All Reviewers”, and this is a problem.
While the object model offers method ToggleShowAllReviewers it does not have any effect, either on the document surface or in this list. Should you want to turn all reviewers on or off a workaround is required that’s a lot more code in VBA, but does do the job. This code can also be adapted to get a list of reviewers.
Update: The method appears to work in a later beta build. The code may still be of interest for getting a list of reviewers, as stored in the array.
Sub ToggleReviewers() Dim wn As Word.Window Set wn = ActiveDocument.ActiveWindow Dim i As Long, j As Long Dim duplicate As Boolean Dim author As String Dim cmt As Word.Comment Dim a() As Variant If ActiveDocument.Comments.Count < 1 Then Debug.Print "The document contains no comments." Exit Sub End If i = 0 For Each cmt In ActiveDocument.Comments ReDim Preserve a(i) author = cmt.author duplicate = False For j = 0 To i 'Avoid duplicates as an author may have more than one comment If a(j) = author Then duplicate = True Exit For End If Next If Not duplicate Then a(i) = author i = i + 1 Else ReDim Preserve a(i - 1) End If Next For j = 0 To UBound(a) wn.View.RevisionsFilter.Reviewers(a(j)).Visible = _ Not wn.View.RevisionsFilter.Reviewers(a(j)).Visible Next End Sub
New functionality: Discussions
One of the major changes for Comments is the support for discussions: multiple comments linked to a single, original comment.
In the object model, the original Comment in a discussion corresponds to the Comment.Ancestor
property. As there can be only one Ancestor, there is no collection and no Count
property. So how do you determine if there is an Ancestor (whether the Comment is a reply in a discussion)? You try to assign it to a different Comment
object, then test whether that is Nothing
(null
in C#):
Dim cmtA As Word.Comment Set cmtA = cmt.Ancestor If Not cmtA Is Nothing Then ‘There is an Ancestor Else ‘There is no Ancestor, the comment is at the top-level End If
If you try to use Comment.Ancestor
when there is no Ancestor you’ll get the Runtime error 91 “Object variable or With block variable not set.”
If you want to know whether a Comment is the first item in a discussion, you can query whether it has any Replies. In this case, there is a Count
property:
nrReplies = cmt.Replies.Count If nrReplies > 0 Then ‘It’s a top-level Comment with Replies Else ‘There are no replies, but it might itself be a reply End If
Another aspect of the discussion functionality is being able to mark a Comment set as “Done” when a point under discussion has been resolved. This can be applied to a single comment, or a reply in a discussion. When applied to an Ancestor, the entire Comment is marked as “Done”: Comment.Done = True ‘or False
.
The other major new propery is Comment.Contact
. This returns an object of data type CoAuthor
and provides information such as the Name
, ID
and, if available, EmailAddress
(if no e-mail address can be associated with the Contact and empty string is returned).
As Comments are now fully integrated into co-authoring (multiple users working simultaneously on a document), there’s also capability to lock portions of the document against someone else changing them. These are managed through the Contact.Locks
property, for which the example has no sample code.
April 12th, 2013 at 14:37
Hi Cindy,
I will post in the MSDN Word for Developers as you suggested. Thanks.
Brenda
April 10th, 2013 at 15:22
Cindy,
Are you available to contract with me to change the code in my application. I currently use OpenDataSource via DDE and would like to change it to use OLE translating an Access Query into a text file.
You helped me once before a good few years ago.
Thanks,
Brenda
April 11th, 2013 at 09:39
Hi Brenda
I’m currently bogged down in a book project, writing five new chapters for our 1000-page German Word programming book. I’m afraid I wouldn’t be able to give it the necessary attention until October or November. If you post in the Word for Developers forum on MSDN I can give a heads-up to someone I know who has specialized in the past on OpenDataSource connection issues and who might be available for a contract.