Here’s how to replace private or confidential text with ‘filler’ nonsense or anonymous text in a Word document. Handy for getting help with Word formatting or numbering problems where you can’t share the real document to an outsider.
This is often a problem for legal workers or others with privacy considerations. It’s hard to ask for outside help with a Word formatting or numbering problem when you can’t share the troublesome document.
Most of the ‘solutions’ to this issue aren’t appropriate. Redaction or replacing text with black bars is hard to read. Random text in Word using Rand(), Rand.old() or Lorem() will insert filler text but not replace existing text, which can mess with the formatting.
We did some searches and could not find a solution so we fired up the VBA editor and wrote some code to do the job.
Our simple Word macro replaces each letter with a random letter, keeping upper/lower case. Digits are also randomly replaced. Formatting, numbering etc are all retained.
BUT — it’s not super-secure. Each letter is replaced with the same alternative letter throughout. A little elementary codebreaking can reverse the process and reveal the document. Sherlock Holmes used the technique to decipher the Dancing Men. (Thanks to Office Watcher David P. for pointing this out).
A standard document like this:
Is converted into the same formatting but random letters like this:
Send the converted document off to anyone for help or comment without them knowing what the real document says.
Thanks to the lovely Lillie for prompting this idea.
Obviously, make a COPY of the original document before running this macro.
Suggestion: add the complete letter and digit string at the top of the document, as in the above example. This will reassure you that all characters have been replaced.
The VBA Code
This isn’t very elegant code. It was written, in part, so it could be easily understood. Like most modern developers, we’ve copied some functions from smart developers online.
The code takes a little while to run and Word might seem to ‘lock up’, but it’s really just doing a lot of replacements.
We working on an alternative approach where each word is replaced with a filler word of the same length.
If you can suggest more elegant code/solutions we’d love to hear about them via our Feedback page.
Sub ReplaceWithFiller()
' Office-Watch.com
' To replace real text with filler characters
' Allows formatting problems with Word doc to be examined
' with disclosing private information
Application.ScreenUpdating = False ' stop screen display to speed up
Dim LookFor, LookChar, FillerChar As String
LookFor = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
Dim i As Long
For i = 1 To Len(LookFor)
LookChar = Mid$(LookFor, i, 1) ' look for next character
If IsNumeric(LookChar) Then
' character is a digit
FillerChar = RandomDigit()
Else ' character is a letter - UPPER or lower case.
FillerChar = RandomChar() ' generate filler character to replace it
' retain case of original character
If AllCaps(LookChar) Then
' force to upper case
FillerChar = UCase(FillerChar)
Else
' force to lower case (not really necessary)
FillerChar = LCase(FillerChar)
End If ' AllCaps
End If ' isNumeric()
Selection.Find.ClearFormatting
Selection.Find.Replacement.ClearFormatting
With Selection.Find
.Text = LookChar
.Replacement.Text = FillerChar
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = True
.MatchWholeWord = False
.MatchKashida = False
.MatchDiacritics = False
.MatchAlefHamza = False
.MatchControl = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
End With
Selection.Find.Execute Replace:=wdReplaceAll
Next
' optional. Clears the Undo buffer to ensure the original text is not recoverable.
' ActiveDocument.UndoClear
Application.ScreenUpdating = True ' enable screen display
End Sub
Function AllCaps(stringToCheck) As Boolean
' From http://www.freevbcode.com/ShowCode.asp?ID=5198
AllCaps = StrComp(stringToCheck, UCase(stringToCheck), _
vbBinaryCompare) = 0
End Function
Function RandomChar() As String
' from https://stackoverflow.com/questions/292254/vb6-how-do-i-make-a-random-string-of-0-9-and-a-z-of-x-characters
' returns a single random character
' Note: does NOT test that the new character is different from the original
Randomize
Dim rgch As String
rgch = "abcdefghijklmnopqrstuvwxyz"
RandomChar = Mid$(rgch, Int(Rnd() * Len(rgch) + 1), 1)
End Function
Function RandomDigit() As String
' from https://stackoverflow.com/questions/292254/vb6-how-do-i-make-a-random-string-of-0-9-and-a-z-of-x-characters
' returns a single random digit
' Note: does NOT test that the new character is different from the original
Randomize
Dim rgch As String
rgch = "0123456789"
RandomDigit = Mid$(rgch, Int(Rnd() * Len(rgch) + 1), 1)
End Function