In Microsoft Word, it is possible to a list of just the tracked changes; see the first point of this blog post. Is there a way to do this in LibreOffice? From searching the answer appears to be “no” but wanted to do a hive mind check that I’m not missing something. I can see that I can print comments only, from the print dialog, but nowhere to get just changes.
did you mean to post this as a reply to my question? it seems like it is a separate question
You want a feature that currently isn’t available in LibreOffice; the link tells you how to make a request to have it added.
My question was “Does this functionality currently exist somewhere in the application?” not “How do I file a feature request?”, in an attempt to not file FR’s for things that already exist. But I’ll take I guess both of these answers as implied “No this functionality does not exist” answers.
I think that is as close to No, it doesn’t exist as makes no difference.
This could be a rewarding task for a macro coder.
Starting version (0.2) of the macro.
Activate the document containing Track Changes and execute the ShowTrackChanges2 macro (without parameter).
' Shows Track Changes in a separate Calc document.
Sub ShowTrackChanges2(Optional ByVal oDoc As Object)
Dim dataArray(), ind As Long, n as Long, oRedlines As Object, oViewCursor As Object
Dim oCalcDoc As Object, oRange As Object, oColumns as Object, nf As Long, page, s As String
Dim oLocale As New com.sun.star.lang.Locale
If IsMissing(oDoc) Then oDoc=ThisComponent
oRedlines=oDoc.RedLines
If oRedLines.Count=0 Then
Msgbox "No Track Changes"
Exit Sub
End If
oViewCursor=ThisComponent.CurrentController.getViewCursor()
n=oRedlines.Count
ReDim dataArray(n)
dataArray(0)=Array("DateTime", "Author", "Description", "Page", "Text", "Comment")
For ind=0 To n-1
With oRedLines(ind)
s=""
page=""
If (Not (.RedlineStart Is Nothing)) And (Not (.RedlineEnd Is Nothing)) Then
oViewCursor.gotoRange .RedlineStart, False
oViewCursor.gotoRange .RedlineEnd, True
page=oViewCursor.page
s=oViewCursor.String
End If
dataArray(ind+1)=Array(Cdbl(CDateFromUnoDateTime(.RedlineDateTime)), .RedlineAuthor, _
.RedlineDescription, page, s, .RedlineComment)
End With
Next ind
' Show DataArray
oCalcDoc = StarDesktop.LoadComponentFromUrl("private:factory/scalc","_default",0, Array())
oRange=oCalcDoc.Sheets(0).getCellRangeByPosition(0, 0, Ubound(DataArray(0)), Ubound(DataArray))
oRange.setDataArray dataArray
' Title style
oRange.getCellRangeByPosition(0, 0, oRange.Columns.Count-1, 0).CellStyle="Accent"
' NumberFormat
nf=oCalcDoc.NumberFormats.queryKey("YYYY-MM-DD HH:MM:SS", oLocale, false)
oRange.getCellRangeByPosition(0, 1, 0, oRange.Rows.Count-1).NumberFormat=nf
oColumns=oRange.Spreadsheet.Columns
' AutoFilter
oCalcDoc.DatabaseRanges.addNewByName("db_1", oRange.RangeAddress)
oCalcDoc.DatabaseRanges.getByName("db_1").autoFilter=True
' OptimalWidth
For ind = 0 To 3
oColumns.getByIndex(ind).OptimalWidth=True
Next ind
oColumns(4).Width=10000
oColumns(5).Width=5000
oRange.getCellRangeByPosition(4, 1, 5, oRange.Rows.Count-1).IsTextWrapped=True
End Sub
OP here, just using this macro again for the first time in a while. Two things: (A) Thank you. It is completely amazing that you wrote this *checks timestamps* 22 hours after it was suggested that it be a macro. It is very useful as it is (and, in fact, superior to the Word version which is not sortable). (B) feature request: would it be possible to have comments show up in the sheet? The sheet has a column entitled entitled “Comments” but it doesn’t seem to get populated. For me, so long as comments get a row like other changes with their timestamp and their text, it doesn’t really matter to me what column the comment text is in. If “Description” said “Comment” and the “Text” had the comment text, that works. Or the comment text could go in a “Comment” column to indicate it was a comment. Whatever is easier to implement.
Hello!
The use of the “Comment” field can be illustrated by the example above from colleague @fpy .
- Select the deleted or changed fragment.
-
Menu
/Edit
/Track Changes
/Comment
Enter a comment for the change made and click OK. - Click the Show changes… button.
Thanks for getting back to me quickly. It seems like the word “Comment” is used to refer to two data types in LibreOffice: (1) a comment that is part of a tracked change (your use, which I wasn’t previously aware of), and (2) a comment on the document, which one adds via insert->comment (my use, I’ll call these “comments type 2”). My enhancement request, should you choose to implement it, would be to somehow include comments type 2 in this export of tracked changes. The reason is that comments type 2 are more commonly used in general, and are in particular commonly used to explain reasons for tracked changes. So while comment type 2 are perhaps not literally (in a Libre Office data structure sense) part of tracked changes they are, in how people use them, a part of the tracked changes. So in my use case the purpose is to see, in a large document, just a summary of proposed changes, plus comments type 2, where authors often give reasons for their changes. I often have to review large change sets and this makes it faster and easier. In the implementation in MS Word (which AFAIK does not have comments type 1), comments are included when it prints tracked changes. What Word does is not definitive of course, but it does tend to indicate that including comments type 2 in a list of tracked changes is not just my particular use case, but something that has been useful for others. Thanks for considering.
Thanks for the informative answer!
If we show comments of type 2, there may be problems with sorting.
Let’s try.
Please upload a more complicated example and we’ll try. I can’t promise to do it quickly, as I’m very busy right now.
Sure, no problem if it takes time. Here is an example that has changes from two different authors. The first has a comment type 2 on it, the second has a comment type 1 on it. If you want a longer example let me know but this seems to have one instance of all the things we may want to show.
Write the macro however it makes sense for you. However one way that comes to mind to avoid sorting issues is to just use the same columns, and for comments type 2, to just put the text “Comment” in the Description column (hard-coded, says “Comment” for all comments type 2), and the comment’s text goes in the “Text” row. This may seem unpleasant as a programmer since it is no longer a clear 1:1 mapping from the track changes data into the ods sheet, but it would seem clear to me as a user.
Then maybe change the header of Column F to be “Track Changes Comment” so users who are not aware that comment type 1 exists are maybe slightly less confused by the two types of “comment” that appear in the sheet.
If the output of the macro can sort the rows by DateTime that’s great, but if the comments (type 2) come after the changes, no big deal for the user to sort by DateTime in Calc.
Once we have this implemented I’ll put in a feature request in bugzilla for this to get added to the macros that ship with LibreOffice. It already has a lot of macros and it seems like a better place for it to permanently reside, and the devs said in my last FR “The proposed macro solution seems to be the right way to tackle this niche use case”.
Test File For Changes Macro.odt (13.6 KB)
Let’s try the new version of the macro.
I added a PosY
column, which shows the vertical distance from the beginning of the document - can be useful for sorting.
The Comment
column has been removed. Comments of type 1
are reflected in the Text
column via a line break.
' https://ask.libreoffice.org/t/is-there-any-way-to-print-a-list-of-only-tracked-changes-without-the-rest-of-the-document-in-writer/104216?u=sokol92
' Shows Track Changes And Comments in a separate Calc document.
Sub ShowTrackChanges3(Optional ByVal oDoc As Object)
Dim dataArray(), ind As Long, i as Long, n as Long, oRedlines As Object, oViewCursor As Object
Dim oCalcDoc As Object, oRange As Object, oColumns as Object, oTextField as Object
Dim nf As Long, page, posY, s As String
Dim oLocale As New com.sun.star.lang.Locale
If IsMissing(oDoc) Then oDoc = ThisComponent
oViewCursor = ThisComponent.CurrentController.getViewCursor()
oRedlines=oDoc.RedLines
n = oRedlines.Count
ReDim dataArray(n + 999)
ind = 0
dataArray(ind)=Array("DateTime", "Author", "Description", "Page", "PosY", "Text")
' Track Changes
For i=0 To n-1
With oRedLines(i)
ind = ind + 1
s = ""
page = ""
posY = ""
If (Not (.RedlineStart Is Nothing)) And (Not (.RedlineEnd Is Nothing)) Then
oViewCursor.gotoRange .RedlineStart, False
oViewCursor.gotoRange .RedlineEnd, True
s = oViewCursor.String
posY = oViewCursor.Position.Y
page = oViewCursor.Page
End If
If .RedlineComment <> "" Then s = s & ":" & Chr(10) & .RedlineComment
dataArray(ind)=Array(Cdbl(CDateFromUnoDateTime(.RedlineDateTime)), .RedlineAuthor, _
.RedlineDescription, page, posY, s)
End With
Next i
' Comments
For Each oTextField In oDoc.TextFields
If oTextField.supportsService("com.sun.star.text.textfield.Annotation") Then
With oTextField.Anchor
ind = ind + 1
If ind > UBound(dataArray) Then
ReDim Preserve dataArray(UBound(dataArray) * 2)
End If
page = ""
posY = ""
If (Not (.Start Is Nothing)) And (Not (.End Is Nothing)) Then
oViewCursor.gotoRange .Start, False
oViewCursor.gotoRange .End, True
posY = oViewCursor.Position.Y
page = oViewCursor.page
End If
End With
With oTextField
dataArray(ind)=Array(Cdbl(CDateFromUnoDateTime(.DateTimeValue)), .Author, _
"", page, posY, .Content)
End With
End If
Next oTextField
If ind < 1 Then
Msgbox "No Track Changes or Comments"
Exit Sub
End If
ReDim Preserve dataArray(ind)
' Show DataArray
oCalcDoc = StarDesktop.LoadComponentFromUrl("private:factory/scalc","_default",0, Array())
oRange=oCalcDoc.Sheets(0).getCellRangeByPosition(0, 0, Ubound(dataArray(0)), Ubound(dataArray))
oRange.setDataArray dataArray
' Title style
oRange.getCellRangeByPosition(0, 0, oRange.Columns.Count-1, 0).CellStyle="Accent"
' NumberFormat
nf=oCalcDoc.NumberFormats.queryKey("YYYY-MM-DD HH:MM:SS", oLocale, false)
oRange.getCellRangeByPosition(0, 1, 0, oRange.Rows.Count-1).NumberFormat=nf
oColumns=oRange.Spreadsheet.Columns
' AutoFilter
oCalcDoc.DatabaseRanges.addNewByName("db_1", oRange.RangeAddress)
oCalcDoc.DatabaseRanges.getByName("db_1").autoFilter=True
' OptimalWidth
For ind = 0 To 5
oColumns.getByIndex(ind).OptimalWidth=True
Next ind
oColumns(5).Width=10000
oRange.getCellRangeByPosition(4, 1, 5, oRange.Rows.Count-1).IsTextWrapped=True
End Sub