Dragon Drop
Dragon Drop - A Software Consultancy
Home      Our Products      Consultancy      Web Page Development      Services      Coding      Windows      External Resources     
Links      Newsletter      News And Issues      Books etc.      About Us     
CODING:   Exchange      Visual Basic      VBA      HomeSite     |     Coding Tools      Software Clinic     

Word Code

Navigating Between Comments

We were asked to write a small tool for someone who wanted to be able to see each user's comments within a Word document and to be able to navigate between the comments. This code, which resides in a start-up Word template, is a more friendly version of the F5 'go to...' function within Word. More importantly, with a little more work we can expand on this tool to manage the comments.

In the current version the user can click on the icon in the toolbar and if a document is present and it has comments then a dialog box appears:

The user is able to select which author's comments to view; or to view all of the comments within the document.

Having selected an author the list of his or her comments are listed in the right hand control.

Selecting a comment will do two things. First it will put the actual commment text into the bottom control of the dialog box and, second, the comment within the document will be selected. Therefore, if the user clicks on the 'Go To' button then that comment will remain selected. Clicking on the 'Cancel' button will cause the user's selection to return to where he or she was before this dialog box was brought up.

The code comes in two classes; the modComments code module and the form itself, which is frmSelectComment

The code for the module modComments:




Option Explicit

 

  Public Const ALL_AUTHORS As String = "- All -"

'





Public Sub GoToComment()



  Dim oFrm As frmSelectComment

  

  On Error GoTo Error_GotoComment

  

  

  If Documents.Count > 0 Then

  

    If ActiveDocument.Comments.Count = 0 Then

      MsgBox "There are no comments are in the current Active Document.", _

          vbOKOnly + vbExclamation, "Dragon Drop Comments"

    Else

    

      ActiveDocument.Bookmarks.Add "DragonDropOriginalPosition", Selection.Range

      

      Set oFrm = New frmSelectComment

      oFrm.Tag = "Cancel"

      

      oFrm.Show

      '--------

      

      If oFrm.Tag = "Cancel" Then

        ActiveDocument.Bookmarks("DragonDropOriginalPosition").Range.Select

      End If

      ActiveDocument.Bookmarks("DragonDropOriginalPosition").Delete

      

      Unload oFrm

      Set oFrm = Nothing

      

    End If

    

  End If

  

  

Exit_GoToComment:

  

  Exit Sub

  

  

  

Error_GotoComment:

  

  On Error Resume Next



  If ActiveDocument.Bookmarks.Exists("DragonDropOriginalPosition") Then

    ActiveDocument.Bookmarks("DragonDropOriginalPosition").Range.Select

  End If

  ActiveDocument.Bookmarks("DragonDropOriginalPosition").Delete

    

  Resume Exit_GoToComment



End Sub



 

The entry point for the code is the public subroutine, GoToComment(), above. This is what is called from the button on the toolbar.

The code for the form frmSelectComment:




Option Explicit

'



Private Sub cmdCancel_Click()



  Me.Tag = "Cancel"

  Me.Hide



End Sub







Private Sub cmdGoTo_Click()



  Me.Tag = "OK"

  Me.Hide



End Sub



Private Sub UserForm_Initialize()



  Dim oComment As Comment

  Dim sAuthor As String

  

    

  Me.lstAuthors.AddItem ALL_AUTHORS

  For Each oComment In ActiveDocument.Comments

    sAuthor = Trim$(oComment.Author)

    If Len(sAuthor) > 0 Then

      If Not IsAuthorListed(sAuthor) Then

        Me.lstAuthors.AddItem sAuthor

      End If

    End If

  Next oComment



End Sub





Private Function IsAuthorListed(sAuthor As String) As Boolean



  Dim nIndex As Long

  Dim bIsFound As Boolean

  

  

  bIsFound = False

  nIndex = 0

  

  Do While nIndex < Me.lstAuthors.ListCount

    If Me.lstAuthors.List(nIndex) = sAuthor Then

      bIsFound = True

      Exit Do

    End If

    nIndex = nIndex + 1

  Loop

  

  IsAuthorListed = bIsFound



