order: 5 id: excel-events-data-changed name: Data changed event description: Registers an event handler that runs when data is changed. author: OfficeDev host: EXCEL api_set: ExcelApi: '1.4' script: content: |- document.getElementById("setup").addEventListener("click", () => tryCatch(setup)); document.getElementById("register-data-changed-handler").addEventListener("click", () => tryCatch(registerDataChangedHandler)); async function registerDataChangedHandler() { await Excel.run(async (context) => { const sheet = context.workbook.worksheets.getItem("Sample"); const salesTable = sheet.tables.getItem("SalesTable"); const salesByQuarterBinding = context.workbook.bindings.add(salesTable.getRange(), "Table", "SalesByQuarter"); salesByQuarterBinding.onDataChanged.add(onSalesDataChanged); console.log("The data changed handler is registered."); await context.sync(); }); } async function onSalesDataChanged(eventArgs: Excel.BindingDataChangedEventArgs) { await Excel.run(async (context) => { console.log("Data was changed with binding " + eventArgs.binding.id); // Get the name of the table that's changed. const table: Excel.Table = context.workbook.bindings.getItem(eventArgs.binding.id).getTable(); table.load("name"); await context.sync(); console.log("Name of the changed table: " + table.name); }); } async function setup() { await Excel.run(async (context) => { context.workbook.worksheets.getItemOrNullObject("Sample").delete(); const sheet = context.workbook.worksheets.add("Sample"); let salesTable = sheet.tables.add('A1:E1', true); salesTable.name = "SalesTable"; salesTable.getHeaderRowRange().values = [["Sales Team", "Qtr1", "Qtr2", "Qtr3", "Qtr4"]]; salesTable.rows.add(null, [ ["London", 500, 700, 654, null ], ["Hong Kong", 400, 323, 276, null ], ["New York", 1200, 876, 845, null ], ["Port-of-Spain", 600, 500, 854, null ], ["Nairobi", 5001, 2232, 4763, null ] ]); salesTable.getRange().format.autofitColumns(); salesTable.getRange().format.autofitRows(); sheet.activate(); await context.sync(); }); } /** Default helper for invoking an action and handling errors. */ async function tryCatch(callback) { try { await callback(); } catch (error) { // Note: In a production add-in, you'd want to notify the user through your add-in's UI. console.error(error); } } language: typescript template: content: |-

This sample shows how to register and use a handler for the data-changed event.

Set up

Try it out

language: html style: content: |- body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; font-size: 14px; line-height: 1.5; padding: 10px; } section { margin-bottom: 20px; } h3 { margin-top: 0; margin-bottom: 10px; font-size: 16px; } p { margin: 0 0 10px 0; } button { background-color: #f0f0f0; color: #333333; border: 1px solid #8a8a8a; padding: 8px 16px; font-size: 14px; cursor: pointer; border-radius: 2px; margin-left: 20px; margin-bottom: 5px; min-width: 80px; display: block; } button:hover { background-color: #e0e0e0; } button:active { background-color: #d0d0d0; } input { padding: 8px; margin: 5px 0; border: 1px solid #ccc; border-radius: 2px; font-size: 14px; } .header { text-align: center; background-color: #f3f2f1; padding: 10px; } language: css libraries: |- https://appsforoffice.microsoft.com/lib/1/hosted/office.js https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/master/types/office-js/index.d.ts