Повторное использование объекта диапазона в Excel.run для приложений для офиса

Я новичок в приложениях для офиса

Я пытаюсь простой код, в котором я проверяю данные Excel. Поэтому вместо того, чтобы снова и снова вкладывать вещи в ctx.sync(), я пишу такой код:

        // **json** object used beneath is somewhat like:
        {"Field":[
            {"FieldName":"Field1", "FieldDesc":"Field 1 desc", "MappedTo":"B2", "IsMandatory":"true", "LOV":"1,2,3"}]}

       // **LOV** in above json data means:- the field data can only be among the values given.

        //********** MY PIECE OF CODE**************

        var fieldData = "";
        $.each(json, function (index, field) {
            range = ctx.workbook.worksheets.getActiveWorksheet().getRange(field.MappedTo + ":" + field.MappedTo);
            range.load('text');
            ctx.sync();
            fieldData = range.text;

            if(field.IsMandatory == true && (fieldData == "" || fieldData == null))
            {
                headerValidation = headerValidation + "Data is required for Field : " + field.FieldDesc + "\n";
            }
            else if(field.LOV != "" )
            {
                if($.inArray(fieldData, field.LOV.split(',')) == -1)
                {
                    headerValidation = headerValidation + "Data not among LOV for Field : " + field.FieldDesc + "\n";
                }
            }

            range = null;
        });

Как видно, мне нужно снова и снова читать объект диапазона. Поэтому я каждый раз использую объект диапазона с другим адресом и вызываю сначала "load()", а затем "ctx.sync()".

Если я медленно отлаживаюсь, все работает хорошо, но при запуске приложения я получаю частые ошибки время от времени: -

*

Свойство text недоступно. Прежде чем читать значение свойства, вызовите метод load для содержащего объекта и вызовите "context.sync()" в связанном контексте запроса.

*

Пожалуйста, наведите меня, как я могу справиться с этим? Кроме того, мой подход правильный?

1 ответ

Решение

С точки зрения того, что не так, ошибка находится рядом с вашим оператором ctx.sync(). Вам нужно это быть

ctx.sync()
    .then(function() {
        fieldData = range.text;
        ...
    });

И я не забуду также.catch(function(error) { ... }) в конце.

Что касается повторного использования переменной или нет, это действительно не имеет значения. Делая "range = ctx.workbook....", вы фактически создаете глобальную переменную диапазона, что считается плохой практикой. Лучше сделать "var range = ctx.workbook....". И вам не нужно беспокоиться о том, чтобы установить его в ноль в конце.

Следует отметить, что, поскольку вы делаете это в цикле for-each, обратите внимание, что число одновременных.sync (), которые могут происходить, ограничено (я полагаю, что-то около 50-60). Поэтому вам может потребоваться настроить алгоритм, если у вас будет большое количество полей.

Наконец, вы можете сделать этот код намного более эффективным, одновременно отключив все ваши объекты диапазона, загрузив их все сразу, а затем выполнив один ".sync".

var ranges = [];
$.each(json, function (index, field) {
    var range = ctx.workbook.worksheets.getActiveWorksheet().getRange(field.MappedTo + ":" + field.MappedTo);
    range.load('text');
    ranges.push(range);
});
ctx.sync()
    .then(function() {
        // iterate through the read ranges and do something
    })

Надеюсь это поможет,

~ Михаил Златковский, разработчик команды Office Extensibility, MSFT

Другие вопросы по тегам