End Function





Private Sub lstAuthors_Click()



  Dim nIndex As Long

  Dim sAuthor As String

  Dim oComment As Comment





  Me.lstComments.Clear

  Me.txtComment.Text = ""



  nIndex = Me.lstAuthors.ListIndex

  If nIndex >= 0 Then

    sAuthor = Me.lstAuthors.Text

    For Each oComment In ActiveDocument.Comments

      If oComment.Author = sAuthor Or sAuthor = ALL_AUTHORS Then

        Me.lstComments.AddItem oComment.Index 

        Me.lstComments.List(Me.lstComments.ListCount - 1, 1) = oComment.Scope.Text

      End If

    Next oComment

  End If

  

End Sub





Private Sub lstComments_Click()



  Dim nCommentIndex As Long

  Dim nIndex As Long

  

  nIndex = Me.lstComments.ListIndex

  If nIndex >= 0 Then

    nCommentIndex = Val(Me.lstComments.List(nIndex, 0))

  

    If nCommentIndex > 0 Then

      Me.txtComment.Text = ActiveDocument.Comments(nCommentIndex).Range.Text

      ActiveDocument.Comments(nCommentIndex).Scope.Select

    End If

  End If

  

End Sub



This code is rather straightforward. When the GoToComment() routine is entered the first thing that happens is that the number of open documents are counted. If there are no documents open then nothing happens as the first If...Then statement fails.

The next check is to see if there are any comments within the current active document. This is done by counting the number of .Comments in the ActiveDocument. If there are no comments then the user is informed of this by a message box and then the processing stops.

The next thing that happens is that a bookmark is created in the document at the current selection position and range. This is so that the user can return to this point if he or she presses the Cancel button on the dialog box.

The next thing is that the dialog box is created and before the dialog box is displayed the .Tag property of the dialog box is set to "Cancel". The reason that this is done this way is that one way of processing the result of the button presses on the form is within the form itself or it can be done, as in this example, in the calling routine. The advantage of doing it this way is that if the user cancels the form via the 'x' control then we still have the return value of "Cancel" and we can continue clearing up any objects in exactly the same way as if the the form was left in the expected way.

The dialog box is then shown; the processing is done on the form until the form is closed. After the form is closed the form object is destroyed and the pointer to it reset. If the user didn't exit the form by going pressing the 'Go To' button then the range of the our bookmark is reselected and destroyed thus clearing everything up and leaving no sign that this code was ever executed.

So, what happens when the form is created and until it is destroyed?

The first thing is that it does is on initialising the form the string "- ALL -" is added to the lstAuthors list control and then each comment in the active document is accessed to locate each of the names of the authors of the comment; this is done by looking at the .Author property.

This is the then the situation that the user first sees after he or she has clicked on the toolbar button. The list of comment authors are in the left hand control and the dialog box is ready for user operation.

When the user clicks on an author's name the collection of comments is traversed once more and each comment by that author is placed into the right hand control. What one can see in this control is the actual text used in the main document which is commented.

Actually, the code does a little more than this; the right hand control, lstCommments, actually has two columns. The first column of the lstComments control is zero width and it is into here that the index value of the comment is placed. In the second column, the visible column, is the document commented text.

The reason for this is that each item in the .Comments collection has an index. To save further travelling through the comments each time the user selects a comment in the lstComments window the index value is gathered and the acutal comment can be directly accessed from the collection.

When the comment is selected in the lstComments window the range of the text of the comment, i.e. the comment notes, are placed into the control at the bottom and then, finally, the scope of the comment on the document is selected so it seems like the user has 'gone to the comment' by selecting it in the dialog box.

There is nothing really difficult about this code item but that doesn't mean to say that it isn't useful. Of course there will be futher enhancements to it in the future so that full comment control can be given to the user.

This code can be downloaded from here and placed into Word's start-up folder.

Updates or Comments

If there are any suggestions for updates or comments then please drop us a mail at malcolm.smith@dragondrop.com.