Over the last few years I have reviewed many student assignments, both at undergrad and PhD level, and as a favour for friends (or friends of friends), as a student supervisor, or as a freelance contractor. This kind of work has three main challenges:
- Timing: students, friends and clients often send you text to check at the very last minute. I think my personal record is sending the comments at 2am one morning (4 hours of broken sleep before a 6am start to a working day!)
- Constructive correction or comments: most often I work with people for whom English is not their first language (nor perhaps their second language either, which puts my language learning attempts to shame!). When I’m working in another language and I’m relaxed and confident, I really appreciate someone taking the time to explain my mistakes, but when I’m stressed and tired and I have a deadline, I just want the document corrected and to move on!
- Quantity of text that can be corrected: almost all my proofreading work is for people who will submit the work as their own, without formal reference to me or my help. So how much of a document can I/should I correct without formal recognition?
Co-author or ghost writer
When I first started proof reading, the first few thesis chapters I reviewed were high quality writing, which just needed the occasional grammatical correction. As I got more experience (and more work) the assignments needed a closer review, taking a longer periods of time, and more corrections, and I started to worry that, at some point, I would cross over into effectively ghost writing someone’s thesis. It’s easy to sit back and say that you should never do that, but it’s hard if you’ve been working with a client, or student, for sometime, to cut them adrift at the end of their studies (when most write ups are done) when they’re in real jam. Especially if that student has mortgaged the family home to study in the UK and hasn’t had any effective support from their department. (Although, as a university teacher is see that a lack of academic support can be a two way street, with students sometimes not taking their tutors advice in accessing support services.) I might be an OK-ish writer now, but Laurence Barron must have used a least one or two red pens marking up the first draft versions of my PhD!. Some time ago I decided that, as a freelancer, I could not write more than 10% of a text, without crossing over into ghost-writing. 10-20% seems to be a generally accepted similarity score (for systems like turnitin), so that where I based my level. The next problem is how I work out how much text I’ve changed. That’s where VBA helped again.
I got my first hint from the wordribbon.net website, but I wanted my code to:
- Count all the characters and words in the reviewed text
- Give me a percentage of the number of inserted text to the final number of words.
- Give me values for selected text, not just the whole document.
- Allow me to add the data into the document (so I could keep a record).
- The code from wordribbon produces approximate values because VBA counts punctuation characters and leading whitespace as words, but I wanted a proper word count.
Points 1 – 4 were easy to sort as its simple coding changes, but I spent an hour or so playing around with code similar to some previous Excel VBA to try and count the punctuation characters using Regex replacement commands! I ended up with something like the code below (just for those folks who might be interested)…
StripPunct = oRevision.Range.Text With CreateObject("VBScript.RegExp") .Global = True .Pattern = "[^0-9a-z-A-Z ]" StripPunct = .Replace(StripPunct, "") End With
…before I stumbled upon the ComputeStatistics command that would do it automatically. So the code is….
Sub GetTrackChangeStats() 'Basis taken from https://wordribbon.tips.net/T011484_Counting_Changed_Words 'ComputeStatistics from https://support.microsoft.com/en-us/topic/word-count-appears-inaccurate-when-you-use-the-vba-words-property-835c0cd8-3bff-50d0-b6ea-9da4ca22e3ff 'declare the variables and set them to nothing Dim lInsertsWords As Long Dim lInsertsChar As Long Dim lDeletesWords As Long Dim lDeletesChar As Long Dim lWords As Long Dim lChar As Long Dim sTemp As String Dim oRevision As Revision Dim answer As String lInsertsWords = 0 lInsertsChar = 0 lDeletesWords = 0 lDeletesChar = 0 lWords = 0 lChar = 0 sTemp = "" 'a messagebox to check if text has been selected. If Selection.Range.ComputeStatistics(wdStatisticWords) = 0 Then answer = MsgBox("You have not selected part of the document" & vbCrLf _ & "Do you want to check the whole document?", vbYesNo) If answer = vbYes Then ActiveDocument.Range.Select Else MsgBox ("Select part of the document an re-run the macro.") Exit Sub End If End If 'counts the characters and words in every revision in the range For Each oRevision In Selection.Range.Revisions Select Case oRevision.Type Case wdRevisionInsert lInsertsChar = lInsertsChar + Len(oRevision.Range.Text) lInsertsWords = lInsertsWords + oRevision.Range.ComputeStatistics(wdStatisticWords) Case wdRevisionDelete lDeletesChar = lDeletesChar + Len(oRevision.Range.Text) lDeletesWords = lDeletesWords + oRevision.Range.ComputeStatistics(wdStatisticWords) End Select Next oRevision lWords = Selection.Range.ComputeStatistics(wdStatisticWords) lChar = Len(Selection.Range.Text) 'creates the string for the message box sTemp = "Insertions" & vbCrLf sTemp = sTemp & " Words: " & lInsertsWords & vbCrLf sTemp = sTemp & " New Words: " & _ Round(100 * lInsertsWords / lWords, 2) & "%" & vbCrLf sTemp = sTemp & " Characters: " & lInsertsChar & vbCrLf sTemp = sTemp & "Deletions" & vbCrLf sTemp = sTemp & " Words: " & lDeletesWords & vbCrLf sTemp = sTemp & " Characters: " & lDeletesChar & vbCrLf sTemp = sTemp & "Current" & vbCrLf sTemp = sTemp & " Words: " & lWords & vbCrLf sTemp = sTemp & " Characters: " & lChar & vbCrLf & vbCrLf sTemp = sTemp & "Do you want this message inserted at" _ & vbCrLf & "the end of the selected text?" 'displays the message box to give the user 'the option of pasting the values into the 'document (at the end of the selection) 'it rewrites the sTemp string answer = MsgBox(sTemp, vbYesNo) If answer = vbYes Then sTemp = "Insertions: Words " & lInsertsWords sTemp = sTemp & " : New Words " & _ Round(100 * lInsertsWords / lWords, 2) & "%" sTemp = sTemp & " : Characters: " & lInsertsChar & vbCrLf sTemp = sTemp & "Deletions: Words " & lDeletesWords sTemp = sTemp & " : Characters: " & lDeletesChar & vbCrLf sTemp = sTemp & "Current: Words: " & lWords sTemp = sTemp & " :Characters: " & lChar & vbCrLf Selection.InsertAfter Text:=sTemp End If End Sub