Office JS:插件在多个 Excel 实例中执行时出现问题
Office JS: Problems when Addin is executed in multiple Excel instances
我在多个 Excel 实例中执行 office 插件时遇到问题。当两者同时执行时,一个停止 运行。
我做了 2 个快速 ScriptLab 示例,您可以在其中重现一些问题(我粘贴了它们)。一个包含一个 UDF 函数,只需在 ScriptLab 中注册它。另一个是产生我的一个问题的样本。
首先注册 UDF,然后再使用第二部分,创建 2 个工作簿,每个工作簿有 100 个工作sheet,其中包含以下函数(取决于 Snippent 名称,在我的例子中是 "Blank snippet (1)",如果您的名字不同,请在此处和函数 "findAllOrNullObject") 的插件代码中调整公式名称。
=SCRIPTLAB.BLANKSNIPPET1.ADD(1;2)
最快的方法是:
使用该函数创建十个 sheet 并将这十个作品 sheet 复制十次到工作簿的末尾。完成后,再次使用不同的名称保存工作簿。然后,打开两个工作簿并单击 "Run"(在两个 sheet 中)。比在 运行 或打开一个应用程序时单击另一个应用程序。在控制台上,您会看到一个计数器,指示 sheet 插件实际在哪个上工作。您应该期望在这两种情况下都出现 "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);
}
}
如果我删除搜索部分,它会起作用。
这个issue可以重现,没有CF也可以重现。所以这是更多 API 相关的问题。创建了错误 4124929 来跟踪此问题。更有可能是 findAllOrNullObject API 中的问题,我们正在对此问题进行一些调查。
我在多个 Excel 实例中执行 office 插件时遇到问题。当两者同时执行时,一个停止 运行。
我做了 2 个快速 ScriptLab 示例,您可以在其中重现一些问题(我粘贴了它们)。一个包含一个 UDF 函数,只需在 ScriptLab 中注册它。另一个是产生我的一个问题的样本。
首先注册 UDF,然后再使用第二部分,创建 2 个工作簿,每个工作簿有 100 个工作sheet,其中包含以下函数(取决于 Snippent 名称,在我的例子中是 "Blank snippet (1)",如果您的名字不同,请在此处和函数 "findAllOrNullObject") 的插件代码中调整公式名称。
=SCRIPTLAB.BLANKSNIPPET1.ADD(1;2)
最快的方法是: 使用该函数创建十个 sheet 并将这十个作品 sheet 复制十次到工作簿的末尾。完成后,再次使用不同的名称保存工作簿。然后,打开两个工作簿并单击 "Run"(在两个 sheet 中)。比在 运行 或打开一个应用程序时单击另一个应用程序。在控制台上,您会看到一个计数器,指示 sheet 插件实际在哪个上工作。您应该期望在这两种情况下都出现 "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);
}
}
如果我删除搜索部分,它会起作用。
这个issue可以重现,没有CF也可以重现。所以这是更多 API 相关的问题。创建了错误 4124929 来跟踪此问题。更有可能是 findAllOrNullObject API 中的问题,我们正在对此问题进行一些调查。