使用 OfficeExtension.TrackedObjects 类在不同的 Word.run 上下文中跟踪范围。

huangapple go评论45阅读模式
英文:

Track ranges across different Word.run contexts using OfficeExtension.TrackedObjects class

问题

我已经为Word创建了一个任务窗格插件,可以运行搜索并以列表形式向用户显示结果的信息。当用户点击列表中的项目时,我想选择Word中的范围,以向用户显示项目的位置。然后,该插件将允许用户对该范围执行其他任务,例如更改字体颜色,类似于先前提到的问题中的用法。

然而,尽管它可以对使用一个搜索词进行基本搜索的情况运行(如下所示),但对于context.document.body.match函数(执行正则表达式搜索)或运行多个搜索的情况则无法运行。

工作示例

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();
  });
}

然而,例如以下功能似乎无法跟踪指定的范围:

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;
    }
  });
}

我的问题是是否有一种方法来:a)在使用匹配功能时跟踪搜索结果的范围;b)继续跟踪多个搜索的结果。

在文档中似乎对此付出了很少的关注。我已经查阅了下面的书籍,其中提供了指导,但没有完全达到我想要的目标:(https://leanpub.com/buildingofficeaddins/)。

非常感谢您的帮助。

英文:

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: (https://stackoverflow.com/questions/37275482/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.

答案1

得分: 1

以下是要翻译的内容:

我对示例中的一些问题有疑虑。

变量results被初始化为一个数组,但在testSearch函数中,它被赋值为一个RangeCollection对象。在这种情况下,results.length将未定义,因为results不再是一个数组。

英文:

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.

huangapple
  • 本文由 发表于 2023年4月13日 16:04:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/76003058.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定