-1

I'm trying to be able to select all instances of a highlight color running a macro in Word. `

I've gotten so far as to select the first instance of a highlight color, but the code doesn't loop through the entire document to select every instance of that highlight color. The VB I'm currently using is:

Sub FindNextYellow()
    With Selection.Find
        .ClearFormatting
        .Replacement.ClearFormatting
        .Text = ""
        .MatchWildcards = False
        .Forward = True
        .Wrap = wdFindContinue
        .Highlight = True
        Do
            .Execute
        Loop Until Selection.Range.HighlightColorIndex = wdYellow _
          Or Not .Found
        Selection.Range.Select
    End With
End Sub
Eugene Astafiev
  • 47,483
  • 3
  • 24
  • 45
  • Your loop stops when it finds the first yellow highlight, instead of continuing to find additional ones. So, you'll need two nested loops. The challenge will be to figure how to not search endlessly, so perhaps better to not wrap and start from the top of the doc. – Paul Dempsey May 06 '23 at 17:35
  • 1
    It is not possible to select non-contiguous ranges using VBA, so you will not be able “to select every instance of that highlight color“. You can loop through all highlights and do something if the highlight color meets your requirement, but if that is what you want to do you will need to edit your question. – Timothy Rylatt May 06 '23 at 18:02

1 Answers1

0

Concept

As Timothy Rylatt notes, Selection objects in VBA are unique and of reference type, which means that setting a new Selection object changes the previous Selection to.

As in my code below. if it was written as "cln.Add Selection", then the "cln.Add Selection" obtained in the next loop will affect the previous element added to the Collection. That is, two elements, although two, but in fact, and the object is actually one ONLY. So it is not possible to co-exist two Selection objects in a Word document (i.e., they are not selected consecutively, or in the case of multiple selections). Therefore, if you want to make consistent processing of the collected Range objects, you can use the following way of thinking instead, although you can not achieve the result of selecting objects in different document locations, but still can deal with different parts of the document at the same time:

Rem Find All Yellow and Chage them to Green
Sub FindAllYellowChage2Green()
    Dim cln As New VBA.Collection
    Selection.HomeKey wdStory
    With Selection.Find
        .ClearFormatting
        .Replacement.ClearFormatting
        .Text = ""
        .MatchWildcards = False
        .Forward = True
        .Wrap = wdFindStop ' wdFindContinue
        .Highlight = True
        .Execute
        Do Until Not .Found
            If Selection.Range.HighlightColorIndex = wdYellow Then
                Rem Collect Selection.Range objects
                cln.Add Selection.Range
            End If
            .Execute
        Loop
        
        Rem Process the collected Range objects
        Dim e
        For Each e In cln
            e.Select
            e.HighlightColorIndex = wdBrightGreen 'wdGreen
            'e.Range.HighlightColorIndex = wdBrightGreen 'wdGreen
        Next e
    End With
End Sub

Oscar Sun
  • 1,427
  • 2
  • 8
  • 13