У меня проблемы с выполнением надстройки Office в нескольких экземплярах Excel. Один из них останавливается, когда оба выполняются одновременно.
Я сделал 2 быстрых примера ScriptLab, где вы можете воспроизвести некоторые проблемы (я их вставил). Один содержит UDF-функцию, просто зарегистрируйте ее в ScriptLab. Другой пример - это одна из моих проблем.
Сначала зарегистрируйте UDF, затем, перед использованием второй части, создайте 2 рабочие книги, каждая из которых имеет 100 листов, которые содержат следующую функцию (в зависимости от имени фрагмента, в моем случае «Пустой фрагмент (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);
}
}
Если я удаляю часть поиска это работает.