Office.js:如何批量从派生自集合的项目(例如,NamedItemCollection 中所有范围的 'address' 属性)获取 属性

Office.js: How to get a property from an item derived from a collection (e.g., 'address' property of all Ranges in a NamedItemCollection) in a batch

我有一个包含 2000 个命名范围的工作簿。我想获取范围属性,例如地址、columnCount、rowCount,也许还有单元格值对象。我可以通过 2000 次服务器调用获得这些。这在 Excel 中没问题,但在 Excel 在线(2000 次服务器往返)中不行。
我想通过几个批处理操作获得像 'address' 这样的属性?
我已经尝试了如下所示的各种组合(不起作用),但无法弄清楚如何。

    Excel.run(function (ctx) {
        var nameditems = ctx.workbook.names;
        nameditems.load('items');
        return ctx.sync().then(function () {
            var nameditemsProperties = nameditems.load('address, rowCount');
            return ctx.sync().then(function () {
                for (var i = 0; i < nameditemsProperties.items.length; i++) {
                    app.showNotification('address: ' + nameditemsProperties.getItem[i].address);
                }
            });
        })
    }).catch(function (error) {
        handleErrors(error);
    });

我可以(我怎样才能)通过几个批处理操作在数组中获得类似 'address' 的属性?
我正在使用 Excel API 1.3.

您很接近...但是您需要对 Range 对象进行加载。

您仍然可以只同步 2 次。第一个获取所有命名项,第二个加载每个命名项的地址。

Excel.run(function (ctx) {
    var nameditems = ctx.workbook.names.load('name');
    var namesToRanges = {};
    return ctx.sync()
        .then(function () {
            nameditems.items.forEach(function (item) {
                namesToRanges[item.name] = item.getRange().load("address");
            })
        })
        .then(ctx.sync)
        .then(function () {
            nameditems.items.forEach(function (item) {
                console.log(item.name, namesToRanges[item.name].address);
            })
        })
})
.catch(function (error) {
    OfficeHelpers.Utilities.log(error);
});

无论如何,如果您使用 TypeScript,您将获得更好的 IntelliSense 和更易于阅读的代码:

async function run() {
    try {
        await Excel.run(async (ctx) => {
            const nameditems = ctx.workbook.names.load('name');
            const namesToRanges: { [name: string]: Excel.Range } = {};
            await ctx.sync()
            nameditems.items.forEach(function (item) {
                namesToRanges[item.name] = item.getRange().load("address");
            })
            await ctx.sync();
            nameditems.items.forEach(function (item) {
                console.log(item.name, namesToRanges[item.name].address);
            })
        });
    } catch (error) {
        OfficeHelpers.Utilities.log(error);
    }
}

您可以在电子书“Building Office Add-ins using Office.js”中找到一些关于 Office.js 使用 TypeScript 的信息。全面披露:我是这本书的作者,但我可以很好地保证你会在那里找到很多有用的 material,无论是关于使用 TypeScript 还是关于一般的 Office.js 模式。

更新:更新代码以允许非范围命名项:

$("#run").click(run);

async function run() {
    try {
        await Excel.run(async (ctx) => {
            const nameditems = ctx.workbook.names.load('name, type, value');
            const namesToValues: { [name: string]: Excel.Range | any } = {};
            await ctx.sync()

            nameditems.items.forEach(item => {
                if (item.type === Excel.NamedItemType.range) {
                    namesToValues[item.name] = item.getRange().load("address");
                } else {
                    namesToValues[item.name] = item.value;
                }
            });

            await ctx.sync();

            nameditems.items.forEach(item => {
                const value = namesToValues[item.name];
                console.log(item.name,
                    (value instanceof Excel.Range) ? value.address : value);
            });
        });
    } catch (error) {
        OfficeHelpers.Utilities.log(error);
    }
}

我可以使用 1.4

获取姓名和地址,但不能获取单元格值或计数
async function run() {
    try {
        await Excel.run(async (context) => {
            var names = context.workbook.names;
            names.load();
            await context.sync();
            console.log(JSON.stringify(names.items));
        });
    }
    catch (error) {
        OfficeHelpers.Utilities.log(error);
    }
}