Find table intersect with selection

a 夏天 提交于 2019-11-28 14:28:15

There are several ways to check whether the current selection intersects with a table. This snippet demonstrates two of them.

Both of the examples below are written with TypeScript 2.1+'s async/await syntax. The second method is made significantly simpler through the use of "await", but both are possible with just regular promise-chaining as well.

  1. The ExcelApi 1.4+ one is vastly more efficient, but it will only run on newer builds of Excel (on subscription-based, not on 2016 MSI/RTM). It does all of its intersection-checks simultaneously.
  2. The ExcelApi 1.1 version is less efficient if you have hundreds of tables, or if you're running on Excel Online. It requires more roundtrips to the server, as it checks every table intersection one-by-one, and relies on a thrown error to inform it that there is no intersection found.

ExcelApi 1.4+ approach:

$('#check-intersection-preview').click(function() {
    // Note: this function uses a "Preview" API ("range.getIntersectionOrNull"),
    // which is only available on the Beta CDN right now, and is subject to change.
    // Do not rely on this for production. Instead, use the alternate
    // (albeit less neat) version.

    Excel.run(async function(context) {
        var selection = context.workbook.getSelectedRange();
        var tables = context.workbook.tables.load("name");
        await context.sync();

        var intersections: { [email: string]: Excel.Range } = { };
        tables.items.forEach((table) => {
            intersections[table.name] = table.getRange().
                getIntersectionOrNullObject(selection).load("address");
        });
        await context.sync();

        var found = false;
        for (var tableName in intersections) {
            var rangeOrNull = intersections[tableName];
            if (!rangeOrNull.isNullObject) {
                found = true;
                console.log(`Intersection found with table "${tableName}". ` +
                    `Intersection range: "${rangeOrNull.address}".`);
            }
        }
        if (!found) {
            console.log("Selection does not intersect any table");
        }
    }).catch(errorHandler);
});

ExcelApi 1.1 approach:

$('#check-intersection-prod').click(function() {
    Excel.run(async function(context) {
        var selection = context.workbook.getSelectedRange();
        var tables = context.workbook.tables.load("name");
        await context.sync();

        var found = false;        
        for (var i = 0; i < tables.items.length; i++) {
            try {
                var table = tables.items[i];
                var intersectionRange = table.getRange()
                    .getIntersection(selection).load("address");
                await context.sync();

                // If reached past the sync, it means that "getIntersection"
                // did not throw an error, and so the intersection must be valid.
                found = true;
                console.log(`Intersection found with table "${table.name}". ` +
                    `Intersection range: "${intersectionRange.address}".`);

            } catch (e) {
                var isExpectedError = e instanceof OfficeExtension.Error &&
                    (<OfficeExtension.Error>e).code === Excel.ErrorCodes.itemNotFound;

                if (!isExpectedError) {
                    throw e;
                } 
            }
        }

        if (!found) {
            console.log("Selection does not intersect any table");
        }
    }).catch(errorHandler);
});

Common errorHandler helper:

function errorHandler(error) {
    console.log(error);
    if (error instanceof OfficeExtension.Error) {
        console.log("Debug info: " + JSON.stringify(error.debugInfo));
    }
}


TRY IT LIVE: You can try the Excel 1.4+ approach live in literally five clicks in the new Script Lab (https://aka.ms/getscriptlab). Simply install the Script Lab add-in (free), then choose "Import" in the navigation menu, and use the following GIST URL: https://gist.github.com/Zlatkovsky/3ebdf5587cdc56d23b289fb6a5645030. See more info about importing snippets to Script Lab.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!