Jeremy Jonas
Jeremy Jonas

Reputation: 3

How to add exceptions list to a string search?

I'm trying to create a macro that can flag up instances of the prefix 'pre' being used. I can create one that highlights all instances of 'pre' appearing but this then flags words like "present", "pretend" etc.

My plan to go about this was to create an array with words that I wouldn't want to be flagged (like "present") and then use an AND operation so the text equals "pre" and is NOT equal to the words I don't want flagged. My code is below, when running there is a syntax error on the .Text <> Exceptions line. Is there a better way to go about this? Thanks!

Sub NeedPrefix()
    Dim range As range
    Dim i As Long
    Dim TargetList
    Dim Exception

    TargetList = Array(" pre")
    Exceptions = Array("prepare", "preparation", "present", "presentation", "presented", "prepared", "pretense", "pretend")

    For i = 0 To UBound(TargetList)
        Set range = ActiveDocument.range
        With range.Find
            .Text = TargetList(i)
            .Text <> Exceptions
            .Format = False
            .MatchCase = False
            .MatchWholeWord = False
            .MatchWildcards = False
            .MatchSoundsLike = False
            .MatchAllWordForms = False

            Do While .Execute(Forward:=True) = True
                ActiveDocument.Comments.Add range, "Is the use of a prefix appropriate?"
            Loop
        End With
    Next
End Sub

Upvotes: 0

Views: 70

Answers (1)

Cindy Meister
Cindy Meister

Reputation: 25693

Here's one possibility to compare a list of terms with a found Range.

Looping an array for each "hit" would be possible, although time-consuming. Instead, it's possible to compare the found Range with the list using Instr. This returns 0 if the found Range isn't present in the string.

In order for this to work, the found Range needs to be extended to encompass the entire word, so Range's end-point is extended until a space is found.

If you don't need to do anything if a term in the list is found you can, of course, leave out the Else part of the code snippet.

range.Collapse wdCollapseEnd puts the starting point for the next Find loop after the found term - otherwise the loop would repeat endlessly on the same " pre".

I've changed the variable name from range to rng - it's always a bad idea in VBA to use a reserved word (the name of an object, method or property belonging to Word or VBA) as a variable name. Notice, also, the inclusion of .Wrap = wdFindStop - this is important as otherwise the code could continue again from the start of the document.

Sub NeedPrefix()
    Dim rng As Range
    Dim i As Long
    Dim TargetList
    Dim Exceptions As String
    Dim theException As String

    TargetList = Array(" pre")
    Exceptions = "prepare preparation present presentation presented prepared pretense pretend"

    For i = 0 To UBound(TargetList)
        Set rng = ActiveDocument.Content
        With rng.Find
            .Text = TargetList(i)
            .Format = False
            .Wrap = wdFindStop
            .MatchCase = False
            .MatchWholeWord = False
            .MatchWildcards = False
            .MatchSoundsLike = False
            .MatchAllWordForms = False

            Do While .Execute(Forward:=True) = True
                Debug.Print "Characters moved: " & rng.MoveEndUntil(" " & Chr(13))
                If InStr(Exceptions, rng.Text) = 0 Then
                    ActiveDocument.Comments.Add rng, "Is the use of a prefix appropriate?"
                Else
                    theException = Mid(Exceptions, InStr(Exceptions, rng.Text))
                    theException = Mid(theException, 2)
                    theException = Left(theException, InStr(theException, " ") - 1)
                    Debug.Print "An exception was found: " & theException
                End If
                rng.Collapse wdCollapseEnd
            Loop
        End With
    Next
End Sub

Upvotes: 1

Related Questions