Consulting

Page 1 of 2 1 2 LastLast
Results 1 to 20 of 26

Thread: Final hurdle for combined comment and revision grid

  1. #1
    VBAX Regular
    Joined
    Oct 2016
    Posts
    45
    Location

    Final hurdle for combined comment and revision grid

    So, many of the dumb questions that I've been asking recently are because I've been working on trying to update the famous comment and revision trackers by Lene Fredborg, DocTools. I claim no particular credit for any of the code below. Most of it is just modified from the Lene Fredborg original. I'm also indebted to macropod, gmayor and John Wilson for their extreme helpfulness while I've been trying to get to grips with VBA. All of this is to say: I am not attempting to steal any credit for other's hard work.

    However, I have hit a final brick wall that I am wasting a lot of time trying to get past and so I'm crying out for one last bit of help on this.

    The modified code is now a combined revision and comment grid maker, with options to do one or the other (or both). It also gives you the option to exclude comments and revisions from specific authors.

    But I'm having a problem that I can't seem to get around at the last part. For some reason, I can no longer populate the final table with the details of the tracked insertions and deletions. It is still counting them, and creating the right number of rows, but it is not populating the cells with the information for each revision. Obviously that's a problem!

    When you look at the code, you may wonder why I've gone for cycling through revisions using "For integer = 1 to revision counts" loops, instead of using the neater "For Each Revision in ActiveDocument.Revisions". I've found that using the neater method creates a runtime error if there are overlapping revisions, in which VBA seems to fall over in trying to define the Revision.Type.

    So I used the messier 'For 1 to...' method to get around this. I know this seems to work in the other instances of the code, as it is producing an accurate list of revision authors and number of insertions and deletions. But it seems to be failing at the last bit of the macro (in the "Tracks:" section), so I end up with a blank table. If anyone can work out why it is doing this, and how I can get around it, while still avoiding the runtime error that comes from "For Each Revision...", you'll have made my week. Maybe my year.

    Public Sub Rev_and_Comm_Tracker()
    
        Dim oDoc, oNewDoc As Document
        Dim oTable As Table
        Dim oRange As Range
        Dim nCount, n, i, numRows, rCount, rCount2, rTb, cTb, blRows, cax, rax, b, c, d, j, k, w, x, y, z, cmCounter, revCounter, sCmtTally, sRevTally As Long
        Dim noCol As Integer
        Dim Title, strText, selType, selType2, finSel, exAuth, exRev, exAuthNum, exRevNum, Auth2ex1, Auth2ex2, Auth2ex3, Auth2ex4, Auth2ex5 As String
        Dim Rev2ex1, Rev2ex2, Rev2ex3, Rev2ex4, Rev2ex5, initCSum, initRSum As String
        Dim sCmAuTxt1, sCmAuTxt2, sCmAuTxt3, sCmAuTxt4, sRvAuTxt1, sRvAuTxt2, sRvAuTxt3, sRvAuTxt4, stCmtAuth, stRvAuth, sAllCmtAus, sAllRvAus, CmtMax, RvMax As String
        Dim CmtOne, RvOne, CmtMaxOp, RvMaxOp, CmtAuNum, RvAuNum, AuNumRet, RevNumRet, CmntCnter, RevCnter, CmntSmmry, RvSmmry As String
        Dim CmtAuArr() As String
        Dim RvAuArr() As String
        Dim strType, strPage, strAuthor, strSort As String
        Dim CmtMkrs As New Collection, a
        Dim RvMkrs As New Collection, g
        
        sCmAuTxt1 = "The following people have made comments:" & vbNewLine & vbNewLine: sCmAuTxt2 = vbNewLine & "Enter the name of the ": sCmAuTxt3 = "commenter to exclude, exactly as it appears above (without the list number)." & vbNewLine & vbNewLine & "Leaving this box empty will exit the macro.": sCmAuTxt4 = " reviewer to exclude"
        sRvAuTxt1 = "The following people have made tracked insertions or deletions:" & vbNewLine & vbNewLine: sRvAuTxt2 = vbNewLine & "Enter the name of the ": sRvAuTxt3 = "reviewer to exclude, exactly as it appears above." & vbNewLine & vbNewLine & "Leaving this box empty will exit the macro.": sRvAuTxt4 = " reviewer to exclude"
        
        Title = "Comment and revision tracker"
        n = 0
        rCount2 = 0
        Set oDoc = ActiveDocument
        nCount = ActiveDocument.Comments.Count
        rCount = oDoc.Revisions.Count
           
           Application.ScreenUpdating = False
        Selection.HomeKey Unit:=wdStory
        For w = 1 To rCount
            Selection.NextRevision
            If Selection.Range.Revisions(1).Type = wdRevisionDelete Or wdRevisionInsert Then
                rCount2 = rCount2 + 1
            Else
                GoTo Nextw
            End If
                
    Nextw:
        Next w
        
        Selection.HomeKey Unit:=wdStory
        Application.ScreenUpdating = True
        
        If nCount = 0 Then
            initCSum = ""
        ElseIf nCount > 0 Then
            initCSum = "There are " & nCount & " comments in this document." & vbNewLine & vbNewLine
        End If
       
        If rCount2 = 0 Then
            initRSum = ""
        ElseIf rCount2 > 0 Then
            initRSum = "There are " & rCount2 & " eligible tracked insertions and deletions in this document." & vbNewLine & vbNewLine
        End If
        
        If (nCount = 0) And (rCount2 = 0) Then
            MsgBox "There are no comments or revisions to extract.", vbOKOnly + vbCritical, Title
            GoTo ExitHere
        End If
        
        If MsgBox("This macro can extract comments and tracked insertions" & vbNewLine & "or deletions but not other types of tracked changes." _
        & vbNewLine & vbNewLine & initCSum & initRSum & "Continue?", vbYesNo) = vbNo Then GoTo ExitHere
       
        If (rCount2 = 0) And (nCount > 0) Then
            finSel = "Comments"
            RvSmmry = ""
            GoTo ExclAuth
        ElseIf (rCount2 > 0) And (nCount = 0) Then
            finSel = "Tracks"
            CmntSmmry = ""
            GoTo Start
        ElseIf (rCount2 > 0) And (nCount > 0) Then
            selType = MsgBox("Do you want to extract both comments and revisions*?" & vbNewLine & vbNewLine & "Yes:" & vbTab & "Extract both" & vbNewLine & "No:" & vbTab & "To choose which to extract" & vbNewLine & "Cancel:" & vbTab & "To exit" & vbNewLine & vbNewLine & "*Only insertions and deletions will be extracted", vbYesNoCancel, "Customise extraction")
                If selType = vbCancel Then
                    GoTo ExitHere
                ElseIf selType = vbYes Then
                    finSel = "Both"
                ElseIf selType = vbNo Then
                    selType2 = MsgBox("Do you want to extract comments or revisions?" & vbNewLine & vbNewLine & "Yes:" & vbTab & "Extract comments" & vbNewLine & "No:" & vbTab & "Extract revisions*" & vbNewLine & "Cancel:" & vbTab & "To exit" & vbNewLine & vbNewLine & "*Only insertions and deletions will be extracted", vbYesNoCancel, "Choose comments or revisions")
                        If selType2 = vbCancel Then
                            GoTo ExitHere
                        ElseIf selType2 = vbYes Then
                            finSel = "Comments"
                            RvSmmry = ""
                        ElseIf selType2 = vbNo Then
                            finSel = "Tracks"
                            CmntSmmry = ""
                        End If
                End If
        End If
        
    ExclAuth:
        If Not finSel = "Tracks" Then
            blDimensioned = False
            For n = 1 To nCount
                stCmtAuth = ActiveDocument.Comments(n).Author
                If stCmtAuth <> "" Then
                    If blDimensioned = True Then
                        ReDim Preserve CmtAuArr(0 To UBound(CmtAuArr) + 1) As String
                    Else
                        ReDim CmtAuArr(0 To 0) As String
                        CmtAuArr(0) = ""
                        blDimensioned = True
                    End If
                    CmtAuArr(UBound(CmtAuArr)) = stCmtAuth
                End If
            Next
            
            sAllCmtAus = ""
            
            On Error Resume Next
            For Each a In CmtAuArr
                CmtMkrs.Add a, a
            Next
            
            For cax = 1 To CmtMkrs.Count
                sAllCmtAus = sAllCmtAus & cax & ". " & CmtMkrs(cax) & vbNewLine
            Next
            
            Erase CmtAuArr
            
            If CmtMkrs.Count > 5 Then
                CmtMax = 5
                CmtMaxOp = "You can exclude comments from a maximum of 5 people."
            ElseIf CmtMkrs.Count <= 5 Then
                CmtMax = CmtMkrs.Count - 1
            End If
            
            If CmtMax > 1 Then
                CmtMaxOp = "You can exclude comments from a maximum of " & CmtMax & " people."
            ElseIf CmtMax = 1 Then
                CmtMaxOp = "As there are only comments from 2 people, you can" & vbNewLine & "only choose to exclude a maximum of 1 person."
            ElseIf CmtMax = 0 Then
                CmtOne = MsgBox("There are only comments from 1 person, so you can't exclude any authors from the tracker.", vbOKCancel)
                If CmtOne = vbCancel Then
                    GoTo ExitHere
                Else
                    GoTo Start
                End If
            End If
            
            CmtAuNum = CmtMkrs.Count
            
            exAuth = MsgBox("There are comments from " & CmtAuNum & " different people." & vbNewLine & vbNewLine & "Do you want to exclude any commenters?", vbYesNoCancel + vbInformation, "Exclude authors")
            If exAuth = vbNo Then
                CmntSmmry = "All " & nCount & " comments from " & CmtAuNum & " authors were extracted." & vbNewLine & vbNewLine
                cTb = nCount
                If finSel = "Comments" Then
                    GoTo Start
                ElseIf finSel = "Both" Then
                    GoTo ExclRev
                End If
            ElseIf exAuth = vbCancel Then
                GoTo ExitHere
            ElseIf exAuth = vbYes Then
    
    
    ChooseAuNum:
                If CmtMax = 1 Then
                    exAuthNum = MsgBox(CmtMaxOp & vbNewLine & vbNewLine & "Click CANCEL to exit.", vbOKCancel, "Exclude author")
                    If exAuthNum = vbOK Then
                        exAuthNum = 1
                    ElseIf exAuthNum = vbCancel Then
                        GoTo ExitHere
                    End If
                ElseIf CmtMax = 2 Or 3 Or 4 Or 5 Then
                    exAuthNum = InputBox(sCmAuTxt1 & sAllCmtAus & vbNewLine & CmtMaxOp & vbNewLine & vbNewLine & "Enter the number of people to exclude below", "Number to exclude")
                End If
                
                If (exAuthNum = 0) Or (exAuthNum = "") Then
                    AuNumRet = MsgBox("Do you want to continue without excluding any authors?" & vbNewLine & vbNewLine & "Click YES to proceed without excluding an author." & vbNewLine & vbNewLine & "Press NO to go back and input a valid number." & vbNewLine & vbNewLine & "Press CANCEL to exit", vbYesNoCancel + vbQuestion, "Error!")
                    If AuNumRet = vbCancel Then
                        GoTo ExitHere
                    ElseIf AuNumRet = vbYes Then
                        CmntSmmry = "All " & nCount & " comments from " & CmtAuNum & " authors were extracted." & vbNewLine & vbNewLine
                        GoTo Start
                    ElseIf AuNumRet = vbNo Then
                        GoTo ChooseAuNum
                    End If
                ElseIf (exAuthNum > CmtMaxOp) Or (IsNumeric(exAuthNum) = False) Then
                    AuNumRet = MsgBox("You have entered an invalid value." & vbNewLine & vbNewLine & "Click RETRY to try again or CANCEL to exit", vbRetryCancel + vbCritical, "Error!")
                    If AuNumRet = vbCancel Then
                        GoTo ExitHere
                    ElseIf AuNumRet = vbRetry Then
                        GoTo ChooseAuNum
                    End If
                End If
                
                If exAuthNum = 1 Then
                    Auth2ex1 = InputBox(sCmAuTxt1 & sAllCmtAus & vbNewLine & sCmAuTxt2 & sCmAuTxt3, "Author to exclude")
                        If Auth2ex1 = "" Then End
                    Auth2ex2 = "Null and void": Auth2ex3 = "Null and void": Auth2ex4 = "Null and void": Auth2ex5 = "Null and void"
                ElseIf exAuthNum = 2 Then
                    Auth2ex1 = InputBox(sCmAuTxt1 & sAllCmtAus & vbNewLine & sCmAuTxt2 & "1st " & sCmAuTxt3, "1st " & sCmAuTxt4)
                        If Auth2ex1 = "" Then End
                    Auth2ex2 = InputBox(sCmAuTxt1 & sAllCmtAus & vbNewLine & sCmAuTxt2 & "2nd " & sCmAuTxt3, "2nd " & sCmAuTxt4)
                        If Auth2ex2 = "" Then End
                    Auth2ex3 = "Null and void": Auth2ex4 = "Null and void": Auth2ex5 = "Null and void"
                ElseIf exAuthNum = 3 Then
                    Auth2ex1 = InputBox(sCmAuTxt1 & sAllCmtAus & vbNewLine & sCmAuTxt2 & "1st " & sCmAuTxt3, "1st " & sCmAuTxt4)
                        If Auth2ex1 = "" Then End
                    Auth2ex2 = InputBox(sCmAuTxt1 & sAllCmtAus & vbNewLine & sCmAuTxt2 & "2nd " & sCmAuTxt3, "2nd " & sCmAuTxt4)
                        If Auth2ex2 = "" Then End
                    Auth2ex3 = InputBox(sCmAuTxt1 & sAllCmtAus & vbNewLine & sCmAuTxt2 & "3rd " & sCmAuTxt3, "3rd " & sCmAuTxt4)
                        If Auth2ex3 = "" Then End
                    Auth2ex4 = "Null and void": Auth2ex5 = "Null and void"
                ElseIf exAuthNum = 4 Then
                    Auth2ex1 = InputBox(sCmAuTxt1 & sAllCmtAus & vbNewLine & sCmAuTxt2 & "1st " & sCmAuTxt3, "1st " & sCmAuTxt4)
                        If Auth2ex1 = "" Then End
                    Auth2ex2 = InputBox(sCmAuTxt1 & sAllCmtAus & vbNewLine & sCmAuTxt2 & "2nd " & sCmAuTxt3, "2nd " & sCmAuTxt4)
                        If Auth2ex2 = "" Then End
                    Auth2ex3 = InputBox(sCmAuTxt1 & sAllCmtAus & vbNewLine & sCmAuTxt2 & "3rd " & sCmAuTxt3, "3rd " & sCmAuTxt4)
                        If Auth2ex3 = "" Then End
                    Auth2ex4 = InputBox(sCmAuTxt1 & sAllCmtAus & vbNewLine & sCmAuTxt2 & "4th " & sCmAuTxt3, "4th " & sCmAuTxt4)
                        If Auth2ex4 = "" Then End
                    Auth2ex5 = "Null and void"
                ElseIf exAuthNum = 5 Then
                    Auth2ex1 = InputBox(sCmAuTxt1 & sAllCmtAus & vbNewLine & sCmAuTxt2 & "1st " & sCmAuTxt3, "1st " & sCmAuTxt4)
                        If Auth2ex1 = "" Then End
                    Auth2ex2 = InputBox(sCmAuTxt1 & sAllCmtAus & vbNewLine & sCmAuTxt2 & "2nd " & sCmAuTxt3, "2nd " & sCmAuTxt4)
                        If Auth2ex2 = "" Then End
                    Auth2ex3 = InputBox(sCmAuTxt1 & sAllCmtAus & vbNewLine & sCmAuTxt2 & "3rd " & sCmAuTxt3, "3rd " & sCmAuTxt4)
                        If Auth2ex3 = "" Then End
                    Auth2ex4 = InputBox(sCmAuTxt1 & sAllCmtAus & vbNewLine & sCmAuTxt2 & "4th " & sCmAuTxt3, "4th " & sCmAuTxt4)
                        If Auth2ex4 = "" Then End
                    Auth2ex5 = InputBox(sCmAuTxt1 & sAllCmtAus & vbNewLine & sCmAuTxt2 & "5th " & sCmAuTxt3, "5th " & sCmAuTxt4)
                        If Auth2ex5 = "" Then End
                Else
                    End
                End If
            End If
            
    CommCount:
        If exAuthNum = 1 Then
            CmntCnter = vbCr: cmCounter = Array(Auth2ex1)
        ElseIf exAuthNum = 2 Then
            CmntCnter = vbCr: cmCounter = Array(Auth2ex1, Auth2ex2)
        ElseIf exAuthNum = 3 Then
            CmntCnter = vbCr: cmCounter = Array(Auth2ex1, Auth2ex2, Auth2ex3)
        ElseIf exAuthNum = 4 Then
            CmntCnter = vbCr: cmCounter = Array(Auth2ex1, Auth2ex2, Auth2ex3, Auth2ex4)
        ElseIf exAuthNum = 5 Then
            CmntCnter = vbCr: cmCounter = Array(Auth2ex1, Auth2ex2, Auth2ex3, Auth2ex4, Auth2ex5)
        End If
        
        For b = LBound(cmCounter) To UBound(cmCounter)
            c = 0
            For d = 1 To nCount
                With oDoc.Comments(d)
                    If .Author = cmCounter(b) Then c = c + 1
                End With
            Next
        Next
        
        sCmtTally = nCount - c: cTb = nCount - c
        
        CmntSmmry = "Extracted:" & vbTab & vbTab & vbTab & sCmtTally & " comments from " & (CmtAuNum - exAuthNum) & " authors." & vbNewLine & "Total in document:" & vbTab & vbTab & nCount & " comments from " & CmtAuNum & " authors." & vbNewLine & vbNewLine
    
    
        End If
        
        If finSel = "Comments" Then GoTo Start
    
    
    ExclRev:
        If Not finSel = "Comments" Then
            blDimensioned = False
            Application.ScreenUpdating = False
            Selection.HomeKey Unit:=wdStory
            
            For x = 1 To rCount
                Selection.NextRevision
                If Selection.Range.Revisions(1).Type = wdRevisionDelete Or wdRevisionInsert Then
                    With Selection.Range.Revisions(1)
                        stRvAuth = .Author
                        If stRvAuth <> "" Then
                            If blDimensioned = True Then
                                ReDim Preserve RvAuArr(0 To UBound(RvAuArr) + 1) As String
                            Else
                                ReDim RvAuArr(0 To 0) As String
                                RvAuArr(0) = ""
                                blDimensioned = True
                            End If
                            RvAuArr(UBound(RvAuArr)) = stRvAuth
                        End If
                    End With
                 End If
            Next x
            
           
            sAllRvAus = ""
            
            On Error Resume Next
            For Each g In RvAuArr
                RvMkrs.Add g, g
            Next
            
            For rax = 1 To RvMkrs.Count
                sAllRvAus = sAllRvAus & rax & ". " & RvMkrs(rax) & vbNewLine
            Next
            
            Erase RvAuArr
            
            If RvMkrs.Count > 5 Then
                RvMax = 5
                RvMaxOp = "You can exclude tracked insertions or deletions from a maximum of 5 people."
            ElseIf RvMkrs.Count <= 5 Then
                RvMax = RvMkrs.Count - 1
            End If
            
            If RvMax > 1 Then
                RvMaxOp = "You can exclude tracked insertions or deletions from a maximum of " & RvMax & " people."
            ElseIf RvMax = 1 Then
                RvMaxOp = "As there are only tracked insertions or deletions from 2 people, you can" & vbNewLine & "only choose to exclude a maximum of 1 person."
            ElseIf RvMax = 0 Then
                RvOne = MsgBox("There are only tracked insertions or deletions from 1 person, so you can't exclude any reviewers from the tracker.", vbOKCancel)
                If RvOne = vbCancel Then
                    GoTo ExitHere
                Else
                    GoTo Start
                End If
            End If
            
            RvAuNum = RvMkrs.Count
            
            exRev = MsgBox("There are tracked insertions or deletions from " & RvAuNum & " different people." & vbNewLine & vbNewLine & "Do you want to exclude any reviewers?", vbYesNoCancel + vbInformation, "Exclude reviewers")
            If exRev = vbNo Then
                RvSmmry = "All " & rCount2 & " tracked insertions or deletions from " & RvAuNum & " people were extracted." & vbNewLine & vbNewLine
                rTb = rCount2
                GoTo Start
            ElseIf exRev = vbCancel Then
                GoTo ExitHere
            ElseIf exRev = vbYes Then
    
    
    ChooseRevNum:
                If RvMax = 1 Then
                    exRevNum = MsgBox(RvMaxOp & vbNewLine & vbNewLine & "Click CANCEL to exit.", vbOKCancel, "Exclude reviewer")
                    If exRevNum = vbOK Then
                        exRevNum = 1
                    ElseIf exRevNum = vbCancel Then
                        GoTo ExitHere
                    End If
                ElseIf RvMax = 2 Or 3 Or 4 Or 5 Then
                    exRevNum = InputBox(sRvAuTxt1 & sAllRvAus & vbNewLine & RvMaxOp & vbNewLine & vbNewLine & "Enter the number of people to exclude below", "Number to exclude")
                End If
                
                If (exRevNum = 0) Or (exRevNum = "") Then
                    RevNumRet = MsgBox("Do you want to continue without excluding any reviewers?" & vbNewLine & vbNewLine & "Click YES to proceed without excluding a reviewer." & vbNewLine & vbNewLine & "Press NO to go back and input a valid number." & vbNewLine & vbNewLine & "Press CANCEL to exit", vbYesNoCancel + vbQuestion, "Error!")
                    If RevNumRet = vbCancel Then
                        GoTo ExitHere
                    ElseIf RevNumRet = vbYes Then
                        RvSmmry = "All " & rCount2 & " tracked insertions or deletions from " & RvAuNum & " people were extracted." & vbNewLine & vbNewLine
                        rTb = rCount2
                        GoTo Start
                    ElseIf RevNumRet = vbNo Then
                        GoTo ChooseRevNum
                    End If
                ElseIf (exRevNum > RvMaxOp) Or (IsNumeric(exRevNum) = False) Then
                    RevNumRet = MsgBox("You have entered an invalid value." & vbNewLine & vbNewLine & "Click RETRY to try again or CANCEL to exit", vbRetryCancel + vbCritical, "Error!")
                    If RevNumRet = vbCancel Then
                        GoTo ExitHere
                    ElseIf RevNumRet = vbRetry Then
                        GoTo ChooseRevNum
                    End If
                End If
                
                If exRevNum = 1 Then
                    Rev2ex1 = InputBox(sRvAuTxt1 & sAllRvAus & vbNewLine & sRvAuTxt2 & sRvAuTxt3, "Reviewer to exclude")
                        If Rev2ex1 = "" Then End
                    Rev2ex2 = "Null and void": Rev2ex3 = "Null and void": Rev2ex4 = "Null and void": Rev2ex5 = "Null and void"
                ElseIf exRevNum = 2 Then
                    Rev2ex1 = InputBox(sRvAuTxt1 & sAllRvAus & vbNewLine & sRvAuTxt2 & "1st " & sRvAuTxt3, "1st " & sRvAuTxt4)
                        If Rev2ex1 = "" Then End
                    Rev2ex2 = InputBox(sRvAuTxt1 & sAllRvAus & vbNewLine & sRvAuTxt2 & "2nd " & sRvAuTxt3, "2nd " & sRvAuTxt4)
                        If Rev2ex2 = "" Then End
                    Rev2ex3 = "Null and void": Rev2ex4 = "Null and void": Rev2ex5 = "Null and void"
                ElseIf exRevNum = 3 Then
                    Rev2ex1 = InputBox(sRvAuTxt1 & sAllRvAus & vbNewLine & sRvAuTxt2 & "1st " & sRvAuTxt3, "1st " & sRvAuTxt4)
                        If Rev2ex1 = "" Then End
                    Rev2ex2 = InputBox(sRvAuTxt1 & sAllRvAus & vbNewLine & sRvAuTxt2 & "2nd " & sRvAuTxt3, "2nd " & sRvAuTxt4)
                        If Rev2ex2 = "" Then End
                    Rev2ex3 = InputBox(sRvAuTxt1 & sAllRvAus & vbNewLine & sRvAuTxt2 & "3rd " & sRvAuTxt3, "3rd " & sRvAuTxt4)
                        If Rev2ex3 = "" Then End
                    Rev2ex4 = "Null and void": Rev2ex5 = "Null and void"
                ElseIf exRevNum = 4 Then
                    Rev2ex1 = InputBox(sRvAuTxt1 & sAllRvAus & vbNewLine & sRvAuTxt2 & "1st " & sRvAuTxt3, "1st " & sRvAuTxt4)
                        If Rev2ex1 = "" Then End
                    Rev2ex2 = InputBox(sRvAuTxt1 & sAllRvAus & vbNewLine & sRvAuTxt2 & "2nd " & sRvAuTxt3, "2nd " & sRvAuTxt4)
                        If Rev2ex2 = "" Then End
                    Rev2ex3 = InputBox(sRvAuTxt1 & sAllRvAus & vbNewLine & sRvAuTxt2 & "3rd " & sRvAuTxt3, "3rd " & sRvAuTxt4)
                        If Rev2ex3 = "" Then End
                    Rev2ex4 = InputBox(sRvAuTxt1 & sAllRvAus & vbNewLine & sRvAuTxt2 & "4th " & sRvAuTxt3, "4th " & sRvAuTxt4)
                        If Rev2ex4 = "" Then End
                    Rev2ex5 = "Null and void"
                ElseIf exRevNum = 5 Then
                    Rev2ex1 = InputBox(sRvAuTxt1 & sAllRvAus & vbNewLine & sRvAuTxt2 & "1st " & sRvAuTxt3, "1st " & sRvAuTxt4)
                        If Rev2ex1 = "" Then End
                    Rev2ex2 = InputBox(sRvAuTxt1 & sAllRvAus & vbNewLine & sRvAuTxt2 & "2nd " & sRvAuTxt3, "2nd " & sRvAuTxt4)
                        If Rev2ex2 = "" Then End
                    Rev2ex3 = InputBox(sRvAuTxt1 & sAllRvAus & vbNewLine & sRvAuTxt2 & "3rd " & sRvAuTxt3, "3rd " & sRvAuTxt4)
                        If Rev2ex3 = "" Then End
                    Rev2ex4 = InputBox(sRvAuTxt1 & sAllRvAus & vbNewLine & sRvAuTxt2 & "4th " & sRvAuTxt3, "4th " & sRvAuTxt4)
                        If Rev2ex4 = "" Then End
                    Rev2ex5 = InputBox(sRvAuTxt1 & sAllRvAus & vbNewLine & sRvAuTxt2 & "5th " & sRvAuTxt3, "5th " & sRvAuTxt4)
                        If Rev2ex5 = "" Then End
                Else
                    End
                End If
            End If
            
    RevCount:
        If exRevNum = 1 Then
            RevCnter = vbCr: revCounter = Array(Rev2ex1)
        ElseIf exRevNum = 2 Then
            RevCnter = vbCr: revCounter = Array(Rev2ex1, Rev2ex2)
        ElseIf exRevNum = 3 Then
            RevCnter = vbCr: revCounter = Array(Rev2ex1, Rev2ex2, Rev2ex3)
        ElseIf exRevNum = 4 Then
            RevCnter = vbCr: revCounter = Array(Rev2ex1, Rev2ex2, Rev2ex3, Rev2ex4)
        ElseIf exRevNum = 5 Then
            RevCnter = vbCr: revCounter = Array(Rev2ex1, Rev2ex2, Rev2ex3, Rev2ex4, Rev2ex5)
        End If
        
        For j = LBound(revCounter) To UBound(revCounter)
            k = 0
            
            Application.ScreenUpdating = False
            Selection.HomeKey Unit:=wdStory
            For y = 1 To rCount
                Selection.NextRevision
                If (Selection.Range.Revisions(1).Type = wdRevisionDelete Or wdRevisionInsert) _
                    And (Selection.Range.Revisions(1).Author = revCounter(j)) Then k = k + 1
            Next y
        Next j
        
        Selection.HomeKey Unit:=wdStory
        Application.ScreenUpdating = True
        
        sRevTally = rCount2 - k: rTb = rCount2 = k
        
        RvSmmry = "Extracted:" & vbTab & vbTab & vbTab & sRevTally & " revisions from " & (RvAuNum - exRevNum) & " reviewers." & vbNewLine & "Total in document:" & vbTab & vbTab & rCount2 & " tracked insertions or deletions from" & vbNewLine & vbTab & vbTab & vbTab & RvAuNum & " people." & vbNewLine & vbNewLine
    
    
        End If
    
    
    Start:
        MsgBox "Word may appear to freeze during this process!" & vbNewLine & vbNewLine & "Don't panic! Word has not crashed. Just wait for the process to finish." & vbNewLine & vbNewLine & "The more revisions and comments there are, the longer the process will take.", vbOKOnly, "DON'T PANIC!"
        Application.ScreenUpdating = False
        Set oNewDoc = Documents.Add
        oNewDoc.PageSetup.Orientation = wdOrientLandscape
        With oNewDoc
            .Content = ""
            If finSel = "Comments" Then
                Set oTable = .Tables.Add _
                    (Range:=Selection.Range, _
                    numRows:=cTb + 1, _
                    NumColumns:=7)
            ElseIf finSel = "Tracks" Then
                Set oTable = .Tables.Add _
                    (Range:=Selection.Range, _
                    numRows:=rTb + 1, _
                    NumColumns:=7)
            ElseIf finSel = "Both" Then
                Set oTable = .Tables.Add _
                    (Range:=Selection.Range, _
                    numRows:=cTb + rTb + 1, _
                    NumColumns:=7)
            End If
        End With
       
        If finSel = "Comments" Then
            oNewDoc.Sections(1).Headers(wdHeaderFooterPrimary).Range.Text = _
                "Comments extracted from: " & oDoc.Name
        ElseIf finSel = "Tracks" Then
            oNewDoc.Sections(1).Headers(wdHeaderFooterPrimary).Range.Text = _
                "Revisions extracted from: " & oDoc.Name
        ElseIf finSel = "Both" Then
            oNewDoc.Sections(1).Headers(wdHeaderFooterPrimary).Range.Text = _
                "Comments and revisions extracted from: " & oDoc.Name
        End If
    
    
        With oNewDoc.Styles(wdStyleNormal)
            .Font.Name = "Calibri"
            .Font.Size = 9
            .ParagraphFormat.LeftIndent = 0
            .ParagraphFormat.SpaceAfter = 6
        End With
       
        With oNewDoc.Styles(wdStyleHeader)
            .Font.Size = 8
            .ParagraphFormat.SpaceAfter = 0
        End With
    
    
        With oTable
            .Range.Style = wdStyleNormal
            .AllowAutoFit = False
            .PreferredWidthType = wdPreferredWidthPercent
            .PreferredWidth = 100
            .Columns.PreferredWidthType = wdPreferredWidthPercent
            .Columns(1).PreferredWidth = 5
            .Columns(2).PreferredWidth = 10
            .Columns(3).PreferredWidth = 25
            .Columns(4).PreferredWidth = 25
            .Columns(5).PreferredWidth = 15
            .Columns(6).PreferredWidth = 30
            .Columns(7).PreferredWidth = 2
            .Rows(1).HeadingFormat = True
        End With
    
    
        With oTable.Rows(1)
            .Range.Font.Bold = True
            .Cells(1).Range.Text = "Page"
            .Cells(2).Range.Text = "Type"
            .Cells(3).Range.Text = "Comment"
            .Cells(4).Range.Text = "Relevant text"
            .Cells(5).Range.Text = "Commenter"
            .Cells(6).Range.Text = "Action/response"
            .Cells(7).Range.Text = "Sort"
        End With
        
        If (finSel = "Both" Or finSel = "Comments") Then
            GoTo Comments
        Else
            If finSel = "Tracks" Then
                GoTo Tracks
            End If
        End If
       
    Comments:
        For n = 1 To nCount
            If (oDoc.Comments(n).Author = Auth2ex1) Or (oDoc.Comments(n).Author = Auth2ex2) Or (oDoc.Comments(n).Author = Auth2ex3) Or (oDoc.Comments(n).Author = Auth2ex4) Or (oDoc.Comments(n).Author = Auth2ex5) Then
                GoTo NextN
            Else
                With oTable.Rows(n + 1)
                    .Cells(1).Range.Text = _
                        oDoc.Comments(n).Scope.Information(wdActiveEndPageNumber)
                    .Cells(2).Range.Text = "Comment"
                    .Cells(3).Range.Text = oDoc.Comments(n).Range.Text
                    .Cells(4).Range.Text = oDoc.Comments(n).Scope
                    .Cells(5).Range.Text = oDoc.Comments(n).Author
                    .Cells(7).Range.Text = oDoc.Comments(n).Scope.Information(wdFirstCharacterLineNumber)
                End With
                GoTo NextN
            End If
    NextN:
        Next n
        
        If finSel = "Comments" Then
            GoTo Finalise
        Else
            GoTo Tracks
        End If
    
    
    Tracks:
        Selection.HomeKey Unit:=wdStory
        For z = 1 To rCount
            Selection.NextRevision
            With Selection.Range.Revisions(1)
                If (.Type <> wdRevisionDelete Or wdRevisionInsert) Or (.Author = (Rev2ex1 Or Rev2ex2 Or Rev2ex3 Or Rev2ex4 Or Rev2ex5)) Then
                        GoTo Nextz
                Else
                    Select Case .Type
                        Case wdRevisionInsert
                            strPage = .Range.Information(wdActiveEndPageNumber)
                            strType = "Insert"
                            strAuthor = .Author
                            strSort = .Range.Information(wdFirstCharacterLineNumber)
    
                            strText = .Range.Text
                            oRange = .Range
                            Do While InStr(1, oRange.Text, Chr(2)) > 0
                                i = InStr(1, strText, Chr(2))
                                    If oRange.Footnotes.Count = 1 Then
                                       strText = Replace(Expression:=strText, _
                                                Find:=Chr(2), Replace:="[footnote reference]", _
                                                Start:=1, Count:=1)
                                        oRange.Start = oRange.Start + i
    
                                    ElseIf oRange.Endnotes.Count = 1 Then
                                       strText = Replace(Expression:=strText, _
                                                Find:=Chr(2), Replace:="[endnote reference]", _
                                                Start:=1, Count:=1)
                                        oRange.Start = oRange.Start + i
                                    End If
                            Loop
    
                            Set oRows = oTable.Rows.Add
    
                            With oRows
                                .Cells(1).Range.Text = strPage
                                With .Cells(2).Range
                                    .Text = strType
                                    .Font.Color = wdColorBlue
                                End With
                                With .Cells(4).Range
                                    .Text = strText
                                    .Font.Color = wdColorBlue
                                End With
                                .Cells(5).Range.Text = strAuthor
                                .Cells(7).Range.Text = strSort
                            End With
    
                        Case wdRevisionInsert
                            strPage = .Range.Information(wdActiveEndPageNumber)
                            strType = "Delete"
                            strAuthor = .Author
                            strSort = .Range.Information(wdFirstCharacterLineNumber)
    
                            strText = .Range.Text
                            oRange = .Range
                            Do While InStr(1, oRange.Text, Chr(2)) > 0
                                i = InStr(1, strText, Chr(2))
                                    If oRange.Footnotes.Count = 1 Then
                                       strText = Replace(Expression:=strText, _
                                                Find:=Chr(2), Replace:="[footnote reference]", _
                                                Start:=1, Count:=1)
                                        oRange.Start = oRange.Start + i
    
                                    ElseIf oRange.Endnotes.Count = 1 Then
                                       strText = Replace(Expression:=strText, _
                                                Find:=Chr(2), Replace:="[endnote reference]", _
                                                Start:=1, Count:=1)
                                        oRange.Start = oRange.Start + i
                                    End If
                            Loop
    
                            Set oRows = oTable.Rows.Add
    
                            With oRows
                                .Cells(1).Range.Text = strPage
                                With .Cells(2).Range
                                    .Text = strType
                                    .Font.Color = wdColorRed
                                End With
                                With .Cells(4).Range
                                    .Text = strText
                                    .Font.Color = wdColorRed
                                End With
                                .Cells(5).Range.Text = strAuthor
                                .Cells(7).Range.Text = strSort
                            End With
                    End Select
                End If
            End With
    Nextz:
        Next z
      
    Finalise:
       
        Set myTable = ActiveDocument.Tables(1)
        With myTable.Borders
            .InsideLineStyle = wdLineStyleSingle
            .OutsideLineStyle = wdLineStyleSingle
        End With
        
        ActiveDocument.Tables(1).Select
        
        Selection.Sort ExcludeHeader:=True, FieldNumber:="Column 1", SortFieldType _
            :=wdSortFieldNumeric, SortOrder:=wdSortOrderAscending, FieldNumber2:= _
            "Column 7", SortFieldType2:=wdSortFieldNumeric, SortOrder2:= _
            wdSortOrderAscending, FieldNumber3:="", SortFieldType3:= _
            wdSortFieldAlphanumeric, SortOrder3:=wdSortOrderAscending, Separator:= _
            wdSortSeparateByCommas, SortColumn:=False, CaseSensitive:=False, _
            LanguageID:=wdEnglishUK, SubFieldNumber:="Paragraphs", SubFieldNumber2:= _
            "Paragraphs", SubFieldNumber3:="Paragraphs"
            
        Selection.Columns(7).Delete
        
        With ActiveDocument.Tables(1)
            noCol = .Range.Rows(1).Cells.Count
                For blRows = .Rows.Count To 1 Step -1
                    With .Rows(blRows)
                        If Len(.Range) = noCol * 2 + 2 Then .Delete
                    End With
                Next blRows
        End With
        
        Application.ScreenUpdating = True
        Application.ScreenRefresh
              
        oNewDoc.Activate
        MsgBox CmntSmmry & RvSmmry & "Finished creating tracker.", vbOKOnly + vbInformation, "Job summary"
        
    
    
    ExitHere:
        Set oDoc = Nothing
        Set oNewDoc = Nothing
        Set oTable = Nothing
       
    End Sub

  2. #2
    Knowledge Base Approver VBAX Guru macropod's Avatar
    Joined
    Jul 2008
    Posts
    4,435
    Location
    Instead of trying to combine everything into a single code module, you should have three modules; one for the revisions; one for the comments; and one for the decision-making that calls either/both of the others as appropriate. Where necessary, the first two should use their own variables (e.g. for counters); you can use global variables for things like the names if they're to be shared by the first two modules.
    Cheers
    Paul Edstein
    [Fmr MS MVP - Word]

  3. #3
    VBAX Regular
    Joined
    Oct 2016
    Posts
    45
    Location
    Ah, interesting. I'm still an amateur just tweaking things without a deep understanding, so hadn't considered separating it into three modules. Appreciate your help. I'll give this a try.

    So, if my decision module gets the Author names held in a String, like Auth2ex1, how would I pass that value into the next module (i.e. the comment module)?

    Thanks again.

  4. #4
    Knowledge Base Approver VBAX Guru macropod's Avatar
    Joined
    Jul 2008
    Posts
    4,435
    Location
    For example:
    Dim StrAuth As String, i As Long
    
    Sub Main()
    Dim Rslt
    StrAuth = InputBox("Input Authors, separated by | (e.g. AuthA|AuthB)")
    Select Case MsgBox("Process OptionA = Yes" & vbCr & "Process OptionB = No" & vbCr & "Process OptionB = Cancel", vbYesNoCancel)
      Case vbYes: MsgBox "You chose OptionA": Call OptionA
      Case vbNo: MsgBox "You chose OptionB": Call OptionB
      Case vbCancel: MsgBox "You chose OptionA & OptionB": Call OptionA: Call OptionB
    End Select
    End Sub
    
    Sub OptionA()
    For i = 0 To UBound(Split(StrAuth, "|"))
      MsgBox " OptionA " & Split(StrAuth, "|")(i)
    Next
    End Sub
    
    Sub OptionB()
    For i = 0 To UBound(Split(StrAuth, "|"))
      MsgBox " OptionB " & Split(StrAuth, "|")(i)
    Next
    End Sub
    Cheers
    Paul Edstein
    [Fmr MS MVP - Word]

  5. #5
    VBAX Tutor
    Joined
    Jul 2016
    Posts
    266
    Location
    H2Whoa what an amazing and useful tool this would be. I hope someone can figure out the table population issue.

  6. #6
    VBAX Regular
    Joined
    Oct 2016
    Posts
    45
    Location
    Great, thanks Paul. I'll give this a whirl.

    Cheers.

  7. #7
    VBAX Regular
    Joined
    Oct 2016
    Posts
    45
    Location
    Quote Originally Posted by Kilroy View Post
    H2Whoa what an amazing and useful tool this would be. I hope someone can figure out the table population issue.
    I'll keep you posted! I feel like it's nearly there.

  8. #8
    VBAX Tutor
    Joined
    Jul 2016
    Posts
    266
    Location
    Try this. in the Comments section:

    Comments:
        For n = 1 To nCount
            If (oDoc.Comments(n).Author = Auth2ex1) Or (oDoc.Comments(n).Author = Auth2ex2) Or (oDoc.Comments(n).Author = Auth2ex3) Or (oDoc.Comments(n).Author = Auth2ex4) Or (oDoc.Comments(n).Author = Auth2ex5) Then
                GoTo NextN
            Else
                oTable.Rows.Add
                With oTable.Rows(n + 1)
                    .Cells(1).range.Text = _
                        oDoc.Comments(n).Scope.Information(wdActiveEndPageNumber)
                    .Cells(2).range.Text = "Comment"
                    .Cells(3).range.Text = oDoc.Comments(n).range.Text
                    .Cells(4).range.Text = oDoc.Comments(n).Scope
                    .Cells(5).range.Text = oDoc.Comments(n).Author
                    .Cells(7).range.Text = oDoc.Comments(n).Scope.Information(wdFirstCharacterLineNumber)
                End With
                GoTo NextN
            End If

    I just added " oTable.Rows.Add"

  9. #9
    VBAX Tutor
    Joined
    Jul 2016
    Posts
    266
    Location
    Unfortunately it is not populating the table with the tracked changes, just the comments are working. I'll look at it more when I get home from work.

  10. #10
    Knowledge Base Approver VBAX Guru macropod's Avatar
    Joined
    Jul 2008
    Posts
    4,435
    Location
    You might be interested in the revision & comment extraction macros I posted at: https://answers.microsoft.com/en-us/...f-8dc609cc75af. See my posts of November 3, 2014 & September 5, 2015, respectively.
    Cheers
    Paul Edstein
    [Fmr MS MVP - Word]

  11. #11
    VBAX Regular
    Joined
    Oct 2016
    Posts
    45
    Location
    Quote Originally Posted by Kilroy View Post
    Unfortunately it is not populating the table with the tracked changes, just the comments are working. I'll look at it more when I get home from work.
    Yeah, it's so frustrating. I just don't know why it's refusing to cooperate with the tracked changes! Will also take a look at macropod's macros.

  12. #12
    VBAX Tutor
    Joined
    Jul 2016
    Posts
    266
    Location
    I couldn't figure it out but I did put this together today. No options but it works.

    Sub CommentsAndRevisionsToTable()
    'Kilroy
    Dim s As String
    Dim r As String
    Dim cmt As Word.Comment
    Dim doc As Word.Document
    Dim rev As Word.Revision
    Dim oTbl As Table
    For Each cmt In ActiveDocument.Comments
    s = s & cmt.Author & (",Comment " & cmt.Index) & "," & cmt.range.Text & vbCr
    Next
    For Each rev In ActiveDocument.Revisions
    r = r & rev.Author & (",Revision " & rev.Index) & "," & rev.range.Text & vbCr  
    Next
    Set doc = Documents.Add
    doc.range.Text = s & r
      Selection.WholeStory
        Selection.ConvertToTable Separator:=wdSeparateByCommas, NumColumns:=3, _
            numRows:=12, AutoFitBehavior:=wdAutoFitFixed
        With Selection.Tables(1)
            If .Style <> "Table Grid" Then
                .Style = "Table Grid"
            End If
            
        End With
        Selection.InsertRowsAbove 1
      With Selection.Tables(1).Columns(3)
      .Select
    Selection.InsertColumnsRight
    End With
    With Selection.Tables(1)
    .Columns(1).SetWidth ColumnWidth:=100, _
    RulerStyle:=wdAdjustFirstColumn
    .Columns(2).SetWidth ColumnWidth:=100, _
    RulerStyle:=wdAdjustFirstColumn
    .Columns(3).SetWidth ColumnWidth:=100, _
    RulerStyle:=wdAdjustFirstColumn
    .Columns(4).SetWidth ColumnWidth:=100, _
    RulerStyle:=wdAdjustFirstColumn
    .Cell(1, 1).range.Text = "Author"
    .Cell(1, 2).range.Text = "Edit Type"
    .Cell(1, 3).range.Text = "Comment/Revision"
    .Cell(1, 4).range.Text = "Acceptable?"
    End With
    End Sub
    Last edited by Kilroy; 07-04-2018 at 10:07 AM.

  13. #13
    VBAX Tutor
    Joined
    Jul 2016
    Posts
    266
    Location
    I know VBA can't tell what a "sentence" is but is there a way to include in the revision portion, an entire sentence using something like selection.start and selection.end? Ist here something else?

  14. #14
    VBAX Regular
    Joined
    Oct 2016
    Posts
    45
    Location
    Interesting idea. And thanks for the code. Will take a look today.

  15. #15
    VBAX Tutor
    Joined
    Jul 2016
    Posts
    266
    Location
    Really the most ideal layout would include the before and after "sentence".

  16. #16
    VBAX Regular
    Joined
    Oct 2016
    Posts
    45
    Location
    Update:

    I have had a significant breakthrough with this. I need to tidy up a few things as I'd be embarrassed to post the code in it's current working form, but I have actually managed to get it working. Furthermore, in my updated code the only limit on the number of people you can choose to exclude is the number of reviewers and commenters in the document. I'll post the code in the next couple of days.

  17. #17
    VBAX Regular
    Joined
    Oct 2016
    Posts
    45
    Location
    Well. Here we go. Wow, this has had me smashing my head into my desk on numerous occasions. It's not pretty, but it seems to work. Three things to consider:


    1. I'm quite sure that this is not 'pretty' and that somebody who actually knows what they are doing would be able to make this much more elegant than my fudge.
    2. This will only extract comments and tracked text insertions or deletions. During the course of this I found out that revision handling isn't great in VBA, so I had to add a Like test for revisions to only select text ranges to prevent failures.
    3. If your document is large and/or contains extensive revisions, Word may appear to freeze at various points in this process. In the last stage, when it's building the table, Word may appear to lock up for a good few minutes, especially if there are lots of revisions. This is normal. Just leave it to run and it will get there.


    As mentioned in the top post of this thread, I'm indebted to the brains and helpfulness of others for getting me to this point. If you have any ideas for tidying up this behemoth and making it more efficient, please just let me know!

    As suggested by macropod, I've split this out into a number of subs, each one handling a specific part of the process.

    'Public declarations
    
    Public cmInc, cmEx, comSkip, revInc, revEx, revSkip As Boolean
    Public cmSummary, revSummary, scrllPs As String
    Public nCount, lAn, lFAn, cmTally, _
            rCount, indelCount, lRn, lFRevn, revTally As Long
    Public crsRng As Range
    Public nc2, rev2exN As Integer
    Public Cmt2ex As New Collection, cd
    Public Review2ex As New Collection, rd
    Public Cmt2exArr() As String
    Public Rev2exArr() As String
    Public oDoc As Document
    Public Sub Comment_And_InDel_Grid()
    i_Reset_Pub_Decs
    ii_Com_Analyse
    iii_Rev_Analyse
    iv_Grid_maker
    End Sub
    Public Sub i_Reset_Pub_Decs()
    cmInc = False: cmEx = False: comSkip = False: revInc = False: revEx = False: revSkip = False
    
    
    cmSummary = "": revSummary = "": scrllPs = ""
    nCount = 0: lAn = 0: lFAn = 0: cmTally = 0: rCount = 0: indelCount = 0: lRn = 0: lFRevn = 0: revTally = 0
    
    
    Set crsRng = Nothing
    nc2 = 0: rev2exN = 0
    Set Cmt2ex = Nothing
    Set Review2ex = Nothing
    Erase Cmt2exArr
    Erase Rev2exArr
    
    
    Set oDoc = Nothing
    
    
    End Sub
    Public Sub ii_Com_Analyse()
    
    
        Dim b, c, e, g, h, i, j As Long
        Dim sCmAuTxt1, initCSum, chsEx, stCmtAuth, sTCmAs, _
            rtrn2ex, rtrn2exsel, cmtMax, selComs, stSkpRv, C2X As String
        Dim CmtAuArr() As String
        Dim CmtCol As New Collection, ca
    
    
        sCmAuTxt1 = "The following people have made comments:" & vbNewLine & vbNewLine
    
    
        Set oDoc = ActiveDocument
        nCount = ActiveDocument.Comments.Count
        rCount = ActiveDocument.Revisions.Count
        cmInc = False
        comSkip = False
        Set crsRng = Selection.Range
        scrllPs = ActiveWindow.ActivePane.VerticalPercentScrolled
        
        If (nCount = 0) And (rCount > 0) Then
            MsgBox "There are no comments in this document.", vbOKOnly + vbCritical
            cmInc = False: cmEx = False: comSkip = True
            Cmt2exArr(LBound(Cmt2exArr)) = "ZilchCom 1"
            Cmt2exArr(UBound(Cmt2exArr)) = "ZilchCom 2"
            GoTo Revcheck
        ElseIf (nCount = 0) And (rCount = 0) Then
            MsgBox "There are no comments or changes in this document in this document.", vbOKOnly + vbCritical
            Set oDoc = Nothing
            End
        ElseIf nCount = 1 Then
            initCSum = "There is only one comment in this document." & vbNewLine & vbNewLine & "Do you want to include this in the tracker?"
            lAn = 1
            cmtMax = "There is only one author, so you can't exclude them from the tracker."
        ElseIf nCount > 1 Then
            'Compiles a list of people who have made comments in the document
            blDimensioned = False
            For b = 1 To nCount
                stCmtAuth = ActiveDocument.Comments(b).Author
                If stCmtAuth <> "" Then
                    If blDimensioned = True Then
                        ReDim Preserve CmtAuArr(0 To UBound(CmtAuArr) + 1) As String
                    Else
                        ReDim CmtAuArr(0 To 0) As String
                        CmtAuArr(0) = ""
                        blDimensioned = True
                    End If
                    CmtAuArr(UBound(CmtAuArr)) = stCmtAuth
                End If
            Next
            
            'Collects and counts authors
            On Error Resume Next
            For Each ca In CmtAuArr
                CmtCol.Add ca, ca
            Next
            
            lAn = CmtCol.Count
            
            'Commenter exclusion text building
            If CmtCol.Count = 1 Then
                cmtMax = "There is only one author, so you can't exclude them from the tracker."
                initCSum = "There are " & nCount & " comments from " & CmtCol(1) & "." & vbNewLine & vbNewLine & "Do you want to include comments in the tracker?"
            ElseIf CmtCol.Count > 1 Then
                sTCmAs = ""
                For c = 1 To lAn
                    sTCmAs = sTCmAs & c & ". " & CmtCol(c) & vbNewLine
                Next
                
                initCSum = "There are " & nCount & " comments from " & lAn & " people." & vbNewLine & sCmAuTxt1 & sTCmAs & vbNewLine _
                & vbNewLine & "Do you want to include comments in the tracker?"
                
                If CmtCol.Count > 2 Then
                    lFAn = CmtCol.Count - 1
                    cmtMax = "You can exclude comments from a maximum of " & lFAn & " people." & vbNewLine & vbNewLine & "Do you want to exclude anyone?"
                ElseIf CmtCol.Count = 2 Then
                    lFAn = 1
                    cmtMax = "You can exclude comments from a maximum of one person." & vbNewLine & vbNewLine & "Do you want to exclude anyone?"
                End If
            End If
        End If
        
        'Decide whether to include comments in the tracker
        selComs = MsgBox(initCSum, vbYesNo + vbQuestion)
        
        If selComs = vbYes Then
            cmInc = True
        ElseIf selComs = vbNo Then
            comSkip = True: cmInc = False: cmEx = False
            Cmt2exArr(LBound(Cmt2exArr)) = "ZilchCom 1"
            Cmt2exArr(UBound(Cmt2exArr)) = "ZilchCom 2"
            GoTo Revcheck
        End If
    Revcheck:
        If rCount > 0 Then
            stSkpRv = MsgBox("Will you also want to process tracked changes?", vbYesNo + vbQuestion)
            If stSkpRv = vbYes Then
                revSkip = False: revInc = True
            ElseIf stSkpRv = vbNo Then
                revSkip = True
                revInc = False: revEx = False
                Rev2exArr(LBound(Rev2exArr)) = "ZilchRev 1"
                Rev2exArr(UBound(Rev2exArr)) = "ZilchRev 2"
            End If
            If comSkip = True Then GoTo EndComCount
        ElseIf rCount = 0 Then
            MsgBox "There are no tracked changes in this document. Only comments will be extracted.", vbOKOnly + vbInformation
            revSkip = True
            revInc = False: revEx = False
            Rev2exArr(LBound(Rev2exArr)) = "ZilchRev 1"
            Rev2exArr(UBound(Rev2exArr)) = "ZilchRev 2"
        End If
            
        If lAn = 1 Then
            If MsgBox(cmtMax, vbOKCancel + vbInformation) = vbOK Then
                cmInc = True: cmEx = False
                Cmt2exArr(LBound(Cmt2exArr)) = "ZilchCom 1"
                Cmt2exArr(UBound(Cmt2exArr)) = "ZilchCom 2"
                cmSummary = "All " & nCount & " comments from " & CmtCol(1) & " extracted."
                GoTo EndComCount
            Else
                cmInc = False: cmEx = False
                Cmt2exArr(LBound(Cmt2exArr)) = "ZilchCom 1"
                Cmt2exArr(UBound(Cmt2exArr)) = "ZilchCom 2"
                GoTo EndComCount
            End If
        Else
            'Choose whether to exclude any commenters
            chsEx = MsgBox(sCmAuTxt1 & sTCmAs & vbNewLine & cmtMax, vbYesNoCancel)
            If chsEx = vbYes Then
                cmEx = True
    n2ex:
                'Choose number of commenters to exclude
                nc2 = InputBox(sCmAuTxt1 & sTCmAs & vbNewLine & "How many people do you want to exclude?" & vbNewLine & vbNewLine & "Maximum of " & lFAn & ".", "Number to exclude")
                
                'Number validity testing
                If (IsNumeric(nc2) = False) Or (nc2 > (CmtCol.Count - 1)) Or (nc2 = 0) Then
                    rtrn2ex = MsgBox("Invalid value." & vbNewLine & vbNewLine & "ABORT to not extract comments" _
                    & vbNewLine & vbNewLine & "RETRY to enter valid value" _
                    & vbNewLine & vbNewLine & "IGNORE to proceed without excluding anyone.", vbAbortRetryIgnore + vbCritical)
                    If rtrn2ex = vbRetry Then
                        GoTo n2ex
                    
                    ElseIf rtrn2ex = vbAbort Then
                        cmInc = False: cmEx = False
                        Cmt2exArr(LBound(Cmt2exArr)) = "ZilchCom 1"
                        Cmt2exArr(UBound(Cmt2exArr)) = "ZilchCom 2"
                        GoTo EndComCount
                    
                    ElseIf rtrn2ex = vbIgnore Then
                        cmInc = True: cmEx = False
                        Cmt2exArr(LBound(Cmt2exArr)) = "ZilchCom 1"
                        Cmt2exArr(UBound(Cmt2exArr)) = "ZilchCom 2"
                        cmSummary = "All " & nCount & " comments extracted."
                        GoTo EndComCount
                    End If
                Else
                    'Build user-defined list of commenters to exclude
                    blDimensioned = False
                    For e = 1 To nc2
    Exn:
                        j = InputBox(sCmAuTxt1 & sTCmAs & vbNewLine & "Enter the number of the person to exclude, from the list above.")
                            If (j > CmtCol.Count) Or (j = 0) Or (IsNumeric(j) = False) Then
                                rtrn2exsel = MsgBox("Invalid value." & vbNewLine & vbNewLine & "ABORT to not extract comments" _
                                            & vbNewLine & vbNewLine & "RETRY to enter valid value" _
                                            & vbNewLine & vbNewLine & "IGNORE to proceed without excluding anyone.", vbAbortRetryIgnore + vbCritical)
                                            
                                            If rtrn2exsel = vbRetry Then
                                            GoTo Exn
                                            
                                            ElseIf rtrn2exsel = vbAbort Then
                                                cmInc = False: cmEx = False
                                                Cmt2exArr(LBound(Cmt2exArr)) = "ZilchCom 1"
                                                Cmt2exArr(UBound(Cmt2exArr)) = "ZilchCom 2"
                                                GoTo EndComCount
                                            
                                            ElseIf rtrn2exsel = vbIgnore Then
                                                cmInc = True: cmEx = False
                                                Cmt2exArr(LBound(Cmt2exArr)) = "ZilchCom 1"
                                                Cmt2exArr(UBound(Cmt2exArr)) = "ZilchCom 2"
                                                cmSummary = "All " & nCount & " comments extracted."
                                                GoTo EndComCount
                                            End If
                                Else
                                
                                    C2X = CmtCol(j)
                                    
                        
                                    If blDimensioned = True Then
                                        ReDim Preserve Cmt2exArr(0 To UBound(Cmt2exArr) + 1) As String
                                    Else
                                        ReDim Cmt2exArr(0 To 0) As String
                                        Cmt2exArr(0) = ""
                                        blDimensioned = True
                                    End If
                                    Cmt2exArr(UBound(Cmt2exArr)) = C2X
                                End If
                    Next
                    
                    
                    On Error Resume Next
                    For Each cd In Cmt2exArr
                        Cmt2ex.Add cd, cd
                    Next
                    
                    'Counts number of comments made by authors to exclude
                    For g = LBound(Cmt2exArr) To UBound(Cmt2exArr)
                        h = 0
                        For i = 1 To nCount
                            With oDoc.Comments(i)
                                If .Author = Cmt2exArr(g) Then h = h + 1
                            End With
                        Next
                    Next
                    
                    'Counts number of comments that are included in the tracker
                    cmTally = nCount - h
                    
                    cmSummary = "Extracted:" & vbTab & vbTab & vbTab & cmTally & " comments from " & Cmt2ex.Count & " people." & vbNewLine _
                                & "Total in document:" & vbTab & vbTab & nCount & " comments from" & vbNewLine _
                                & vbTab & vbTab & vbTab & lAn & " people." & vbNewLine & vbNewLine
                
                End If
            
            ElseIf chsEx = vbNo Then
                cmInc = True: cmEx = False
                Cmt2exArr(LBound(Cmt2exArr)) = "ZilchCom 1"
                Cmt2exArr(UBound(Cmt2exArr)) = "ZilchCom 2"
                cmSummary = "All " & nCount & " comments from " & CmtCol(1) & " extracted."
                GoTo EndComCount
            ElseIf chsEx = vbCancel Then
                cmInc = False: cmEx = False
                Cmt2exArr(LBound(Cmt2exArr)) = "ZilchCom 1"
                Cmt2exArr(UBound(Cmt2exArr)) = "ZilchCom 2"
                GoTo EndComCount
            End If
        End If
    
    
    EndComCount:
    End Sub
    Public Sub iii_Rev_Analyse()
    
    
    Dim b, c, e, g, h, i, n As Long
        Dim sReviewerTxt1, initRevSum, chsRevEx, stReviewer, sTReviewrs, _
            rtrn2Revex, revMax, selRevs, rtrnrvlist, R2X As String
        Dim ReviewerArr() As String
        Dim RevCol As New Collection, ra
    
    
        If revSkip = True Then GoTo EndRevCount
        
        sReviewerTxt1 = "The following people have made tracked insertions/deletions:" & vbNewLine & vbNewLine
    
    
        revInc = False
        
        If rCount = 1 Then
            Application.ScreenUpdating = False
            Selection.HomeKey Unit:=wdStory
            Selection.NextRevision.Range.Select
            With Selection.Range.Revisions(1)
                If .Type = wdRevisionDelete Or wdRevisionInsert Then
                    initRevSum = "There is only one tracked insertion/deletion in this document." & vbNewLine & vbNewLine & "Do you want to include this in the tracker?"
                    revMax = "There is only one reviewer, so you can't exclude them from the tracker."
                    lRn = 1
                Else
                    crsRng.Select
                    ActiveWindow.ActivePane.VerticalPercentScrolled = scrllPs
                    Application.ScreenUpdating = True
                    MsgBox "There are no tracked insertions/deletions in this document.", vbOKOnly + vbCritical
                    revInc = False
                    End
                End If
            End With
            crsRng.Select
            ActiveWindow.ActivePane.VerticalPercentScrolled = scrllPs
            Application.ScreenUpdating = True
        ElseIf rCount > 1 Then
            'Compiles a list of people who have made changes in the document
            
            MsgBox "Note: Word may appear to freeze at various points. Please be patient." & vbNewLine & vbNewLine & _
                    "The more tracked changes there are, the longer the freezes will be.", vbOKOnly + vbInformation, "Word is now processing tracked changes"
            
            Application.Screenrefresh
            Application.ScreenUpdating = False
            Selection.HomeKey Unit:=wdStory
            
            indelCount = 0
            
            blDimensioned = False
            For b = 1 To rCount
                Selection.NextRevision
                With Selection.Range.Revisions(1)
                    If ((.Type = wdRevisionDelete) Or (.Type = wdRevisionInsert)) _
                    And (.Range.Text Like "*[ A-z0-9\,\.\?\(\)\;]*") Then
                        indelCount = indelCount + 1
                        stReviewer = .Author
                        If stReviewer <> "" Then
                            If blDimensioned = True Then
                                ReDim Preserve ReviewerArr(0 To UBound(ReviewerArr) + 1) As String
                            Else
                                ReDim ReviewerArr(0 To 0) As String
                                ReviewerArr(0) = ""
                                blDimensioned = True
                            End If
                            ReviewerArr(UBound(ReviewerArr)) = stReviewer
                        End If
                    End If
                End With
            Next
            
            crsRng.Select
            ActiveWindow.ActivePane.VerticalPercentScrolled = scrllPs
            Application.ScreenUpdating = True
            
            'Collects and counts reviewers
            On Error Resume Next
            For Each ra In ReviewerArr
                RevCol.Add ra, ra
            Next
            
            lRn = RevCol.Count
            
            'Reviewer exclusion text building
            If RevCol.Count = 1 Then
                revMax = "There is only one reviewer, so you can't exclude them from the tracker."
                initRevSum = "There are " & indelCount & " tracked insertions/deletions from " & RevCol(1) & "." & vbNewLine & vbNewLine & "Do you want to include tracked changes in the tracker?"
            ElseIf RevCol.Count > 1 Then
                sTReviewrs = ""
                For c = 1 To lRn
                    sTReviewrs = sTReviewrs & c & ". " & RevCol(c) & vbNewLine
                Next
                
                initRevSum = "There are " & indelCount & " tracked insertions/deletions from " & lRn & " people." & vbNewLine & sReviewerTxt1 & sTReviewrs & vbNewLine _
                & vbNewLine & "Do you want to include tracked changes in the tracker?"
                
                If RevCol.Count > 2 Then
                    lFRevn = RevCol.Count - 1
                    revMax = "You can exclude tracked insertions/deletions from a maximum of " & lFRevn & " people." & vbNewLine & vbNewLine & "Do you want to exclude anyone?"
                ElseIf RevCol.Count = 2 Then
                    lFRevn = 1
                    revMax = "You can exclude tracked insertions/deletions from a maximum of one person." & vbNewLine & vbNewLine & "Do you want to exclude anyone?"
                End If
            End If
        End If
        
        'Decide whether to include tracked changes in the tracker
        selRevs = MsgBox(initRevSum, vbYesNo + vbQuestion)
        
        If selRevs = vbYes Then
            revInc = True
        ElseIf selRevs = vbNo Then
            revInc = False: revEx = False
            Rev2exArr(LBound(Rev2exArr)) = "ZilchRev 1"
            Rev2exArr(UBound(Rev2exArr)) = "ZilchRev 2"
            GoTo EndRevCount
        End If
            
        If lRn = 1 Then
            If MsgBox(revMax, vbOKCancel + vbInformation) = vbOK Then
                revInc = True: revEx = False
                Rev2exArr(LBound(Rev2exArr)) = "ZilchRev 1"
                Rev2exArr(UBound(Rev2exArr)) = "ZilchRev 2"
                revSummary = "All " & indelCount & " tracked insertions/deletions from " & RevCol(1) & " extracted."
                GoTo EndRevCount
            Else
                revInc = False: revEx = False
                Rev2exArr(LBound(Rev2exArr)) = "ZilchRev 1"
                Rev2exArr(UBound(Rev2exArr)) = "ZilchRev 2"
                GoTo EndRevCount
            End If
        Else
            'Choose whether to exclude any reviewers
            chsRevEx = MsgBox(sReviewerTxt1 & sTReviewrs & vbNewLine & revMax, vbYesNoCancel)
            If chsRevEx = vbYes Then
                revEx = True
    nrv2ex:
                'Choose number of reviewers to exclude
                rev2exN = InputBox(sReviewerTxt1 & sTReviewrs & vbNewLine & "How many people do you want to exclude?" & vbNewLine & vbNewLine & "Maximum of " & lFRevn & ".", "Number to exclude")
                
                'Number validity testing
                If (IsNumeric(rev2exN) = False) Or (rev2exN > (RevCol.Count - 1)) Or (rev2exN < 1) Then
                    rtrn2Revex = MsgBox("Invalid value." & vbNewLine & vbNewLine & "ABORT to not extract revisions" _
                    & vbNewLine & vbNewLine & "RETRY to enter valid value" _
                    & vbNewLine & vbNewLine & "IGNORE to proceed without excluding anyone.", vbAbortRetryIgnore + vbCritical)
                    If rtrn2Revex = vbRetry Then
                        GoTo nrv2ex
                    ElseIf rtrn2Revex = vbAbort Then
                        revInc = False: revEx = False
                        Rev2exArr(LBound(Rev2exArr)) = "ZilchRev 1"
                        Rev2exArr(UBound(Rev2exArr)) = "ZilchRev 2"
                        GoTo EndRevCount
                    ElseIf rtrn2Revex = vbIgnore Then
                        revInc = True: revEx = False
                        Rev2exArr(LBound(Rev2exArr)) = "ZilchRev 1"
                        Rev2exArr(UBound(Rev2exArr)) = "ZilchRev 2"
                        revSummary = "All " & indelCount & " insertions/deletions from all " & lRn & " people extracted."
                        GoTo EndRevCount
                    End If
                Else
                    'Build user-defined list of reviewers to exclude
                    blDimensioned = False
                    For e = 1 To rev2exN
    Revexlist:
                        n = InputBox(sReviewerTxt1 & sTReviewrs & vbNewLine & "Enter the number of the person to exclude, exactly " & _
                                    vbNewLine & "as it appears in the list above.")
                            If (n > RevCol.Count) Or (n = 0) Or (IsNumeric(n) = False) Then
                                rtrnrvlist = MsgBox("Invalid value." & vbNewLine & vbNewLine & "ABORT to not extract revisions" _
                                            & vbNewLine & vbNewLine & "RETRY to enter valid value" _
                                            & vbNewLine & vbNewLine & "IGNORE to proceed without excluding anyone.", vbAbortRetryIgnore + vbCritical)
                                            
                                            If rtrn2Revex = vbRetry Then
                                                GoTo Revexlist
                                            ElseIf rtrn2Revex = vbAbort Then
                                                revInc = False: revEx = False
                                                Rev2exArr(LBound(Rev2exArr)) = "ZilchRev 1"
                                                Rev2exArr(UBound(Rev2exArr)) = "ZilchRev 2"
                                                GoTo EndRevCount
                                            ElseIf rtrn2Revex = vbIgnore Then
                                                revInc = True: revEx = False
                                                Rev2exArr(LBound(Rev2exArr)) = "ZilchRev 1"
                                                Rev2exArr(UBound(Rev2exArr)) = "ZilchRev 2"
                                                revSummary = "All " & indelCount & " insertions/deletions from all " & lRn & " people extracted."
                                                GoTo EndRevCount
                                            End If
                            Else
                                R2X = RevCol(n)
                                
                                If blDimensioned = True Then
                                    ReDim Preserve Rev2exArr(0 To UBound(Rev2exArr) + 1) As String
                                Else
                                    ReDim Rev2exArr(0 To 0) As String
                                    Rev2exArr(0) = ""
                                    blDimensioned = True
                                End If
                                Rev2exArr(UBound(Rev2exArr)) = R2X
                            End If
                    Next
                    
                    On Error Resume Next
                    For Each rd In Rev2exArr
                        Review2ex.Add rd, rd
                    Next
                    
                    
                    'Counts number of changes made by reviewers to exclude
                    Application.ScreenUpdating = False
                    Selection.HomeKey Unit:=wdStory
                    
                    
                    h = 0
                    For i = 1 To rCount
                        With Selection.NextRevision
                            If .Range.Text Like "*[ A-z0-9\,\.\?\(\)\;]*" Then
                                For g = LBound(Rev2exArr) To UBound(Rev2exArr)
                                    If .Author = Rev2exArr(g) Then h = h + 1
                                Next
                            End If
                        End With
                    Next
                    
                    
                    crsRng.Select
                    ActiveWindow.ActivePane.VerticalPercentScrolled = scrllPs
                    Application.ScreenUpdating = True
                    Application.Screenrefresh
                    
                    
                    'Counts number of changes that are included in the tracker
                    revTally = indelCount - h
                    
                    revSummary = "Extracted:" & vbTab & vbTab & vbTab & revTally & " tracked insertions/deletions" & vbNewLine _
                                & vbTab & vbTab & vbTab & "from " & Review2ex.Count & " people." & vbNewLine & "Total in document:" _
                                & vbTab & vbTab & indelCount & " tracked insertions/deletions" & vbNewLine _
                                & vbTab & vbTab & vbTab & "from " & lRn & " people." & vbNewLine & vbNewLine
                
                End If
                
            ElseIf chsRevEx = vbNo Then
                revInc = True: revEx = False
                Rev2exArr(LBound(Rev2exArr)) = "ZilchRev 1"
                Rev2exArr(UBound(Rev2exArr)) = "ZilchRev 2"
                revSummary = "All " & indelCount & " insertions/deletions from all " & lRn & " people extracted."
                GoTo EndRevCount
            ElseIf chsRevEx = vbCancel Then
                revInc = False: revEx = False
                Rev2exArr(LBound(Rev2exArr)) = "ZilchRev 1"
                Rev2exArr(UBound(Rev2exArr)) = "ZilchRev 2"
                GoTo EndRevCount
            End If
        End If
    EndRevCount:
    End Sub
    Public Sub iv_Grid_maker()
    
    
        Dim oNewDoc As Document
        Dim oTable As Table
        Dim NXTA, NXTR As Boolean
        Dim f, i, j, n, rvb, _
            blRows, exRows, rve, rvf, rvg, rvr, rparCount, rrcnt As Long
        Dim Rvtype, Rvpage, Rvsort, Rvauth As String
        
        Title = "Comment and revision tracker"
        Set oDoc = ActiveDocument
        rCount = oDoc.Revisions.Count
        
        Application.Screenrefresh
        
        If cmInc = False And revInc = False Then
            MsgBox "No comments or revisions selected.", vbOKOnly + vbInformation
            GoTo ExitHere
        End If
        
           
    Start:
        Application.Screenrefresh
        MsgBox "Word may appear to freeze during this process!" & vbNewLine & vbNewLine & "Don't panic! Word has not crashed. Just wait for the process to finish." & vbNewLine & vbNewLine & "The more revisions and comments there are, the longer the process will take.", vbOKOnly, "DON'T PANIC!"
        Application.ScreenUpdating = False
        Set oNewDoc = Documents.Add
        oNewDoc.PageSetup.Orientation = wdOrientLandscape
        With oNewDoc
            .Content = ""
            If cmInc = True And revInc = False Then
                Set oTable = .Tables.Add _
                    (Range:=Selection.Range, _
                    numRows:=nCount + 1, _
                    NumColumns:=7)
                    
                .Sections(1).Headers(wdHeaderFooterPrimary).Range.Text = _
                "Comments extracted from: " & oDoc.Name
                
            ElseIf cmInc = False And revInc = True Then
                Set oTable = .Tables.Add _
                    (Range:=Selection.Range, _
                    numRows:=rCount + 1, _
                    NumColumns:=7)
                    
                .Sections(1).Headers(wdHeaderFooterPrimary).Range.Text = _
                "Revisions extracted from: " & oDoc.Name
                    
            ElseIf cmInc = True And revInc = True Then
                Set oTable = .Tables.Add _
                    (Range:=Selection.Range, _
                    numRows:=nCount + rCount + 1, _
                    NumColumns:=7)
                    
                .Sections(1).Headers(wdHeaderFooterPrimary).Range.Text = _
                "Comments and revisions extracted from: " & oDoc.Name
                    
            End If
        End With
    
    
        With oNewDoc.Styles(wdStyleNormal)
            .Font.Name = "Calibri"
            .Font.Size = 9
            .ParagraphFormat.LeftIndent = 0
            .ParagraphFormat.SpaceAfter = 6
        End With
       
        With oNewDoc.Styles(wdStyleHeader)
            .Font.Size = 8
            .ParagraphFormat.SpaceAfter = 0
        End With
    
    
        With oTable
            .Range.Style = wdStyleNormal
            .AllowAutoFit = False
            .PreferredWidthType = wdPreferredWidthPercent
            .PreferredWidth = 100
            .Columns.PreferredWidthType = wdPreferredWidthPercent
            .Columns(1).PreferredWidth = 5
            .Columns(2).PreferredWidth = 10
            .Columns(3).PreferredWidth = 25
            .Columns(4).PreferredWidth = 25
            .Columns(5).PreferredWidth = 15
            .Columns(6).PreferredWidth = 30
            .Columns(7).PreferredWidth = 2
            .Rows(1).HeadingFormat = True
        End With
    
    
        With oTable.Rows(1)
            .Range.Font.Bold = True
            .Cells(1).Range.Text = "Page"
            .Cells(2).Range.Text = "Type"
            .Cells(3).Range.Text = "Comment"
            .Cells(4).Range.Text = "Relevant text"
            .Cells(5).Range.Text = "Commenter"
            .Cells(6).Range.Text = "Action/response"
            .Cells(7).Range.Text = "Sort"
        End With
    
    
    Comments:
        If cmInc = False Then GoTo Tracks
        
        If cmInc = True Then
                    f = 1
                    With oDoc
                        For n = 1 To nCount
                            With oDoc
                                NXTA = False
                                If cmEx = True Then
                                    For i = LBound(Cmt2exArr) To UBound(Cmt2exArr)
                                        If oDoc.Comments(n).Author = Cmt2exArr(i) Then NXTA = True
                                    Next
                                End If
                            End With
                                
                                If NXTA = False Then
                                
                                    f = f + 1
                                    
                                    With oNewDoc
                                        oTable.Rows.Add
                                    
                                        With oTable.Rows(f)
                                            .Cells(1).Range.Text = _
                                                oDoc.Comments(n).Scope.Information(wdActiveEndPageNumber)
                                            .Cells(2).Range.Text = "Comment"
                                            .Cells(3).Range.Text = oDoc.Comments(n).Range.Text
                                            .Cells(4).Range.Text = oDoc.Comments(n).Scope
                                            .Cells(5).Range.Text = oDoc.Comments(n).Author
                                            .Cells(7).Range.Text = oDoc.Comments(n).Scope.Information(wdFirstCharacterLineNumber)
                                        End With
                                    End With
                                End If
    NextComB:
                        Next
                    End With
    
    
        End If
    
    
    Tracks:
        If revInc = False Then GoTo Finalise
        
        Application.ScreenUpdating = False
        Selection.HomeKey Unit:=wdStory
        
        If (cmInc = False) Or (comSkip = True) Then f = 1
            
                With oDoc
                    Selection.HomeKey Unit:=wdStory
                    On Error GoTo NextRevb
                    For rvb = 1 To rCount
                            With Selection.NextRevision
                                NXTR = False
                                If revEx = True Then
                                    For j = LBound(Rev2exArr) To UBound(Rev2exArr)
                                        If .Author = Rev2exArr(j) Then NXTR = True
                                    Next
                                End If
                                
                                If NXTR = False Then
                                    f = f + 1
                                    If (.Range.Text Like "*[ A-z0-9\,\.\?\(\)\;]*") _
                                        And (.Type = wdRevisionDelete) Then
                                        
                                        Rvtype = "Delete"
                                        Rvpage = .Range.Information(wdActiveEndPageNumber)
                                        Rvauth = .Author
                                        Rvsort = .Range.Information(wdFirstCharacterLineNumber)
                                        Rvtext = """" & .Range.Text & """"
                                    
                                    ElseIf (.Range.Text Like "*[ A-z0-9\,\.\?\(\)\;]*") _
                                        And (.Type = wdRevisionInsert) Then
                                        
                                        Rvtype = "Insert"
                                        Rvpage = .Range.Information(wdActiveEndPageNumber)
                                        Rvauth = .Author
                                        Rvsort = .Range.Information(wdFirstCharacterLineNumber)
                                        Rvtext = """" & .Range.Text & """"
                                    
                                    Else
                                        
                                        Rvtype = ""
                                        Rvpage = ""
                                        Rvauth = ""
                                        Rvsort = ""
                                        Rvtext = ""
                                    
                                    End If
                                End If
                            
                            End With
                                            
                            If NXTR = False Then
                                With oNewDoc
                                    oTable.Rows.Add
                                        
                                    With oTable.Rows(f)
                                        .Cells(1).Range.Text = Rvsort
                                        .Cells(2).Range.Text = Rvtype
                                        .Cells(4).Range.Text = Rvtext
                                        .Cells(5).Range.Text = Rvauth
                                        .Cells(7).Range.Text = Rvsort
                                        
                                        If Rvtype = "Delete" Then
                                            .Cells(2).Range.Font.Color = wdColorRed
                                            .Cells(4).Range.Font.Color = wdColorRed
                                        ElseIf Rvtype = "Insert" = True Then
                                            .Cells(2).Range.Font.Color = wdColorBlue
                                            .Cells(4).Range.Font.Color = wdColorBlue
                                        End If
                                    End With
                                End With
                            End If
    NextRevb:
                    oDoc.Activate
                    Next
                End With
                
                crsRng.Select
                ActiveWindow.ActivePane.VerticalPercentScrolled = scrllPs
                GoTo Finalise
      
    Finalise:
        oNewDoc.Activate
        Set myTable = ActiveDocument.Tables(1)
        With myTable.Borders
            .InsideLineStyle = wdLineStyleSingle
            .OutsideLineStyle = wdLineStyleSingle
        End With
        
        ActiveDocument.Tables(1).Select
        
        Selection.Sort ExcludeHeader:=True, FieldNumber:="Column 1", SortFieldType _
            :=wdSortFieldNumeric, SortOrder:=wdSortOrderAscending, FieldNumber2:= _
            "Column 7", SortFieldType2:=wdSortFieldNumeric, SortOrder2:= _
            wdSortOrderAscending, FieldNumber3:="", SortFieldType3:= _
            wdSortFieldAlphanumeric, SortOrder3:=wdSortOrderAscending, Separator:= _
            wdSortSeparateByCommas, SortColumn:=False, CaseSensitive:=False, _
            LanguageID:=wdEnglishUK, SubFieldNumber:="Paragraphs", SubFieldNumber2:= _
            "Paragraphs", SubFieldNumber3:="Paragraphs"
            
        Selection.Columns(7).Delete
        
        With ActiveDocument.Tables(1)
            noCol = .Range.Rows(1).Cells.Count
                For blRows = .Rows.Count To 1 Step -1
                    With .Rows(blRows)
                        If Len(.Range) = noCol * 2 + 2 Then .Delete
                    End With
                Next blRows
        End With
    
        Application.ScreenUpdating = True
        Application.Screenrefresh
              
        oNewDoc.Activate
        MsgBox cmSummary & revSummary & "Finished creating tracker.", vbOKOnly + vbInformation, "Job summary"
        
    
    
    ExitHere:
        Set oDoc = Nothing
        Set oNewDoc = Nothing
        Set oTable = Nothing
        Set crsRng = Nothing
        Set Cmt2ex = Nothing
        Set Review2ex = Nothing
        Erase Cmt2exArr
        Erase Rev2exArr
       
    End Sub
    Last edited by h2whoa; 07-10-2018 at 09:24 AM.

  18. #18
    Microsoft Word MVP 2003-2009 VBAX Guru gmaxey's Avatar
    Joined
    Sep 2005
    Posts
    3,335
    Location
    I haven't studied you code in detail but a few quick comments. You have a few variables that are not declared:

    blDimensioned, Title, Rvtext, myTable noCol

    In your public declarations, when you declare thing like this:

    Public cmSummary, revSummary, scrllPs As String

    You have declarded scrllP as string and everything else as a variant. Do it like this:
    Public cmSummary as String, revSummary as String, scrllPs As String

    If only have one comment you get a run time error subscript out of range on this line:

    Rev2exArr(LBound(Rev2exArr)) = "ZilchRev 1"

    If you have one comment and one revision, you get a run time error subscript out of range on this line:

    Cmt2exArr(LBound(Cmt2exArr)) = "ZilchCom 1"
    Greg

    Visit my website: http://gregmaxey.com

  19. #19
    VBAX Regular
    Joined
    Oct 2016
    Posts
    45
    Location
    Thank you for putting in the time to study this code! I was too vigorous in cleaning up all the 'dead' declarations that arose during the evolution of this code, and must have wiped out some needed variables.

    That's really good to know about only declaring the last item as the variable type. I was under the misapprehension that it was declaring that whole line as a string! Great to know, and may explain some errors I encountered.

    I was so busy testing this code on a document with 122 tracked changes and 147 comments from 8 authors that I never thought to check with a single author. D'oh! I think I know why that is. I haven't setup the Cmt/Rev2exArr's properly. Will take a look now, revise the code and repost.

    Your expertise and knowledge is genuinely appreciated. I love learning this stuff, but I only do it through brute force trial and error.

  20. #20
    VBAX Regular
    Joined
    Oct 2016
    Posts
    45
    Location
    Thanks, Greg, for pointing out some of the existing errors. I think I've corrected them. The only thing I do find is that sometimes it will fall over on the Like test or the .Type part of the Grid maker macro. However, if I close and reopen the document I was testing, it then works fine. So I don't really know why it's doing it. But overall, this seems to be doing the job now

    'Public declarations
    Public blDimensioned As Boolean, cmInc As Boolean, cmEx As Boolean, comSkip As Boolean, revInc As Boolean, revEx As Boolean, revSkip As Boolean
    Public cmSummary As String, revSummary As String, scrllPs As String
    Public nCount As Long, lAn As Long, lFAn As Long, cmTally As Long, _
            rCount As Long, indelCount As Long, lRn As Long, lFRevn As Long, revTally As Long
    Public crsRng As Range
    Public nc2 As Integer, rev2exN As Integer
    Public Cmt2ex As New Collection, cd
    Public Review2ex As New Collection, rd
    Public Cmt2exArr() As String
    Public Rev2exArr() As String
    Public oDoc As Document
    
    
    
    'Master sub to run the lot
    Public Sub Comment_And_InDel_Grid()
    i_Reset_Pub_Decs
    ii_Com_Analyse
    iii_Rev_Analyse
    iv_Grid_maker
    End Sub
    
    
    
    'Sub to ensure all public declarations are reset
    Public Sub i_Reset_Pub_Decs()
        cmInc = False: cmEx = False: comSkip = False: revInc = False: revEx = False: revSkip = False: blDimensioned = False
        
        cmSummary = "": revSummary = "": scrllPs = ""
        nCount = 0: lAn = 0: lFAn = 0: cmTally = 0: rCount = 0: indelCount = 0: lRn = 0: lFRevn = 0: revTally = 0: nc2 = 0: rev2exN = 0
        
        Set crsRng = Nothing: Set Cmt2ex = Nothing: Set Review2ex = Nothing: Set oDoc = Nothing
        Set crsRng = Nothing: Set Cmt2ex = Nothing: Set Review2ex = Nothing
        Erase Cmt2exArr: Erase Rev2exArr
    
    
    End Sub
    
    
    
    'Sub to gather comment info
    Public Sub ii_Com_Analyse()
    
    
        Dim b As Long, c As Long, e As Long, g As Long, h As Long, i As Long, j As Long
        Dim sCmAuTxt1 As String, initCSum As String, chsEx As String, stCmtAuth As String, sTCmAs As String, ComNum As String, _
            rtrn2ex As String, rtrn2exsel As String, cmtMax As String, selComs As String, stSkpRv As String, C2X As String
        Dim CmtAuArr() As String
        Dim CmtCol As New Collection, ca
    
    
        sCmAuTxt1 = "The following people have made comments:" & vbNewLine & vbNewLine
    
    
        Set oDoc = ActiveDocument
        nCount = ActiveDocument.Comments.Count
        rCount = ActiveDocument.Revisions.Count
        cmInc = False
        comSkip = False
        Set crsRng = Selection.Range
        scrllPs = ActiveWindow.ActivePane.VerticalPercentScrolled
        
        If (nCount = 0) And (rCount > 0) Then
            MsgBox "There are no comments in this document.", vbOKOnly + vbCritical
            cmInc = False: cmEx = False: comSkip = True
            ReDim Cmt2exArr(0 To 1) As String
                Cmt2exArr(0) = ""
                Cmt2exArr(1) = "ZilchCom"
            GoTo Revcheck
        ElseIf (nCount = 0) And (rCount = 0) Then
            MsgBox "There are no comments or changes in this document in this document.", vbOKOnly + vbCritical
            Set oDoc = Nothing
            End
        ElseIf nCount >= 1 Then
            'Compiles a list of people who have made comments in the document
            blDimensioned = False
            For b = 1 To nCount
                stCmtAuth = ActiveDocument.Comments(b).Author
                If stCmtAuth <> "" Then
                    If blDimensioned = True Then
                        ReDim Preserve CmtAuArr(0 To UBound(CmtAuArr) + 1) As String
                    Else
                        ReDim CmtAuArr(0 To 0) As String
                        CmtAuArr(0) = ""
                        blDimensioned = True
                    End If
                    CmtAuArr(UBound(CmtAuArr)) = stCmtAuth
                End If
            Next
            
            'Collects and counts authors
            On Error Resume Next
            For Each ca In CmtAuArr
                CmtCol.Add ca, ca
            Next
            
            lAn = CmtCol.Count
            
            'Commenter exclusion text building
            If CmtCol.Count = 1 Then
                If nCount = 1 Then
                    ComNum = "There is only one comment from: "
                ElseIf nCount > 1 Then
                    ComNum = "There are " & nCount & " comments from: "
                End If
                cmtMax = "As there is only one author, you can't exclude them from the tracker."
                initCSum = ComNum & CmtCol(1) & "." & vbNewLine & vbNewLine & "Do you want to include comments in the tracker?"
            ElseIf CmtCol.Count >= 2 Then
                sTCmAs = ""
                For c = 1 To lAn
                    sTCmAs = sTCmAs & c & ". " & CmtCol(c) & vbNewLine
                Next
                
                initCSum = "There are " & nCount & " comments from " & lAn & " people." & vbNewLine & sCmAuTxt1 & sTCmAs & vbNewLine _
                & vbNewLine & "Do you want to include comments in the tracker?"
                
                If CmtCol.Count > 2 Then
                    lFAn = CmtCol.Count - 1
                    cmtMax = "You can exclude comments from a maximum of " & lFAn & " people." & vbNewLine & vbNewLine & "Do you want to exclude anyone?"
                ElseIf CmtCol.Count = 2 Then
                    lFAn = 1
                    cmtMax = "You can exclude comments from a maximum of one person." & vbNewLine & vbNewLine & "Do you want to exclude anyone?"
                End If
            End If
        End If
        
        'Decide whether to include comments in the tracker
        selComs = MsgBox(initCSum, vbYesNo + vbQuestion)
        
        If selComs = vbYes Then
            cmInc = True
        ElseIf selComs = vbNo Then
            comSkip = True: cmInc = False: cmEx = False
            ReDim Cmt2exArr(0 To 1) As String
                Cmt2exArr(0) = ""
                Cmt2exArr(1) = "ZilchCom"
            GoTo Revcheck
        End If
    Revcheck:
        If rCount > 0 Then
            stSkpRv = MsgBox("Will you want to process tracked changes?", vbYesNo + vbQuestion)
            If stSkpRv = vbYes Then
                revSkip = False: revInc = True
            ElseIf stSkpRv = vbNo Then
                revSkip = True
                revInc = False: revEx = False
                ReDim Rev2exArr(0 To 1) As String
                    Rev2exArr(0) = ""
                    Rev2exArr(1) = "ZilchRev"
            End If
            If comSkip = True Then GoTo EndComCount
        ElseIf rCount = 0 Then
            MsgBox "There are no tracked changes in this document. Only comments will be extracted.", vbOKOnly + vbInformation
            revSkip = True
            revInc = False: revEx = False
            ReDim Rev2exArr(0 To 1) As String
                Rev2exArr(0) = ""
                Rev2exArr(1) = "ZilchRev"
        End If
            
        If lAn = 1 Then
            If MsgBox(cmtMax & vbNewLine & vbNewLine & "Press OK to continue" & vbNewLine & vbNewLine & _
                    "Press Cancel to quit extracting comments", vbOKCancel + vbInformation) = vbOK Then
                cmInc = True: cmEx = False
                ReDim Cmt2exArr(0 To 1) As String
                    Cmt2exArr(0) = ""
                    Cmt2exArr(1) = "ZilchCom"
                If nCount = 1 Then
                    cmSummary = "The comment from " & """" & CmtCol(1) & """" & " has been extracted." & vbNewLine & vbNewLine
                ElseIf nCount >= 2 Then
                    cmSummary = "All " & nCount & " comments from " & """" & CmtCol(1) & """" & " have been extracted." & vbNewLine & vbNewLine
                End If
                GoTo EndComCount
            Else
                cmInc = False: cmEx = False
                ReDim Cmt2exArr(0 To 1) As String
                    Cmt2exArr(0) = ""
                    Cmt2exArr(1) = "ZilchCom"
                GoTo EndComCount
            End If
        Else
            'Choose whether to exclude any commenters
            chsEx = MsgBox("LAN > 1!!" & sCmAuTxt1 & sTCmAs & vbNewLine & cmtMax, vbYesNoCancel)
            If chsEx = vbYes Then
                cmEx = True
    n2ex:
                'Choose number of commenters to exclude
                nc2 = InputBox(sCmAuTxt1 & sTCmAs & vbNewLine & "How many people do you want to exclude?" & vbNewLine & vbNewLine & "Maximum of " & lFAn & ".", "Number to exclude")
                
                'Number validity testing
                If (IsNumeric(nc2) = False) Or (nc2 > (CmtCol.Count - 1)) Or (nc2 = 0) Then
                    rtrn2ex = MsgBox("Invalid value." & vbNewLine & vbNewLine & "ABORT to not extract comments" _
                    & vbNewLine & vbNewLine & "RETRY to enter valid value" _
                    & vbNewLine & vbNewLine & "IGNORE to proceed without excluding anyone.", vbAbortRetryIgnore + vbCritical)
                    If rtrn2ex = vbRetry Then
                        GoTo n2ex
                    
                    ElseIf rtrn2ex = vbAbort Then
                        cmInc = False: cmEx = False
                        ReDim Cmt2exArr(0 To 1) As String
                            Cmt2exArr(0) = ""
                            Cmt2exArr(1) = "ZilchCom"
                        GoTo EndComCount
                    
                    ElseIf rtrn2ex = vbIgnore Then
                        cmInc = True: cmEx = False
                        ReDim Cmt2exArr(0 To 1) As String
                            Cmt2exArr(0) = ""
                            Cmt2exArr(1) = "ZilchCom"
                        cmSummary = "All " & nCount & " comments extracted."
                        GoTo EndComCount
                    End If
                Else
                    'Build user-defined list of commenters to exclude
                    blDimensioned = False
                    For e = 1 To nc2
    Exn:
                        j = InputBox(sCmAuTxt1 & sTCmAs & vbNewLine & "Enter the number of the person to exclude, from the list above.")
                            If (j > CmtCol.Count) Or (j = 0) Or (IsNumeric(j) = False) Then
                                rtrn2exsel = MsgBox("Invalid value." & vbNewLine & vbNewLine & "ABORT to not extract comments" _
                                            & vbNewLine & vbNewLine & "RETRY to enter valid value" _
                                            & vbNewLine & vbNewLine & "IGNORE to proceed without excluding anyone.", vbAbortRetryIgnore + vbCritical)
                                            
                                            If rtrn2exsel = vbRetry Then
                                            GoTo Exn
                                            
                                            ElseIf rtrn2exsel = vbAbort Then
                                                cmInc = False: cmEx = False
                                                ReDim Cmt2exArr(0 To 1) As String
                                                    Cmt2exArr(0) = ""
                                                    Cmt2exArr(1) = "ZilchCom"
                                                GoTo EndComCount
                                            
                                            ElseIf rtrn2exsel = vbIgnore Then
                                                cmInc = True: cmEx = False
                                                ReDim Cmt2exArr(0 To 1) As String
                                                    Cmt2exArr(0) = ""
                                                    Cmt2exArr(1) = "ZilchCom"
                                                cmSummary = "All " & nCount & " comments extracted."
                                                GoTo EndComCount
                                            End If
                                Else
                                
                                    C2X = CmtCol(j)
                                    
                        
                                    If blDimensioned = True Then
                                        ReDim Preserve Cmt2exArr(0 To UBound(Cmt2exArr) + 1) As String
                                    Else
                                        ReDim Cmt2exArr(0 To 0) As String
                                        Cmt2exArr(0) = ""
                                        blDimensioned = True
                                    End If
                                    Cmt2exArr(UBound(Cmt2exArr)) = C2X
                                End If
                    Next
                    
                    
                    On Error Resume Next
                    For Each cd In Cmt2exArr
                        Cmt2ex.Add cd, cd
                    Next
                    
                    'Counts number of comments made by authors to exclude
                    For g = LBound(Cmt2exArr) To UBound(Cmt2exArr)
                        h = 0
                        For i = 1 To nCount
                            With oDoc.Comments(i)
                                If .Author = Cmt2exArr(g) Then h = h + 1
                            End With
                        Next
                    Next
                    
                    'Counts number of comments that are included in the tracker
                    cmTally = nCount - h
                    
                    cmSummary = "Extracted:" & vbTab & vbTab & vbTab & cmTally & " comments from " & Cmt2ex.Count & " people." & vbNewLine _
                                & "Total in document:" & vbTab & vbTab & nCount & " comments from" & vbNewLine _
                                & vbTab & vbTab & vbTab & lAn & " people." & vbNewLine & vbNewLine
                
                End If
            
            ElseIf chsEx = vbNo Then
                cmInc = True: cmEx = False
                ReDim Cmt2exArr(0 To 1) As String
                    Cmt2exArr(0) = ""
                    Cmt2exArr(1) = "ZilchCom"
                cmSummary = "All " & nCount & " comments from " & CmtCol(1) & " extracted."
                GoTo EndComCount
            ElseIf chsEx = vbCancel Then
                cmInc = False: cmEx = False
                ReDim Cmt2exArr(0 To 1) As String
                    Cmt2exArr(0) = ""
                    Cmt2exArr(1) = "ZilchCom"
                GoTo EndComCount
            End If
        End If
    
    
    EndComCount:
    End Sub
    
    
    
    'Sub to gather information about the tracked insertions and deletions
    
    Public Sub iii_Rev_Analyse()
    
    
        Dim b As Long, c As Long, e As Long, g As Long, h As Long, i As Long, n As Long
        Dim sReviewerTxt1 As String, initRevSum As String, chsRevEx As String, stReviewer As String, sTReviewrs As String, _
            rtrn2Revex As String, revMax As String, selRevs As String, rtrnrvlist As String, R2X As String, RevNum As String
        Dim ReviewerArr() As String
        Dim RevCol As New Collection, ra
    
    
        If revSkip = True Then GoTo EndRevCount
        
        sReviewerTxt1 = "The following people have made tracked insertions/deletions:" & vbNewLine & vbNewLine
    
    
        revInc = False
        
        If rCount = 1 Then
            Application.ScreenUpdating = False
            Selection.HomeKey Unit:=wdStory
            Selection.NextRevision.Range.Select
            With Selection.Range.Revisions(1)
                If .Type = wdRevisionDelete Or wdRevisionInsert Then
                    indelCount = 1
                    lRn = 1
                    revEx = False
                    stReviewer = .Author
                    ReDim ReviewerArr(0 To 1) As String
                        ReviewerArr(0) = ""
                        ReviewerArr(1) = stReviewer
                    
                    ReDim Rev2exArr(0 To 1) As String
                        Rev2exArr(0) = ""
                        Rev2exArr(1) = "ZilchRev"
                Else
                    crsRng.Select
                    ActiveWindow.ActivePane.VerticalPercentScrolled = scrllPs
                    Application.ScreenUpdating = True
                    MsgBox "There are no tracked insertions/deletions in this document.", vbOKOnly + vbCritical
                    revInc = False: revEx = False
                    ReDim Rev2exArr(0 To 1) As String
                        Rev2exArr(0) = ""
                        Rev2exArr(1) = "ZilchRev"
                    GoTo EndRevCount
                End If
            End With
        
        ElseIf rCount > 1 Then
            'Compiles a list of people who have made changes in the document
            
            MsgBox "Note: Word may appear to freeze at various points. Please be patient." & vbNewLine & vbNewLine & _
                    "The more tracked changes there are, the longer the freezes will be.", vbOKOnly + vbInformation, "Word is now processing tracked changes"
            
            Application.Screenrefresh
            Application.ScreenUpdating = False
            Selection.HomeKey Unit:=wdStory
            
            indelCount = 0
            
            blDimensioned = False
            For b = 1 To rCount
                Selection.NextRevision
                With Selection.Range.Revisions(1)
                    If ((.Type = wdRevisionDelete) Or (.Type = wdRevisionInsert)) _
                    And (.Range.Text Like "*[ A-z0-9\,\.\?\(\)\;]*") Then
                        indelCount = indelCount + 1
                        stReviewer = .Author
                        If stReviewer <> "" Then
                            If blDimensioned = True Then
                                ReDim Preserve ReviewerArr(0 To UBound(ReviewerArr) + 1) As String
                            Else
                                ReDim ReviewerArr(0 To 0) As String
                                ReviewerArr(0) = ""
                                blDimensioned = True
                            End If
                            ReviewerArr(UBound(ReviewerArr)) = stReviewer
                        End If
                    End If
                End With
            Next
        End If
            
        'Collects and counts reviewers
        On Error Resume Next
        For Each ra In ReviewerArr
            RevCol.Add ra, ra
        Next
        
        lRn = RevCol.Count
        
        crsRng.Select
        ActiveWindow.ActivePane.VerticalPercentScrolled = scrllPs
        Application.ScreenUpdating = True
        
        If indelCount = 0 Then
            MsgBox "There are no tracked insertions/deletions in this document.", vbOKOnly + vbCritical
            revInc = False
            GoTo EndRevCount
        End If
        
        'Reviewer exclusion text building
        If RevCol.Count = 1 Then
            If indelCount = 1 Then
                RevNum = "There is only one tracked insertion/deletion from: "
            ElseIf indelCount > 1 Then
                RevNum = "There are " & indelCount & " tracked insertions/deletions from: "
            End If
            revMax = "There is only one reviewer, so you can't exclude them from the tracker."
            initRevSum = RevNum & RevCol(1) & "." & vbNewLine & vbNewLine & "Do you want to include tracked changes in the tracker?"
        ElseIf RevCol.Count > 1 Then
            sTReviewrs = ""
            For c = 1 To lRn
                sTReviewrs = sTReviewrs & c & ". " & RevCol(c) & vbNewLine
            Next
            
            initRevSum = "There are " & indelCount & " tracked insertions/deletions from " & lRn & " people." & vbNewLine & sReviewerTxt1 & sTReviewrs & vbNewLine _
            & vbNewLine & "Do you want to include tracked changes in the tracker?"
            
            If RevCol.Count > 2 Then
                lFRevn = RevCol.Count - 1
                revMax = "You can exclude tracked insertions/deletions from a maximum of " & lFRevn & " people." & vbNewLine & vbNewLine & "Do you want to exclude anyone?"
            ElseIf RevCol.Count = 2 Then
                lFRevn = 1
                revMax = "You can exclude tracked insertions/deletions from a maximum of one person." & vbNewLine & vbNewLine & "Do you want to exclude anyone?"
            End If
        End If
        
        'Decide whether to include tracked changes in the tracker
        selRevs = MsgBox(initRevSum, vbYesNo + vbQuestion)
        
        If selRevs = vbYes Then
            revInc = True
        ElseIf selRevs = vbNo Then
            revInc = False: revEx = False
            ReDim Rev2exArr(0 To 1) As String
                Rev2exArr(0) = ""
                Rev2exArr(1) = "ZilchRev"
            GoTo EndRevCount
        End If
            
        If lRn = 1 Then
            If MsgBox(revMax, vbOKCancel + vbInformation) = vbOK Then
                revInc = True: revEx = False
                ReDim Rev2exArr(0 To 1) As String
                    Rev2exArr(0) = ""
                    Rev2exArr(1) = "ZilchRev"
                If indelCount = 1 Then
                    revSummary = "The tracked insertions/deletion from " & """" & RevCol(1) & """" & " has been extracted." & vbNewLine & vbNewLine
                ElseIf indelCount >= 2 Then
                    revSummary = "All " & indelCount & " tracked insertions/deletions from " & """" & RevCol(1) & """" & " have been extracted." & vbNewLine & vbNewLine
                End If
                GoTo EndRevCount
            Else
                revInc = False: revEx = False
                ReDim Rev2exArr(0 To 1) As String
                    Rev2exArr(0) = ""
                    Rev2exArr(1) = "ZilchRev"
                GoTo EndRevCount
            End If
        Else
            'Choose whether to exclude any reviewers
            chsRevEx = MsgBox(sReviewerTxt1 & sTReviewrs & vbNewLine & revMax, vbYesNoCancel)
            If chsRevEx = vbYes Then
                revEx = True
    nrv2ex:
                'Choose number of reviewers to exclude
                rev2exN = InputBox(sReviewerTxt1 & sTReviewrs & vbNewLine & "How many people do you want to exclude?" & vbNewLine & vbNewLine & "Maximum of " & lFRevn & ".", "Number to exclude")
                
                'Number validity testing
                If (IsNumeric(rev2exN) = False) Or (rev2exN > (RevCol.Count - 1)) Or (rev2exN < 1) Then
                    rtrn2Revex = MsgBox("Invalid value." & vbNewLine & vbNewLine & "ABORT to not extract revisions" _
                    & vbNewLine & vbNewLine & "RETRY to enter valid value" _
                    & vbNewLine & vbNewLine & "IGNORE to proceed without excluding anyone.", vbAbortRetryIgnore + vbCritical)
                    If rtrn2Revex = vbRetry Then
                        GoTo nrv2ex
                    ElseIf rtrn2Revex = vbAbort Then
                        revInc = False: revEx = False
                        ReDim Rev2exArr(0 To 1) As String
                            Rev2exArr(0) = ""
                            Rev2exArr(1) = "ZilchRev"
                        GoTo EndRevCount
                    ElseIf rtrn2Revex = vbIgnore Then
                        revInc = True: revEx = False
                        ReDim Rev2exArr(0 To 1) As String
                            Rev2exArr(0) = ""
                            Rev2exArr(1) = "ZilchRev"
                        revSummary = "All " & indelCount & " insertions/deletions from all " & lRn & " people extracted."
                        GoTo EndRevCount
                    End If
                Else
                    'Build user-defined list of reviewers to exclude
                    blDimensioned = False
                    For e = 1 To rev2exN
    Revexlist:
                        n = InputBox(sReviewerTxt1 & sTReviewrs & vbNewLine & "Enter the number of the person to exclude, exactly " & _
                                    vbNewLine & "as it appears in the list above.")
                            If (n > RevCol.Count) Or (n = 0) Or (IsNumeric(n) = False) Then
                                rtrnrvlist = MsgBox("Invalid value." & vbNewLine & vbNewLine & "ABORT to not extract revisions" _
                                            & vbNewLine & vbNewLine & "RETRY to enter valid value" _
                                            & vbNewLine & vbNewLine & "IGNORE to proceed without excluding anyone.", vbAbortRetryIgnore + vbCritical)
                                            
                                            If rtrn2Revex = vbRetry Then
                                                GoTo Revexlist
                                            ElseIf rtrn2Revex = vbAbort Then
                                                revInc = False: revEx = False
                                                ReDim Rev2exArr(0 To 1) As String
                                                    Rev2exArr(0) = ""
                                                    Rev2exArr(1) = "ZilchRev"
                                                GoTo EndRevCount
                                            ElseIf rtrn2Revex = vbIgnore Then
                                                revInc = True: revEx = False
                                                ReDim Rev2exArr(0 To 1) As String
                                                    Rev2exArr(0) = ""
                                                    Rev2exArr(1) = "ZilchRev"
                                                revSummary = "All " & indelCount & " insertions/deletions from all " & lRn & " people extracted."
                                                GoTo EndRevCount
                                            End If
                            Else
                                R2X = RevCol(n)
                                
                                If blDimensioned = True Then
                                    ReDim Preserve Rev2exArr(0 To UBound(Rev2exArr) + 1) As String
                                Else
                                    ReDim Rev2exArr(0 To 0) As String
                                    Rev2exArr(0) = ""
                                    blDimensioned = True
                                End If
                                Rev2exArr(UBound(Rev2exArr)) = R2X
                            End If
                    Next
                    
                    On Error Resume Next
                    For Each rd In Rev2exArr
                        Review2ex.Add rd, rd
                    Next
                    
                    
                    'Counts number of changes made by reviewers to exclude
                    Application.ScreenUpdating = False
                    Selection.HomeKey Unit:=wdStory
                    
                    
                    h = 0
                    For i = 1 To rCount
                        With Selection.NextRevision
                            If .Range.Text Like "*[ A-z0-9\,\.\?\(\)\;]*" Then
                                For g = LBound(Rev2exArr) To UBound(Rev2exArr)
                                    If .Author = Rev2exArr(g) Then h = h + 1
                                Next
                            End If
                        End With
                    Next
                    
                    
                    crsRng.Select
                    ActiveWindow.ActivePane.VerticalPercentScrolled = scrllPs
                    Application.ScreenUpdating = True
                    Application.Screenrefresh
                    
                    
                    'Counts number of changes that are included in the tracker
                    revTally = indelCount - h
                    
                    revSummary = "Extracted:" & vbTab & vbTab & vbTab & revTally & " tracked insertions/deletions" & vbNewLine _
                                & vbTab & vbTab & vbTab & "from " & Review2ex.Count & " people." & vbNewLine & "Total in document:" _
                                & vbTab & vbTab & indelCount & " tracked insertions/deletions" & vbNewLine _
                                & vbTab & vbTab & vbTab & "from " & lRn & " people." & vbNewLine & vbNewLine
                
                End If
                
            ElseIf chsRevEx = vbNo Then
                revInc = True: revEx = False
                ReDim Rev2exArr(0 To 1) As String
                    Rev2exArr(0) = ""
                    Rev2exArr(1) = "ZilchRev"
                revSummary = "All " & indelCount & " insertions/deletions from all " & lRn & " people extracted."
                GoTo EndRevCount
            ElseIf chsRevEx = vbCancel Then
                revInc = False: revEx = False
                ReDim Rev2exArr(0 To 1) As String
                    Rev2exArr(0) = ""
                    Rev2exArr(1) = "ZilchRev"
                GoTo EndRevCount
            End If
        End If
    EndRevCount:
    End Sub
    
    
    
    'Final sub to collect everything together and put it into the grid
    
    Public Sub iv_Grid_maker()
    
    
        Dim oNewDoc As Document
        Dim oTable As Table, oTracker As Table
        Dim NXTA As Boolean, NXTR As Boolean
        Dim f As Long, i As Long, j As Long, n As Long, z As Long, blRows As Long
        Dim Rvtype As String, Rvpage As String, Rvsort As String, Rvauth As String, Rvtext As String
        
        Set oDoc = ActiveDocument
        rCount = oDoc.Revisions.Count
        
        Application.Screenrefresh
        
        If cmInc = False And revInc = False Then
            MsgBox "No comments or revisions selected.", vbOKOnly + vbInformation
            GoTo ExitHere
        End If
        
           
    Start:
        Application.Screenrefresh
        MsgBox "Word may appear to freeze during this process!" & vbNewLine & vbNewLine & "Don't panic! Word has not crashed. Just wait for the process to finish." & vbNewLine & vbNewLine & "The more revisions and comments there are, the longer the process will take.", vbOKOnly, "DON'T PANIC!"
        Application.ScreenUpdating = False
        Set oNewDoc = Documents.Add
        oNewDoc.PageSetup.Orientation = wdOrientLandscape
        With oNewDoc
            .Content = ""
            If cmInc = True And revInc = False Then
                Set oTable = .Tables.Add _
                    (Range:=Selection.Range, _
                    numRows:=nCount + 1, _
                    NumColumns:=7)
                    
                .Sections(1).Headers(wdHeaderFooterPrimary).Range.Text = _
                "Comments extracted from: " & oDoc.Name
                
            ElseIf cmInc = False And revInc = True Then
                Set oTable = .Tables.Add _
                    (Range:=Selection.Range, _
                    numRows:=rCount + 1, _
                    NumColumns:=7)
                    
                .Sections(1).Headers(wdHeaderFooterPrimary).Range.Text = _
                "Revisions extracted from: " & oDoc.Name
                    
            ElseIf cmInc = True And revInc = True Then
                Set oTable = .Tables.Add _
                    (Range:=Selection.Range, _
                    numRows:=nCount + rCount + 1, _
                    NumColumns:=7)
                    
                .Sections(1).Headers(wdHeaderFooterPrimary).Range.Text = _
                "Comments and revisions extracted from: " & oDoc.Name
                    
            End If
        End With
    
    
        With oNewDoc.Styles(wdStyleNormal)
            .Font.Name = "Calibri"
            .Font.Size = 9
            .ParagraphFormat.LeftIndent = 0
            .ParagraphFormat.SpaceAfter = 6
        End With
       
        With oNewDoc.Styles(wdStyleHeader)
            .Font.Size = 8
            .ParagraphFormat.SpaceAfter = 0
        End With
    
    
        With oTable
            .Range.Style = wdStyleNormal
            .AllowAutoFit = False
            .PreferredWidthType = wdPreferredWidthPercent
            .PreferredWidth = 100
            .Columns.PreferredWidthType = wdPreferredWidthPercent
            .Columns(1).PreferredWidth = 5
            .Columns(2).PreferredWidth = 10
            .Columns(3).PreferredWidth = 25
            .Columns(4).PreferredWidth = 25
            .Columns(5).PreferredWidth = 15
            .Columns(6).PreferredWidth = 30
            .Columns(7).PreferredWidth = 2
            .Rows(1).HeadingFormat = True
        End With
    
    
        With oTable.Rows(1)
            .Range.Font.Bold = True
            .Cells(1).Range.Text = "Page"
            .Cells(2).Range.Text = "Type"
            .Cells(3).Range.Text = "Comment"
            .Cells(4).Range.Text = "Relevant text"
            .Cells(5).Range.Text = "Commenter"
            .Cells(6).Range.Text = "Action/response"
            .Cells(7).Range.Text = "Sort"
        End With
    
    
    Comments:
        If cmInc = False Then GoTo Tracks
        
        If cmInc = True Then
                    f = 1
                    With oDoc
                        For n = 1 To nCount
                            With oDoc
                                NXTA = False
                                If cmEx = True Then
                                    For i = LBound(Cmt2exArr) To UBound(Cmt2exArr)
                                        If oDoc.Comments(n).Author = Cmt2exArr(i) Then NXTA = True
                                    Next
                                End If
                            End With
                                
                                If NXTA = False Then
                                
                                    f = f + 1
                                    
                                    With oNewDoc
                                        oTable.Rows.Add
                                    
                                        With oTable.Rows(f)
                                            .Cells(1).Range.Text = _
                                                oDoc.Comments(n).Scope.Information(wdActiveEndPageNumber)
                                            .Cells(2).Range.Text = "Comment"
                                            .Cells(3).Range.Text = oDoc.Comments(n).Range.Text
                                            .Cells(4).Range.Text = oDoc.Comments(n).Scope
                                            .Cells(5).Range.Text = oDoc.Comments(n).Author
                                            .Cells(7).Range.Text = oDoc.Comments(n).Scope.Information(wdFirstCharacterLineNumber)
                                        End With
                                    End With
                                End If
    NextComB:
                        Next
                    End With
    
    
        End If
    
    
    Tracks:
        If revInc = False Then GoTo Finalise
        
        Application.ScreenUpdating = False
        Selection.HomeKey Unit:=wdStory
        
        If (cmInc = False) Or (comSkip = True) Then f = 1
            
                With oDoc
                    Selection.HomeKey Unit:=wdStory
                    On Error GoTo NextRevb
                    For z = 0 To rCount
                        With oDoc
                            With Selection.NextRevision
                                NXTR = False
                                If revEx = True Then
                                    For j = LBound(Rev2exArr) To UBound(Rev2exArr)
                                        If .Author = Rev2exArr(j) Then NXTR = True
                                    Next
                                End If
                                
                                If NXTR = False Then
                                    f = f + 1
                                    If (.Range.Text Like "*[ A-z0-9\,\.\?\(\)\;]*") _
                                        And (.Type = wdRevisionDelete) Then
                                        
                                        Rvtype = "Delete"
                                        Rvpage = .Range.Information(wdActiveEndPageNumber)
                                        Rvauth = .Author
                                        Rvsort = .Range.Information(wdFirstCharacterLineNumber)
                                        Rvtext = """" & .Range.Text & """"
                                    
                                    ElseIf (.Range.Text Like "*[ A-z0-9\,\.\?\(\)\;]*") _
                                        And (.Type = wdRevisionInsert) Then
                                        
                                        Rvtype = "Insert"
                                        Rvpage = .Range.Information(wdActiveEndPageNumber)
                                        Rvauth = .Author
                                        Rvsort = .Range.Information(wdFirstCharacterLineNumber)
                                        Rvtext = """" & .Range.Text & """"
                                    
                                    Else
                                        
                                        Rvtype = ""
                                        Rvpage = ""
                                        Rvauth = ""
                                        Rvsort = ""
                                        Rvtext = ""
                                    
                                    End If
                                End If
                            
                            End With
                        End With
                                            
                            If NXTR = False Then
                                With oNewDoc
                                    oTable.Rows.Add
                                        
                                    With oTable.Rows(f)
                                        .Cells(1).Range.Text = Rvpage
                                        .Cells(2).Range.Text = Rvtype
                                        .Cells(4).Range.Text = Rvtext
                                        .Cells(5).Range.Text = Rvauth
                                        .Cells(7).Range.Text = Rvsort
                                        
                                        If Rvtype = "Delete" Then
                                            .Cells(2).Range.Font.Color = wdColorRed
                                            .Cells(4).Range.Font.Color = wdColorRed
                                        ElseIf Rvtype = "Insert" = True Then
                                            .Cells(2).Range.Font.Color = wdColorBlue
                                            .Cells(4).Range.Font.Color = wdColorBlue
                                        End If
                                    End With
                                End With
                            End If
    NextRevb:
                    oDoc.Activate
                    Next
                End With
                
                crsRng.Select
                ActiveWindow.ActivePane.VerticalPercentScrolled = scrllPs
                GoTo Finalise
      
    Finalise:
        oNewDoc.Activate
        Set oTracker = ActiveDocument.Tables(1)
        With oTracker.Borders
            .InsideLineStyle = wdLineStyleSingle
            .OutsideLineStyle = wdLineStyleSingle
        End With
        
        oTracker.Select
        
        With Selection
    
    
            .Sort ExcludeHeader:=True, FieldNumber:="Column 1", SortFieldType _
            :=wdSortFieldNumeric, SortOrder:=wdSortOrderAscending, FieldNumber2:= _
            "Column 7", SortFieldType2:=wdSortFieldNumeric, SortOrder2:= _
            wdSortOrderAscending, FieldNumber3:="", SortFieldType3:= _
            wdSortFieldAlphanumeric, SortOrder3:=wdSortOrderAscending, Separator:= _
            wdSortSeparateByCommas, SortColumn:=False, CaseSensitive:=False, _
            LanguageID:=wdEnglishUK, SubFieldNumber:="Paragraphs", SubFieldNumber2:= _
            "Paragraphs", SubFieldNumber3:="Paragraphs"
            
    
    
            .Columns(7).Delete
        End With
        
        
        With oTracker
                For blRows = .Rows.Count To 1 Step -1
                    With .Rows(blRows)
                        If (.Cells(1).Range.Text = "" & Chr(13) & Chr(7)) And (.Cells(2).Range.Text = "" & Chr(13) & Chr(7)) And (.Cells(3).Range.Text = "" & Chr(13) & Chr(7)) _
                            And (.Cells(4).Range.Text = "" & Chr(13) & Chr(7)) And (.Cells(5).Range.Text = "" & Chr(13) & Chr(7)) _
                            And (.Cells(6).Range.Text = "" & Chr(13) & Chr(7)) Then .Delete
                    End With
                Next blRows
        End With
    
    
        
        Application.ScreenUpdating = True
        Application.Screenrefresh
              
        oNewDoc.Activate
        MsgBox cmSummary & revSummary & "Finished creating tracker.", vbOKOnly + vbInformation, "Job summary"
        
    
    
    ExitHere:
    
    
        cmInc = False: cmEx = False: comSkip = False: revInc = False: revEx = False: revSkip = False: blDimensioned = False
        
        cmSummary = "": revSummary = "": scrllPs = ""
        nCount = 0: lAn = 0: lFAn = 0: cmTally = 0: rCount = 0: indelCount = 0: lRn = 0: lFRevn = 0: revTally = 0: nc2 = 0: rev2exN = 0
        
        Set crsRng = Nothing: Set Cmt2ex = Nothing: Set Review2ex = Nothing: Set oDoc = Nothing
        Set crsRng = Nothing: Set Cmt2ex = Nothing: Set Review2ex = Nothing
        Erase Cmt2exArr: Erase Rev2exArr
        
        Set oNewDoc = Nothing: Set oTable = Nothing: Set oTracker = Nothing
       
    End Sub

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •