Search code examples
c#ms-wordvstoms-office

C# Word.Interop Find.Execute MatchWholeWord: true fails


I use Find.Excecute() to find a whole word in a document. But Find.Excecute() fails, if FindText contains '#', '-' or ''. It finds all words starting or including FindText. Also when searching in word, "search for whole word" becomes inactive if the search name contains one of the above characters. How can Find.Execute() find whole words containing '#', '-' or ''?

This code finds '#24V_ABCD' also, although MatchWholeWord is set to true

string name = @"#24V";
selection.Find.Execute(FindText: name, MatchCase: true, Wrap: WdFindWrap.wdFindContinue, MatchWholeWord: true);

Solution

  • Word counts words in a special way. #24V_1A are actually 4 words: '#' '24V' '_' '1A'. Therefore, searching for a whole word fails.

    One solution is to increase the range found by Find.Execute() until the end of the word is reached. Then the real word can be compared to the search string. Find.Execute() must be called until the end of the document is reached or the search string is found. The following snippet ignores #24V_1A, but finds #24V.

    string name = "#24V";
    selection.Find.Execute(FindText: name, MatchCase: true, Wrap: WdFindWrap.wdFindContinue, MatchWholeWord: true);
    
    // arbitrary value of 32 words in a word will be fine for me
    string[] delimiterChars = { "\r", " ", ",", ";", ".", ":", "\t", "!", "?", "\a", "\v" };
    for (int j = 0; j < 32; j++)
    {
        string foundName = "";
        selection.MoveRight(WdUnits.wdWord, 1, WdMovementType.wdExtend);
        string text = selection.Range.Text; // debug value
        string lastChar = text.Substring(text.Length - 1);
        if (delimiterChars.Contains(lastChar))
        {
            // found end of word
            foundName = text.Substring(0, text.Length - 1);
    
            if (foundName == name)
            {
                break;
            }
        }
    }