【问题标题】:Office JS: Problems when Addin is executed in multiple Excel instancesOffice JS:在多个 Excel 实例中执行 Addin 时出现问题
【发布时间】:2020-04-27 17:42:53
【问题描述】:

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

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

首先注册UDF,而不是在使用第二部分之前,创建2个工作簿,每个工作簿有100个包含以下功能的工作表(取决于Snippent名称,在我的例子中是“Blank sn-p(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);
  }
}

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

【问题讨论】:

    标签: excel office-js user-defined-functions custom-functions-excel


    【解决方案1】:

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

    【讨论】:

    • 感谢您的回复,我首先认为这是一个 CF 问题,因为我无法使用标准内置 UDF 重现它。你能给我链接来跟踪你提到的错误吗?
    • 很抱歉,无法在 Microsoft corpnet 之外访问错误数据库。我在这里分享数字更容易通过内部错误状态跟踪此问题。
    • 能否分享一下你的场景,我想学习2个工作簿的用例
    • 我不确定客户是否会同时使用 2 个工作簿,但我怀疑这可能会发生。如果客户创建具有 100 个 UDF 函数的工作簿来请求报告,然后更新此工作簿,他可能不想等到更新完成。由于更新可能需要一些时间(数据将从服务器请求,写入 Excel 并随后设置样式),他可以使用“运行时”在另一个工作簿中执行其他操作。或者他已将 UDF 函数拆分为 2 个工作簿。你永远不会知道,但我过去有客户同时在多个工作簿中工作。
    • 2 工作簿:许多桌面应用程序级插件或 UDF 库旨在与打开的多个工作簿一起使用。这是一个相当频繁遇到的用例。 Web Excel 不会发生这种情况,因为它不支持多个工作簿。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-14
    相关资源
    最近更新 更多