0

I have created a taskpane addin for word that runs a search and displays information about the results as a list to the user. When the user clicks on an item in the list I want to select the range in word to show the user the location of the item. The addin will then allow the user to perform additional tasks on the range, for example change the font colour, similar to the use in this previous question: (How can a range be used across different Word.run contexts?).

However, although it works for basic searches using one search term (outlined below), it does not work for a context.document.body.match function (to perform regex searches) or where multiple searches are run.

Working example 

let results = [];

async function testSearch() {
    if (results.length > 0) {
    await Word.run(results, async (context) => {
      results.forEach((range) => range.untrack());
      results = [];
      await context.sync();
    });
  }
  cleartable();
  await Word.run(async (context) => {
    var i = 0
    results = context.document.body.search('<[A-Z][A-Za-z]*>[ ]{1,}<[A-Z][A-Za-z]*>[A-Za-z ]*>', {matchWildcards: true});
    results.load('text');
    await context.sync(); 
     
    for (const result of results.items) {
        i++;
        createtable(i, result.text)    
    }
  results.track();
  });
}

However, the following function, for example, does not appear to track the specified ranges:

async function batchsearch() {
  const words = Object.keys(americanbody).join("|");
  // Clear previous search results
  if (results.length > 0) {
    await Word.run(results, async (context) => {
      results.forEach((range) => range.untrack());
      results = [];
      await context.sync();
    });
  }
  cleartable();
  await Word.run(async (context) => {
    var i = 0;
    const body = context.document.body;
    const paragraphs = body.paragraphs;
    paragraphs.load("text");
    await context.sync();

    const regex = new RegExp(`\\b(${words})\\b`, "ig");
    const batchSize = 100;
    let start = 0;
    while (start < paragraphs.items.length) {
      const end = Math.min(start + batchSize, paragraphs.items.length);
      const chunk = paragraphs.items.slice(start, end);
      for (const para of chunk) {
        const matches = para.text.matchAll(regex);
        for (const match of matches) {
          const typo = match[0];
          const correction = americanbody[typo];
          i++;
          createtable(i, typo, correction);
        }
      }
      start += batchSize;
    }
  });
}

My question is whether there is a way to: a) track ranges of search results when using the match function; and b) continue to track results with multiple searches.

There seems to be very little attention given to this in the documentation. I have reviewed the follow book, which provided guidance but did not fully get me to where I want to go: (https://leanpub.com/buildingofficeaddins/).

Any help would be greatly appreciated.

  • Can you say more about "it does not work for a context.document.body.match"? What exactly goes wrong? What do you expect to see, and what do you actually see? Also, can you reproduce this with the [Script Lab](https://learn.microsoft.com/office/dev/add-ins/overview/explore-with-script-lab) tool and export a gist? That would make it easier for others to try and reproduce. – Rick Kirkham Apr 13 '23 at 18:15
  • Thank you, Kirk. My goal is to run multiple searches (different search terms) in the word document, track the range of all, populate a table of the results in the taskpane, and then allow the user to select a result in the taskpane table to select the result in the word body. By way of an example, when pressing the dictionary button, I want to check if any of the U.S. spellings in an array are in the document, and find each as above, and populate a table. – Sebastian King Apr 13 '23 at 18:43
  • Here is an amended gist which is a bit easier to follow: https://gist.github.com/SebastianFKing/1483ba3097d3d8197e4981f9b84ee020 – Sebastian King Apr 13 '23 at 19:28
  • OK. Now what kind of content should I have in my Word document to test the gist? Can it just be a bunch of Ipsum Lorem paragraphs? – Rick Kirkham Apr 14 '23 at 19:23

1 Answers1

1

I have some concerns about the Working example.

The variable results is initiated as an array, but in the testSearch function, it is assigned as an RangeCollection object. In this case, results.length would be undefined since results is not an array anymore.

Tyler2P
  • 2,324
  • 26
  • 22
  • 31
YijunMS
  • 11
  • 2