Reputation: 3
I have the following function, but I do not want it to replace anything within quotation marks when I call it:
Function AutoReplace(source As String, typeText As String)
Selection.Find.ClearFormatting
Selection.Find.Replacement.ClearFormatting
With Selection.Find
.Text = Trim(source)
.Replacement.Text = typeText
.Forward = True
.Wrap = wdFindContinue
End With
Selection.Find.Execute Replace:=wdReplaceAll
End Function
Upvotes: 0
Views: 135
Reputation: 25663
Wildcard search can't handle this, unfortunately, so a code solution is required.
The difficulty with this is determining when the search term is within quotes. And of course the search term could occur multiple times within a set of quotes. I tried to think of all permutations, including whether the term occurs at the beginning / end of the document, but I can't guarantee I caught them all...
The trick to the approach I propose is to compare the location in the text of the found term, the previous opening quotes and, if those were found, whether the previous closing quotes follow or precede the opening quotes. If no opening quotes are found, the term is obviously not in quotes. If the closing quotes follow the opening quotes, the term is not in quotes. Otherwise, it's assumed the quotes are in pairs and the term is indeed within quotes.
The coding could be more elegant (fewer nested levels), but I'm not being paid for it, so I leave that up to anyone who wants to use it...
Sub FindTermNotInQuotes()
Dim sTerm As String, sReplacement As String
Dim sOpenQuote As String, sCloseQuote As String
Dim rngSearch As word.Range, rngOpenQuote As word.Range
Dim rngTerm As word.Range, rngCloseQuote As word.Range
Dim bFound As Boolean, rngFound As word.Range
sTerm = "can't"
sReplacement = "cannot"
sOpenQuote = Chr(147)
sCloseQuote = Chr(148)
Set rngSearch = ActiveDocument.content
Set rngFound = ActiveDocument.Range(2)
Do
With rngSearch.Find
'Keep previous location so that we can check
'If searching the open quote is a previous one
rngFound.Collapse wdCollapseStart
.ClearFormatting
.Text = sTerm
.Forward = True
bFound = .Execute
If bFound Then
Set rngOpenQuote = rngSearch.Duplicate
rngOpenQuote.Start = ActiveDocument.content.Start
With rngOpenQuote.Find
.Text = sOpenQuote
.Forward = False
If .Execute Then
If rngOpenQuote.Start < rngFound.Start Then
'This quote is in front of the previous "hit"
'So we need to check if there's a closing quote
Set rngCloseQuote = rngSearch.Duplicate
rngCloseQuote.Start = ActiveDocument.content.Start
With rngCloseQuote.Find
.Text = sCloseQuote
.Forward = False
If .Execute Then
'It's not in a quote
If rngCloseQuote.Start > rngOpenQuote.Start Then
'If close quote is before open quote
'then the term is still within quotes
rngSearch.Text = sReplacement
End If
End If
End With
End If
End If
End With
End If
Set rngFound = rngSearch.Duplicate
rngSearch.Collapse wdCollapseEnd
rngSearch.End = ActiveDocument.content.End
End With
Loop While bFound
End Sub
Upvotes: 1