首页 > 解决方案 > Office JS:在多个 Excel 实例中执行 Addin 时出现问题

问题描述

我在多个 Excel 实例中执行 Office 插件时遇到问题。当两者同时执行时,一个停止运行。

我做了 2 个快速 ScriptLab 示例,您可以在其中重现一些问题(我粘贴了它们)。一个包含一个 UDF 函数,只需在 ScriptLab 中注册它。另一个是产生我的一个问题的样本。

首先注册 UDF,比使用第二部分之前,创建 2 个工作簿,每个工作簿有 100 个包含以下函数的工作表(取决于 Snippent 名称,在我的情况下是“Blank snippet (1)”,如果你的名字不同的话,请在此处以及函数“findAllOrNullObject”的插件代码中调整公式名称)。

=SCRIPTLAB.BLANKSNIPPET1.ADD(1;2)

最快的方法是:使用该功能创建十张工作表并将这十张工作表复制十次到工作簿的末尾。完成此操作后,使用不同的名称再次保存工作簿。之后,打开两个工作簿并单击“运行”(在两个工作表中)。而不是在两者都在运行或打开一个应用程序时单击另一个应用程序。在控制台上,您将看到一个计数器,指示插件实际在哪个工作表上工作。您应该在两个实例中都期望“INDEX:100”,但是当您单击另一个应用程序或启动一个应用程序时,一个实例会停止并且不会达到 100。如果您不会直接遇到问题,只需再试一次,它肯定会出现。

UDF 代码:

/**
 * Adds two numbers.
 * @customfunction
 * @param first First number
 * @param second Second number
 * @returns The sum of the two numbers.
 */
/* global clearInterval, console, setInterval */

function add(first: number, second: number): number {
  return first + second;
}

插件代码:

$("#run").click(() => tryCatch(run));

async function run() {
  this.refreshWorkbook();
}

async function refreshWorkbook() {
  let sheets: Excel.WorksheetCollection;

  Excel.run(async (context) => {
    sheets = context.workbook.worksheets;
    sheets.load("items/name");
    await sheets.context.sync();
    if (sheets.items.length >= 1) {
      for (let sheetIndex = 0; sheetIndex < sheets.items.length; sheetIndex++) {
        console.log("INDEX : " + sheetIndex);
        const sheet = sheets.items[sheetIndex];
        await this.getInfo(sheet.name).then((information) => {
          // some stuff
        });
      }
    }
  });
}

async function getInfo(worksheetName: string): Promise<string> {
  return new Promise<string>((resolve, reject) => {
    Excel.run(async (context) => {
      const sheet: Excel.Worksheet = context.workbook.worksheets.getItem(worksheetName);
      sheet.load("name");
      await context.sync();
      const usedRange = sheet.getUsedRangeOrNullObject();
      if (usedRange) {
        const functionCells = sheet.findAllOrNullObject("=SCRIPTLAB.SCRIPTLAB.BLANKSNIPPET1.ADD(", {
          matchCase: false,
          completeMatch: false
        });
        functionCells.load("areaCount");
        await context.sync();
        if (functionCells) {
          resolve("A");
        } else {
          reject("X");
        }
      }
    });
  });
}

/** Default helper for invoking an action and handling errors. */
async function tryCatch(callback) {
  try {
    await callback();
  } catch (error) {
    // Note: In a production add-in, you'd want to notify the user through your add-in's UI.
    console.error(error);
  }
}

如果我删除搜索部分,它会起作用。

标签: exceloffice-jsuser-defined-functionscustom-functions-excel

解决方案


我们可以重现这个问题,它可以在没有 CF 的情况下重现。所以这是更多与 API 相关的问题。创建了一个错误 4124929 来跟踪此问题。更有可能是 findAllOrNullObject API 中的问题,我们正在对这个问题进行一些调查。


推荐阅读