Share via

Selection.Find.Found is True whereas a manual search says "No results found"

Anonymous
2018-04-09T08:57:33+00:00

I am trying to understand why VBA code that uses the construct depicted at https://stackoverflow.com/questions/13465709/repeating-microsoft-word-vba-until-no-search-results-found results in an endless loop.

I have recorded a search for "any text with language = Dutch", which results in the following macro:

If I perform the search manually, I get "No results found":

but if I run the macro, Selection.Find.Found is True:

How comes?

How can I fix the code so that Selection.Find.Found is False when there are no (more) hits?

Moved from: Office / Word / Windows 10 / Office 2016

Microsoft 365 and Office | Word | For home | Windows

Locked Question. This question was migrated from the Microsoft Support Community. You can vote on whether it's helpful, but you can't add comments or replies or follow the question.

0 comments No comments

12 answers

Sort by: Most helpful
  1. Jay Freedman 207.6K Reputation points Volunteer Moderator
    2018-04-12T20:56:17+00:00

    The very reason I wrote these macros in the first place is that the documents typically have more than one language used, as well as some areas marked as "do no check" (e.g. code). Forcing the entire document to be tagged as EnglishUS or Dutch or French does not fit the bill!

    In that case, there are two possible solutions.

    One is what I suggested before: extract the document.xml file from the zip archive, replace the "bad" language IDs with the "good ones" in a text editor such as Notepad, replace the file in the archive, and rename it back to .docx. I don't know of a way to automate this, but it should take no more than 5 to 10 minutes to fix each document.

    The other solution involves learning enough about C# (or another .Net-capable language) and the Open XML programming interface to create a program that can make changes directly in the document's XML without opening the file. You'll find an overview at Manipulating Office Open XML Formats Documents Programmatically. As far as I'm aware, VBA cannot handle this job; it certainly can't access the System.IO.Packaging class mentioned in the article.

    Was this answer helpful?

    2 people found this answer helpful.
    0 comments No comments
  2. Jay Freedman 207.6K Reputation points Volunteer Moderator
    2018-04-10T21:30:03+00:00

    Inspecting the document.xml file for the document you posted, there are many instances of this sort of structure:

    <w:pPr>

    <w:ind w:left="360"/>

    <w:rPr>

    <w:rFonts w:ascii="Arial" w:hAnsi="Arial"/>

    <w:lang w:val="nl-NL"/>

    </w:rPr>

    </w:pPr>

    <w:r>

    <w:rPr>

    <w:rFonts w:ascii="Arial" w:hAnsi="Arial"/>

    <w:lang w:val="fr-FR"/>

    </w:rPr>

    <w:t>XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX</w:t>

    </w:r>

    The first group, w:pPr, specifies the paragraph's properties (http://officeopenxml.com/WPparagraphProperties.php). Within that, the w:rPr group specifies that paragraph's paragraph mark (¶) as Dutch language. However, that's immediately followed by the second group, w:r, which specifies the properties of the text in the paragraph (http://officeopenxml.com/WPtext.php), and that overrides the language formatting with French.

    When I search manually, I don't find any Dutch. My macro using a Range, on the other hand, says that the entire document is Dutch. It appears that the two methods are looking at different things. Reinforcing that view, asking in VBA for the LanguageID value of the entire document returns this:

    ?ActiveDocument.Range.LanguageID

     9999999 

    That value (also known as the constant wdUndefined) means that there are more than one LanguageID values.

    I'm not sure how this document acquired the conflicting settings, so I'm not sure how to remove the Dutch format. Possibly one way would be to open document.xml in a text editor, replace all the nl-NL instances with fr-FR, and put the edited file back into the docx's zip archive.

    Was this answer helpful?

    2 people found this answer helpful.
    0 comments No comments
  3. Jay Freedman 207.6K Reputation points Volunteer Moderator
    2018-04-09T17:05:41+00:00

    sba,

    Stefan asked me to take an independent look at your question. I recorded the same macro as you showed, and ran it in a document (based on my English (US) Normal template) that has never had any contact with anything containing Dutch proofing language. The macro repeatedly and consistently displayed "NOT found".

    As experiments, I tried (a) applying Dutch proofing language to some text in the document and then reapplying English proofing language to it, and (b) including Dutch proofing language as part of Body Text style but not applying that style to any text in the document. In both cases, both the manual search and the recorded macro continued to find nothing.

    Although I don't have an explanation for the behavior you're seeing, I agree with Stefan that using a Range instead of the Selection is a better option. Unfortunately, the macro recorder doesn't know anything about Range objects and always uses the Selection. One advantage of the Range.Find method is that it always starts with the default set of properties, whereas a Selection.Find starts with whatever properties were used in the most recent search, either manually or by a macro. That means your code doesn't have to specify every property, such as .MatchCase, except where you want to use a non-default value. 

    Sub FindDutchText()

        Dim rg As Range

        Set rg = ActiveDocument.Range

        With rg.Find

            .Format = True

            .LanguageID = wdDutch

            .NoProofing = False

            .Wrap = wdFindStop

            .Execute

            If .Found Then

                MsgBox rg.Text

            Else

                MsgBox "Not found"

            End If

        End With

    End Sub

    Was this answer helpful?

    1 person found this answer helpful.
    0 comments No comments
  4. Stefan Blom 340.3K Reputation points MVP Volunteer Moderator
    2018-04-09T14:16:07+00:00

    You may also want to change the Wrap property to wdFindStop (to prevent Word from continuing the search outside the selection).

    I'd continue testing along these lines:

    Sub testmacro()

    Dim r As Range

    Set r = Selection.Range.Duplicate

    r.Find.LanguageID = wdDutch

    With r.Find

    .Wrap = wdFindStop

    End With

    MsgBox r.Find.Execute

    MsgBox r.Find.Found

    End Sub

    Was this answer helpful?

    1 person found this answer helpful.
    0 comments No comments
  5. Stefan Blom 340.3K Reputation points MVP Volunteer Moderator
    2018-04-09T14:00:10+00:00

    Executing a Find on the Selection object will result in the selection being changed. I suspect that is part of the problem here. Have you tried performing the search on a Range object instead?

    Was this answer helpful?

    1 person found this answer helpful.
    0 comments No comments