Мы занимаемся разработкой с использованием Excel JavaScript API уже несколько месяцев. Мы сталкивались с проблемами, связанными с контекстом, которые были решены по неизвестным причинам. Мы не смогли воспроизвести эти проблемы и задались вопросом, как они были решены. В последнее время подобные проблемы снова стали появляться. Ошибку мы постоянно получаем:
свойство "адрес" недоступно. Перед чтением значения свойства вызовите метод load для содержащего объекта и вызовите context.sync () для связанного контекста запроса.
Мы подумали, что, поскольку у нас есть несколько функций, определенных для модульного построения кода в проекте, возможно, контекст между этими функциями где-то отличается, что осталось незамеченным. Таким образом, мы пришли к единому контекстному решению, реализованному с помощью шаблона модуля JavaScript.
var ContextManager = (function () {
var xlContext;//single context for entire project/application.
function loadContext() {
xlContext = new Excel.RequestContext();
}
function sync(object) {
return (object === undefined) ? xlContext.sync() : xlContext.sync(object);
}
function getWorksheetByName(name) {
return xlContext.workbook.worksheets.getItem(name.toString());
}
//public
return {
loadContext: loadContext,
sync: sync,
getWorksheetByName: getWorksheetByName
};
})();
ПРИМЕЧАНИЕ: приведенный выше код сокращен. Добавлены и другие методы, обеспечивающие использование единого контекста во всем приложении. Однако при реализации единого контекста на этот раз мы смогли воспроизвести проблему.
Office.initialize = function (reason) {
$(document).ready(function () {
ContextManager.loadContext();
function loadRangeAddress(rng, index) {
rng.load("address");
ContextManager.sync().then(function () {
console.log("Address: " + rng.address);
}).catch(function (e) {
console.log("Failed address for index: " + index);
});
}
for (var i = 1; i <= 1000; i++) {
var sheet = ContextManager.getWorksheetByName("Sheet1");
loadRangeAddress(sheet.getRange("A" + i), i);//I expect to see a1 to a1000 addresses in console. Order doesn't matter.
}
});
}
В приведенном выше случае только «A1» выводится на консоль как адрес диапазона. Я не вижу печатаемых других адресов (от A2 до A1000). Выполняется только блок catch. Кто-нибудь может объяснить, почему это происходит? Хотя я написал выше цикл for, это не мой вариант использования. В реальном случае возникают такие ситуации, когда один объект диапазона в функции a должен загрузить адрес диапазона. Между тем, другая функция b также хочет загрузить адрес диапазона. И функция a, и функция b работают асинхронно с отдельными задачами, например, одна создает объект таблицы (таблица требует адреса), а другие вставляют данные в лист (есть инструкция отладки, чтобы увидеть, куда были вставлены данные).
Это то, что наша команда не смогла выяснить или найти решение.