Search code examples
c#ms-wordvstowildcardoffice-interop

How do I use the replace feature in a VSTO C# add-in with Wildcards?


I'm using the Microsoft.Interop library in a C# VSTO Add in.
I am trying to find and replace with wildcards, but the problem I'm having is that I'd like to use the backslash syntax in the replace with functionality to swap groups in the () in the find in my code like the image below, but I can't because it just treats the syntax as a string. enter image description here

The above search and replace in word will take a date in the format of 12/17/85 and change it 85/12/17

When I run the add-in it will change 12/17/85 to \3/\1/\2

Here is the method/function

public void FindAndReplaceWildcardPlayGround(string wildCardText, string replacementText, string commentMessage)
        {
            Microsoft.Office.Interop.Word.Range wordRange = null;
            Word.Document document = this.Application.ActiveDocument;
            wordRange = document.Content;            
            wordRange.Find.ClearFormatting();
            wordRange.Find.ClearAllFuzzyOptions();
            wordRange.Find.Replacement.ClearFormatting();
            wordRange.Find.IgnoreSpace = true;
            wordRange.Find.MatchCase = false;
            wordRange.Find.MatchWildcards = true;
            wordRange.Find.Text = wildCardText;
            wordRange.Find.Execute();
            while (wordRange.Find.Found)
            {
                object commentText = commentMessage;                
                Word.Range rng = this.Application.ActiveDocument.Range(wordRange.Start, wordRange.End);
                rng.Text = replacementText;
                document.Comments.Add(
                rng, ref commentText);
                wordRange.Find.ClearFormatting();
                
                // Next Find
                wordRange.Find.Execute(FindText: wildCardText, MatchCase: false, MatchWildcards: true);
            }
        }

Here is the method/function call

Globals.ThisAddIn.FindAndReplaceWildcardPlayGround("([0-9]{1,2})/([0-9]{1,2})/([0-9]{1,2})", "\\3/\\1/\\2", "Replaced with U.K. Date Format");

I hope my intentions are clear, any help is appreciated. Thanks.


Solution

  • You have to set the arguments MatchWildcards, Replace in the Execute method and .Find.Replacement.Text = replacementText and don't forget to reset the range wordRange itself :

    public void FindAndReplaceWildcardPlayGround(string wildCardText, string replacementText, string commentMessage)
            {
                //do this, it only takes one step when undo
                Microsoft.Office.Interop.Word.UndoRecord ur = this.Application.UndoRecord;
                ur.StartCustomRecord("FindAndReplaceWildcardPlayGround");
    
                Microsoft.Office.Interop.Word.Range wordRange = null;
                Word.Document document = this.Application.ActiveDocument;
                wordRange = document.Content;
                wordRange.Find.ClearFormatting();
                wordRange.Find.ClearAllFuzzyOptions();
                wordRange.Find.Replacement.ClearFormatting();
                wordRange.Find.IgnoreSpace = true;
                wordRange.Find.MatchCase = false;
                //wordRange.Find.MatchWildcards = true;
                wordRange.Find.Text = wildCardText;
    
                wordRange.Find.Replacement.Text = replacementText;//that's the right way to write
                wordRange.Find.Forward = true;
                wordRange.Find.Wrap = WdFindWrap.wdFindStop;
    
                //don't forget the Replace argument
                wordRange.Find.Execute(MatchWildcards:true,Replace:WdReplace.wdReplaceOne);//Just set the argument MatchWildcards here!! like you wrote in this line : wordRange.Find.Execute(FindText: wildCardText, MatchCase: false, MatchWildcards: true);
                while (wordRange.Find.Found)
                {
                    object commentText = commentMessage;
                    Word.Range rng = this.Application.ActiveDocument.Range(wordRange.Start, wordRange.End);
                    //rng.Text = replacementText;//This is wrong!! refer to above
                    document.Comments.Add(rng, ref commentText);
                    wordRange.Find.ClearFormatting();
    
                    // Next Find
                    //don't forget to reset the range wordRange
                    wordRange.SetRange(wordRange.End,wordRange.Document.Content.End);
    
                    //wordRange.Find.Execute(FindText: wildCardText, MatchCase: false, MatchWildcards: true);
                    wordRange.Find.Execute(MatchWildcards: true, Replace: WdReplace.wdReplaceOne);
                }
                
                ur.EndCustomRecord();
            }