When the data is changed in a binding in excel, the BindingDataChanged event if fired.
function addHandler() {
Office.select("bindings#MyBinding").addHandlerAsync(
Office.EventType.BindingDataChanged, dataChanged);
}
function dataChanged(eventArgs) {
write('Bound data changed in binding: ' + eventArgs.binding.id);
}
But the eventArgs
do not have information about what part of the data is changed. Is there any way, we can track this information? We have bindings with large number of cells like 5000 rows * 15 columns or 90 rows * 350 columns. We are using office js api 1.2.
Update 1 Used the code provided by Michael Saunders below. Seeing some strange behavior.I have selected G9:H9 and pressed delete. But the header is always returning as Column1 and Column2 (Look at the toastr notification on top right). I was expecting Column7 and Column8. Is this the expected behavior? (The testing was done on Excel 2016 with a table binding and not on office 365. Will try it next)
I think the above solution of tracking selectionchanged is clever but I believe it gets you in a race condition between events firing. I tested the above solution and it appears that the SelectionChange triggers before the DataChanged Event which means you would be grabbing the current selected cell rather than the previous. I do not think you can avoid this race condition because events are async but potentially you could track previous and current selection like this:
I tested it and it works...not nice and potentially there is a better way to track multiple levels but it seems to work. Ideally the DataChanged Event would have this in the EventArgs like VSTO. Fingers crossed it's coming soon!:)
Note - It does seem to work with copy & paste but this solution would need to be enhanced to handle the following situations:
Update 1 - Another situation
There isn't a direct way to get the row in the binding which changed.
The best workaround to avoid checking your entire table is to track the user's selection. The BindingSelectionChanged event fires every time the user selects something in the Binding, which always happens when entering data in a table. The solution is to always save in memory the most recent previous selection location in a binding. Then when the data changes, check that stored location.
Here's the code:
-Michael, PM for Office add-ins
The only issue with Micheal's answer is that in the onBindingDataChanged function the getDataAsync method's parameter object's startColumn is incorrectly passed as startCol, and that is why the starting column is returned.