查找与选择相交的表格

时间:2016-09-27 16:17:22

标签: excel office-js

我正在寻找相当于Excel VBA Intersect方法的Javascript。我需要找到活动的单元格表。基本上我对表所做的一切都基于用户当前选择的表。 IIRC,目前没有办法直接这样做。所以我试图做的基本上是这样的:

  • 获取所选范围(仍然不完美,因为我真的只想要 ActiveCell ,而不是选择)。
  • 获取工作表。
  • 遍历工作表上的所有表格。
  • 检查每个表格,看看所选范围是否在表格范围内。

我和猴子在一起,这就是我现在所做的不起作用......

Excel.run(function(ctx) {

    var Selection = ctx.workbook.getSelectedRange();
    var Tables = ctx.workbook.tables;
    var TableNames = ctx.workbook.tables.load("name");

    for (var i = 0; i < TableNames.items.length; i++)
    {
        var Table = ctx.workbook.tables.getItem(TableNames.items[i].name);
        Table.getRange().load('address');
        var Intersect = Selection.getBoundingRect(Table.getRange().address);
        if (Intersect != null) {return ctx.sync().then(function() {
            TableNames.items[i].name;
        })};
    }

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

如果API是原生的,这将是向前迈出的重要一步。 ;)

谢谢, 扎克

1 个答案:

答案 0 :(得分:4)

有几种方法可以检查当前选择是否与表格相交。这个片段演示了其中两个。

以下两个示例都是使用TypeScript 2.1 +的async / await语法编写的。第二种方法通过使用“await”变得非常简单,但两者都可以通过常规的promise-chaining来实现。

  1. ExcelApi 1.4+的效率要高得多,但它只能在较新的Excel版本上运行(基于订阅,而不是2016年的MSI / RTM)。它同时进行所有交叉检查。
  2. 如果您有数百个表,或者如果您在Excel Online上运行,则ExcelApi 1.1版本效率较低。它需要更多的往返服务器,因为它逐个检查每个表交集,并依赖于抛出的错误来通知它没有找到交集。
  3. ExcelApi 1.4+方法:

    $('#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方法:

    $('#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);
    });
    

    常见的errorHandler助手:

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


    尝试现场:您可以在新脚本实验室(https://aka.ms/getscriptlab)中实际点击五次点击尝试Excel 1.4+。只需安装Script Lab加载项(免费),然后在导航菜单中选择“导入”,并使用以下GIST URL:https://gist.github.com/Zlatkovsky/3ebdf5587cdc56d23b289fb6a5645030。请参阅more info about importing snippets to Script Lab