简体   繁体   中英

How can I search only in users selected Selection

I know how to search through entire document. I am using foreach (Word.Section paragraph in doc.Sections). But what if I want to search only in Selection. Lets assume that user will select the text and then make a search. Then we want to search only in the selection. How can I do that with Foreach sicle? Rigt now I have this code:

  app.Selection.HomeKey(Unit: WdUnits.wdStory);
        while (WordsCount >= 1)
           foreach (Word.Section paragraph in doc.Sections)
            {

                Word.Selection rngFound = FindAndReplace(app.Selection, searchTerm, ""); //searching and wrapping.


                if (rngFound != null)
                {
                    string foundNr = rngFound.Text;
                    string hyperlinkNr = foundNr.Replace((char)30, (char)45);

                    rngFound.Range.Hyperlinks.Add(rngFound.Range, hyperlink + hyperlinkNr);

                }
                WordsCount--;

I know how many words are there(what I am looking for). But how can i say to search function that we need to search only in selection. Or a range from that selection.

And this is my search function:

Word.Selection FindAndReplace(Word.Selection rngToSearch, object findText, object replaceWithText) //Find function
        {
            bool found = false;
            //options
            object matchCase = false;
            object matchWholeWord = true;
            object matchWildCards = true;
            object matchSoundsLike = false;
            object matchAllWordForms = false;
            object forward = true;
            object format = false;
            object matchKashida = false;
            object matchDiacritics = false;
            object matchAlefHamza = false;
            object matchControl = false;
            object read_only = false;
            object visible = true;
            object replace = false;
            object wrap = Word.WdFindWrap.wdFindStop; ;

            //execute find and replace
            found = rngToSearch.Find.Execute(ref findText, ref matchCase, ref matchWholeWord,
                ref matchWildCards, ref matchSoundsLike, ref matchAllWordForms, ref forward, ref wrap, ref format, ref replaceWithText, ref replace,
                ref matchKashida, ref matchDiacritics, ref matchAlefHamza, ref matchControl);
            if (!found)
            {
                rngToSearch = null;
            }

            return rngToSearch;
        }

Thanks Cindy. I am using the selection because if I will use the Range, then it will find the first search word and loop on it. And I have object forward = true; in my search function. (so that behavior is strange for me)

private void button4_Click(object sender, RibbonControlEventArgs e)
        {
            string hyperlink = "https://Test";
            string searchTerm =
                @"<([1-5])[-^~]([0-9]{2})[-^~]([0-9]{1;6})/([0-9]{1;4})>"; // testing with  2-19-1023/47 2-19-1023/49


            Word.Application app = Globals.ThisAddIn.Application;
            Word.Range rngSel = app.Selection.Range;
            Word.Range rngSearch = rngSel.Duplicate;
            Word.Range rngFound = FindAndReplace(rngSearch, searchTerm, "");
            while (rngFound != null)
            {
                string foundNr = rngFound.Text;
                string hyperlinkNr = foundNr.Replace((char)30, (char)45);
                rngFound.Hyperlinks.Add(rngFound, hyperlink + hyperlinkNr);
                rngSearch.Start = rngFound.End;
                rngSearch.End = rngSel.End;
                rngFound = FindAndReplace(rngSearch, searchTerm, "");
                File.AppendAllText(@"C:\install\CSharp\tulemus.txt", $"File name is: {rngFound.Text}" + Environment.NewLine);
            }

And I am getting endless first searchable string in my test text file. Do u know how can I overcome that?

As long as each search cycle is limited to the specific range, the search should be performed in that range, only. This is done by assigning the selection to a Range object and working with additional Range objects

In the following example, based on the code in the question, a Range object is declared and instantiated with the current selection. A second Range is then set to the Duplicate property of the first range (this creates a "shallow copy" with no link to the original).

The second range is then passed to the function FindAndReplace , which returns a third Range containing what was found. This is then processed.

Finally, the Start point of the search range is set to the end point of the found range (so that the search starts from the end of the last "hit") and the End point of the search Range is set to the end-point of the original Range and the search repeated.

Note the changes throughout, adjusting to use Range rather than Selection objects.

Word.Range rngSel = app.Selection;
Word.Range rngSearch = rngSel.Duplicate;
Word.Range rngFound = FindAndReplace(rngSearch, searchTerm, ""); 
while (rngFound != null)   
{
    string foundNr = rngFound.Text;
    string hyperlinkNr = foundNr.Replace((char)30, (char)45);
    rngFound.Hyperlinks.Add(rngFound, hyperlink + hyperlinkNr);
    rngSearch.Start = rngFound.End
    rngSearch.End = rngSel.End;
    rngFound = FindAndReplace(rngSearch, searchTerm, "");
}

Word.Range FindAndReplace(Word.Range rngToSearch, object findText, object replaceWithText) //Find function
{

I solved it. 1. The first thing, what I didn't know, that the search and replace function steps forward if we are replacing. But if we are not replacing, and just searching then it won't work using range property. 2. I amanaged to make my own method using Rgegex. I am not setting start and end points of my selection but simply counting searchable words. Maby this is not the best solution but it works for me. And Here is the code:

private void button5_Click(object sender, RibbonControlEventArgs e)
        {
            int WordsCount2 = 0;


            string hyperlink = "https://Test";
            string searchTerm =
                @"<([1-5])[-^~]([0-9]{2})[-^~]([0-9]{1;6})/([0-9]{1;4})>"; // testing with  2-19-1023/47 2-19-1023/49


            Word.Application app = Globals.ThisAddIn.Application;
            Word.Range rngSel = app.Selection.Range;
            string s = rngSel.Text;
            Word.Range rngSearch = rngSel.Duplicate;
            Regex regex2 = new Regex(@"\d*(-|\036)\d*(-|\036)\d*/\d*");
            if (regex2.Matches(s).Count != 0)
            {
                WordsCount2 = regex2.Matches(s).Count;



                while (WordsCount2 >= 1)
                {
                    Word.Range rngFound = FindAndReplace(rngSel, searchTerm, "");

                    if (rngFound != null) { 
                        string foundNr = rngFound.Text;
                    string hyperlinkNr = foundNr.Replace((char)30, (char)45);
                    rngFound.Hyperlinks.Add(rngFound, hyperlink + hyperlinkNr);


                    if (rngFound != null)
                    {
                        FindAndReplace2(rngSel, searchTerm, rngFound.Text.Replace((char)45, (char)30).Replace((char)32, (char)160));
                        //   File.AppendAllText(@"C:\install\CSharp\tulemus.txt", $"File name is: {rngFound.Text}" + Environment.NewLine)

                    }
                    WordsCount2--;
                }}

            }
        }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM