Chris Barry
Chris Barry

Reputation: 2590

Word VBA Range.Find always starts at zero, regardless of the vale in Range.start

I am trying to use Find to step through all occurrences of a particular style. This fragment illustrates the problem.

Public Sub test()
    Dim rng As Range
    Dim found As Boolean

    Set rng = ActiveDocument.Range()
    rng.Find.Style = "prod_code"
    found = rng.Find.Execute()
    rng.Start = rng.End
    rng.End = ActiveDocument.Range().End
    found = rng.Find.Execute()
End Sub

After the first Execute found is True, rng.start is 152, rng.end is 153 and rng.text is "1". Immediately before the second Execute rng.start and rng.end are 153 and 27219 and the value of rng.text reflects this. After the second Execute found is true, and start and end are once more 152 and 153.

By searching for text as well as style I have established that the second search is starting at zero, not searching to the end and then wrapping (although it should still wrap within the range).

The end value is taken as given. If I set it before the first match then Execute returns False.

I have tried creating a new Range for the second search but it behaves the same way.

I have tried this with MS Office 2007 and 2016, and with the Execute and Execute2007 methods so, presumably, this behaviour is intended but how should I search a range which does not begin at zero?

I have just realised that the first occurrence of the style I was looking for is in a cell of a table. When I run my test code on a document without tables it behaves as I expected, that is, the second search result was within the range being searched. This gives me a new line of attack but the fundamental problem remains. I want to search for a style within a specific range of a document, regardless of whether or not that range includes a table, or part of a table.

Upvotes: 1

Views: 763

Answers (1)

macropod
macropod

Reputation: 13490

A problem you'll encounter when doing a Find for formatting in tables and you're not specifying the text is that the found range might include the end-of-cell and/or end-of-row markers. In that case, simply collapsing the found range before executing the next 'find' is insufficient. Try something based on:

Sub Demo()
Application.ScreenUpdating = False
With ActiveDocument.Range
  With .Find
    .ClearFormatting
    .Replacement.ClearFormatting
    .Text = ""
    .Replacement.Text = ""
    .Forward = True
    .Format = True
    .Wrap = wdFindStop
    .Style = "prod_code"
    .Execute
  End With
  Do While .Find.Found
    If .Information(wdWithInTable) = True Then
      MsgBox .Text
      If .End = .Cells(1).Range.End - 1 Then
        .End = .Cells(1).Range.End
        .Collapse wdCollapseEnd
        If .Information(wdAtEndOfRowMarker) = True Then
          .End = .End + 1
        End If
      End If
    End If
    If .End = ActiveDocument.Range.End Then Exit Do
    .Collapse wdCollapseEnd
    .Find.Execute
  Loop
End With
Application.ScreenUpdating = True
End Sub

Upvotes: 1

Related Questions