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











up vote
0
down vote

favorite












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.










share|improve this question




























    up vote
    0
    down vote

    favorite












    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.










    share|improve this question


























      up vote
      0
      down vote

      favorite









      up vote
      0
      down vote

      favorite











      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.










      share|improve this question















      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.







      word-vba






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited 5 hours ago

























      asked 6 hours ago









      Chris Barry

      87767




      87767
























          1 Answer
          1






          active

          oldest

          votes

















          up vote
          0
          down vote













          A problem you'll encounter when dong 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





          share|improve this answer





















          • Thanks, your code seems to work but I don't understand what is happening. I had assumed that Find.Execute would search the Range it belonged to until its criteria were matched. My own test code proved this wrong, as the region found lay outside the range being searched, but given this, what does define the range that Find.Execute will search? I thought I had demonstrated that the upper bound of the search range was defined by Range.End, but in your code, at the second Execute .Start and .End are equal and less than the values placed in them by Execute, which succeeds.
            – Chris Barry
            22 mins ago











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














           

          draft saved


          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53370529%2fword-vba-range-find-always-starts-at-zero-regardless-of-the-vale-in-range-start%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          0
          down vote













          A problem you'll encounter when dong 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





          share|improve this answer





















          • Thanks, your code seems to work but I don't understand what is happening. I had assumed that Find.Execute would search the Range it belonged to until its criteria were matched. My own test code proved this wrong, as the region found lay outside the range being searched, but given this, what does define the range that Find.Execute will search? I thought I had demonstrated that the upper bound of the search range was defined by Range.End, but in your code, at the second Execute .Start and .End are equal and less than the values placed in them by Execute, which succeeds.
            – Chris Barry
            22 mins ago















          up vote
          0
          down vote













          A problem you'll encounter when dong 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





          share|improve this answer





















          • Thanks, your code seems to work but I don't understand what is happening. I had assumed that Find.Execute would search the Range it belonged to until its criteria were matched. My own test code proved this wrong, as the region found lay outside the range being searched, but given this, what does define the range that Find.Execute will search? I thought I had demonstrated that the upper bound of the search range was defined by Range.End, but in your code, at the second Execute .Start and .End are equal and less than the values placed in them by Execute, which succeeds.
            – Chris Barry
            22 mins ago













          up vote
          0
          down vote










          up vote
          0
          down vote









          A problem you'll encounter when dong 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





          share|improve this answer












          A problem you'll encounter when dong 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






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered 5 hours ago









          macropod

          1,846228




          1,846228












          • Thanks, your code seems to work but I don't understand what is happening. I had assumed that Find.Execute would search the Range it belonged to until its criteria were matched. My own test code proved this wrong, as the region found lay outside the range being searched, but given this, what does define the range that Find.Execute will search? I thought I had demonstrated that the upper bound of the search range was defined by Range.End, but in your code, at the second Execute .Start and .End are equal and less than the values placed in them by Execute, which succeeds.
            – Chris Barry
            22 mins ago


















          • Thanks, your code seems to work but I don't understand what is happening. I had assumed that Find.Execute would search the Range it belonged to until its criteria were matched. My own test code proved this wrong, as the region found lay outside the range being searched, but given this, what does define the range that Find.Execute will search? I thought I had demonstrated that the upper bound of the search range was defined by Range.End, but in your code, at the second Execute .Start and .End are equal and less than the values placed in them by Execute, which succeeds.
            – Chris Barry
            22 mins ago
















          Thanks, your code seems to work but I don't understand what is happening. I had assumed that Find.Execute would search the Range it belonged to until its criteria were matched. My own test code proved this wrong, as the region found lay outside the range being searched, but given this, what does define the range that Find.Execute will search? I thought I had demonstrated that the upper bound of the search range was defined by Range.End, but in your code, at the second Execute .Start and .End are equal and less than the values placed in them by Execute, which succeeds.
          – Chris Barry
          22 mins ago




          Thanks, your code seems to work but I don't understand what is happening. I had assumed that Find.Execute would search the Range it belonged to until its criteria were matched. My own test code proved this wrong, as the region found lay outside the range being searched, but given this, what does define the range that Find.Execute will search? I thought I had demonstrated that the upper bound of the search range was defined by Range.End, but in your code, at the second Execute .Start and .End are equal and less than the values placed in them by Execute, which succeeds.
          – Chris Barry
          22 mins ago


















           

          draft saved


          draft discarded



















































           


          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53370529%2fword-vba-range-find-always-starts-at-zero-regardless-of-the-vale-in-range-start%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Volksrepublik China

          How to test boost logger output in unit testing?

          Write to the output between two pipeline