Reputation: 95
I would like to mark certain text in my Word document and add a comment with a variety of references. This is so that a) I can output/print those details in the comments for further processing and b) that the information of the comments is updated if the document develops and changes.
The references I want to include into the comments are:
The text may look like this:
1.0 Heading A Text
This is Page 1 of the document.
1.1 Heading B Text
AB | no header actually |
---|---|
[1] | a text paragraph |
[2] | another text paragraph |
1.1.1 Heading C Text
With this heading Page 2 starts
AB | no header actually |
---|---|
[1] | a text paragraph |
[2] | arbitrary paragraphs |
2.0 Heading D Text
AB | no header actually |
---|---|
[1] | a text paragraph |
[2] | another text paragraph |
2.1 Heading E Text
2.1.1 Heading F Text
AB | no header actually |
---|---|
[1] | a text paragraph |
[2] | another text paragraph |
The desired outcome would be if MS Word balloon comments are inserted for selected words/text like in the following example for the word "arbitrary":
arbitrary ----> (Section 1.1.1 Heading C Text; Paragraph [2]; Page 2)
I already managed to extract most that is, all references except the paragraph/list item number and the paragraph page number (for the page number I use for now the page number of the heading).
This is what I have so far:
Sub InsertCommentWithReferences()
Dim rng As Range
Dim iLevel As Integer
Dim sLevel As String
Dim mystring As String
Dim RefList As Variant
Dim row As Integer
Dim Message, Title, Default, myrequirement
'To hand over additional (requirement)text to be inserted at the beginning of the comment
'Message = "Enter the requirement number" ' Set prompt.
'Title = "Requirement number" ' Set title.
'Default = "" ' Set default.
'Display message, title, and default value.
'myrequirement = InputBox(Message, Title, Default)
Set rng = Selection.Range
iLevel = rng.Paragraphs(1).OutlineLevel
sLevel = "0"
mystring = Selection
sLevel = rng.ListFormat.ListString
' Collapse the range to start so as to not have to deal with '
' multi-segment ranges. Then check to make sure cursor is '
' within a table. '
Selection.Collapse Direction:=wdCollapseStart
If Not Selection.Information(wdWithInTable) Then
MsgBox "Can only run this within a table"
Exit Sub
End If
' lookup paragraph number as a text string
' Here I do actually extract the paragraph number but just as string and not as a reference
' which can be updated if the numbering changes
row = Selection.Information(wdEndOfRangeRowNumber)
Selection.Tables(1).Cell(row, -1).Select
paragraphstring = Selection.Paragraphs(1).Range.ListFormat.ListString
'MsgBox (paragraphstring)
Set rng = Selection.GoToPrevious(wdGoToHeading)
If rng.Paragraphs(1).OutlineLevel < iLevel Then
iLevel = rng.Paragraphs(1).OutlineLevel
Set rng = rng.Bookmarks("\line").Range
curr_headinglevel = rng.Paragraphs(1).OutlineLevel
curr_headingnumber = Selection.Paragraphs(1).Range.ListFormat.ListString
curr_headingtext = rng
End If
With Selection.Find
.ClearFormatting
.MatchWholeWord = True
.MatchCase = False
.Execute FindText:=mystring
End With
Selection.Comments.Add Range:=Selection.Range
temp = curr_headingnumber & " " & curr_headingtext
If Right(temp, 1) = vbCr Then
temp = Left(temp, Len(temp) - 1)
End If
myHeadings = ActiveDocument.GetCrossReferenceItems(wdRefTypeHeading)
For i = 1 To UBound(myHeadings)
'debug
'MsgBox (Trim(myHeadings(i)) & vbNewLine & temp)
If InStr(Trim(myHeadings(i)), " ") Then
'debug
'MsgBox ("double space")
Do
temp1 = myHeadings(i)
myHeadings(i) = Replace(myHeadings(i), Space(2), Space(1))
Loop Until temp1 = myHeadings(i)
End If
If InStr(Trim(myHeadings(i)), temp) Then
'debug stuff
'tempheading = myHeadings(i)
'MsgBox ("#" & tempheading & "#")
'If Left(tempheading, 1) = " " Then
' tempheading = Trim(tempheading)
'End If
'Selection.TypeText Text:=("R# " & myrequirement & vbNewLine & "Section ")
Selection.TypeText Text:=("R#" & myrequirement & "#Section ")
Selection.InsertCrossReference ReferenceType:="Heading", _
ReferenceKind:=wdNumberFullContext, _
ReferenceItem:=CStr(i), _
InsertAsHyperlink:=True, _
IncludePosition:=False, _
SeparateNumbers:=False, _
SeparatorString:=" "
Selection.TypeText Text:=(" ")
Selection.InsertCrossReference ReferenceType:="Heading", _
ReferenceKind:=wdContentText, _
ReferenceItem:=CStr(i), _
InsertAsHyperlink:=True, _
IncludePosition:=False, _
SeparateNumbers:=False, _
SeparatorString:=" "
Selection.TypeText Text:=("; Paragraph " & paragraphstring)
Selection.TypeText Text:=("; Page ")
Selection.InsertCrossReference _
ReferenceType:=wdRefTypeHeading, _
ReferenceKind:=wdPageNumber, ReferenceItem:=i
End If
'debug
'MsgBox (temp & "#")
Next i
Set rng = Nothing
End Sub
What I need help with is how to identify and insert the reference of a respective list item/paragraph number into the comment? So in words this would be along the lines of: look into the cell to the left, insert a reference pointing to the list item/paragraph number which can be found in that cell into a comment (number and page number).
As you can see in the example, item numbers can repeat (restart numbering at every new heading) and, they do not have a list item text as headings would, so I cannot search for that text.
Any hints would be much appreciated. Note, I have not much experience with VBA and the above is collected from various other examples in many other Q&A threads.
Thanks so much.
Best regards, Michael.
Upvotes: 1
Views: 700
Reputation: 13515
You don't need to store any of that data in the comments for later extraction. Moreover, such stored data could well be invalidated by edits that occur between the comment's creation and its extraction.
The following macro exports comments in the active document to a new Excel workbook, together with whatever headings are associated with the comment, in heading level order in different columns on the same row.
Sub ExportWordComments()
' Requires reference to Microsoft Excel Object Library in VBA,
Dim wdDoc As Document, wdCmt As Comment, wdRng As Range, i As Long, j As Long
Dim xlApp As New Excel.Application, xlWB As Excel.Workbook, xlRng As Excel.Range
xlApp.Visible = False
Set wdDoc = ActiveDocument
' Create & prepare a new Workbook.
Set xlWB = xlApp.Workbooks.Add
Set xlRng = xlWB.Worksheets(1).Range("A1")
With xlRng
' Create headers for the comment information
.Offset(0, 0) = "Comment Number"
.Offset(0, 1) = "Page Number"
.Offset(0, 2) = "Reviewer Name"
.Offset(0, 3) = "Date Written"
.Offset(0, 4) = "Comment Text"
.Offset(0, 5) = "Section"
End With
' Export the actual comments information
With wdDoc
For Each wdCmt In .Comments
With wdCmt
i = i + 1
xlRng.Offset(i, 0) = .Index
xlRng.Offset(i, 1) = .Reference.Information(wdActiveEndAdjustedPageNumber)
xlRng.Offset(i, 2) = .Author
xlRng.Offset(i, 3) = Format(.Date, "mm/dd/yyyy")
xlRng.Offset(i, 4) = .Range.Text
Set wdRng = .Scope
Set wdRng = wdRng.GoTo(What:=wdGoToBookmark, Name:="\HeadingLevel")
With wdRng
j = Split(.Paragraphs.First.Style, "Heading")(1)
With .Paragraphs.First.Range
xlRng.Offset(i, 4 + j) = .ListFormat.ListString & " " & .Text
End With
End With
Do Until Split(wdRng.Paragraphs.First.Style, " ")(1) = 1
wdRng.Start = wdRng.Start - 1
Set wdRng = wdRng.GoTo(What:=wdGoToBookmark, Name:="\HeadingLevel")
With wdRng
j = Split(.Paragraphs.First.Style, " ")(1)
With .Paragraphs.First.Range
xlRng.Offset(i, 4 + j) = .ListFormat.ListString & " " & .Text
End With
End With
Loop
End With
Next
End With
' Make the Excel workbook visible
xlApp.Visible = True
' Clean up our objects
Set wdRng = Nothing: Set wdCmt = Nothing: Set wdDoc = Nothing
Set xlRng = Nothing: Set xlWB = Nothing: Set xlApp = Nothing
End Sub
You can add more columns for data such as:
.Scope.Paragraphs(1).Range.Text
.Scope.Paragraphs(1).Range.ListFormat.ListString
and so on.
Upvotes: 2