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.
- 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.
- 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.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…