2016-09-28 72 views
2

当在Excel中绑定中更改数据时,BindingDataChanged事件被触发。如何识别办公室js api BindingDataChanged事件中更改的单元格?

function addHandler() { 
    Office.select("bindings#MyBinding").addHandlerAsync(
    Office.EventType.BindingDataChanged, dataChanged); 
} 
function dataChanged(eventArgs) { 
    write('Bound data changed in binding: ' + eventArgs.binding.id); 
} 

但是eventArgs没有关于哪部分数据改变的信息。有什么办法,我们可以跟踪这些信息吗?我们绑定了大量的单元格,如5000行* 15列或90行* 350列。我们正在使用office js api 1.2。

更新1使用下面的Michael Saunders提供的代码。看到一些奇怪的行为。我选择了G9:H9并按下删除。但是标题总是以Column1和Column2的形式返回(查看右上角的toastr通知)。我期待Column7和Column8。这是预期的行为? (测试是在Excel 2016上使用表格绑定完成的,而不是在办公室365上完成的。接下来会尝试使用)data changed behavior

回答

0

没有直接的方法可以获取已更改绑定中的行。

避免检查整个表的最佳解决方法是跟踪用户的选择。每次用户在Binding中选择一些东西时,都会触发BindingSelectionChanged event,这在输入表格中的数据时总会发生。解决方法是始终在内存中保存最近的先前的选择位置的绑定。然后当数据改变时,检查存储的位置。

下面的代码:

myBinding.addHandlerAsync(Office.EventType.BindingSelectionChanged, onSelectionChange); 

var previousStartRow, previousRowCount, previousStartColumn, previousColumnCount; 

function onSelectionChange(eventArgs){ 
    previousStartRow = eventArgs.startRow; 
    previousRowCount = eventArgs.rowCount; 
    previousStartColumn = eventArgs.startColumn; 
    previousColumnCount = eventArgs.columnCount; 
} 

function onBindingDataChange(eventArgs){ 
    eventArgs.binding.getDataAsync({ 
     startRow: previousStartRow, 
     rowCount: previousRowCount, 
     startCol: previousStartColumn, 
     columnCount: previousColumnCount 
    }, function(result){ 
     // Do whatever you need with result.value. 
     // You might want to compare and update your in-memory representation of the data. 
    }); 
} 

-Michael,PM为Office插件

+0

1.用户拖放操作如何工作?这些事件是否总是一个接一个地出现?此外,它看起来像多个用户在工作表上时,所有用户都将获得'BindingSelectionChanged'事件。如何区分在这种情况下更改的选择。 – renil

+0

您有两种选择:或者等到用户在拖放操作之后更改其选择(这适用于上面的解决方案),或者修改解决方案以检查*当前*选定范围的更改。 –

+0

您能否详细解释选项2?我们如何跟踪大型Excel表中的变化?任何推荐的方法?第一个选项对用户有很大的依赖性,除非办公室api触发拖动结束事件。 – renil

1

我想跟踪的SelectionChanged上述解决办法是聪明,但我相信它可以让你在事件之间的竞争条件射击。我测试了上述解决方案,并且看起来SelectionChange在DataChanged事件之前触发,这意味着您将抓取当前选定的单元格而不是先前的单元格。我不认为你能避免这种竞争状态,因为事件是异步但可能你可以跟踪过去和当前的选择是这样的:

myBinding.addHandlerAsync(Office.EventType.BindingSelectionChanged, onSelectionChange); 

var startRow, rowCount, startColumn, columnCount; 
var previousStartRow, previousRowCount, previousStartColumn, previousColumnCount; 



function onSelectionChange(eventArgs){ 
    // save "previous" selected cell into previous variables 
    previousStartRow = startRow; 
    previousRowCount = rowCount; 
    previousStartColumn = startColumn; 
    previousColumnCount = columnCount; 

    // re-assign the current selected to the eventArgs 
    startRow = eventArgs.startRow; 
    rowCount = eventArgs.rowCount; 
    startColumn = eventArgs.startColumn; 
    columnCount = eventArgs.columnCount; 
} 

function onBindingDataChange(eventArgs){ 
    eventArgs.binding.getDataAsync({ 
     startRow: previousStartRow, 
     rowCount: previousRowCount, 
     startCol: previousStartColumn, 
     columnCount: previousColumnCount 
    }, function(result){ 
     // Do whatever you need with result.value. 
     // You might want to compare and update your in-memory representation of the data. 
    }); 
} 

我测试了它和它的作品......不是很好,并可能有更好的跟踪多个层面的方式,但它似乎工作。理想情况下,DataChanged事件可以在像VSTO这样的EventArgs中实现。手指穿过它的到来很快:)

- 它似乎有复制&粘贴工作,但这种解决方案将需要加强,以处理以下情况:

  • 细胞拖动ñ”降带“+”号。
  • 多个小区中选择,然后更新单个细胞用键盘和输入

更新1 - 另一种情况

  • 当更新绑定的边缘细胞,并按下回车键就会造成选择在绑定范围之外。在选择更改事件没有揭开序幕,并在上述解决方案将失败
+0

处理所有的边缘案例将是一个痛苦,正如您在更新1和其他情况中提到的那样。希望excel团队能够在早些时候在'EventArgs'中添加信息。手指越过了API 1.4,这个团队或者团队就会有更好的解决方法。 – renil

+0

@OfficeDev团队应该在Sheet Changed事件(VSTO)中实现功能,您可以轻松识别哪些单元格已更改,而无需跳过这些环节。 – Hari

0

与迈克尔的答案唯一的问题是,在onBindingDataChanged功能getDataAsync方法的参数对象的STARTCOLUMN被错误地作为startCol过去了,这就是为什么起始栏返回。

function onSelectionChange(eventArgs) { 
    startRow = eventArgs.startRow; 
    rowCount = eventArgs.rowCount; 
    startColumn = eventArgs.startColumn; 
    columnCount = eventArgs.columnCount; 
} 

// When data in the table is changed, this event is triggered. 
function onBindingDataChanged(eventArgs) { 
    Excel.run(function (ctx) { 
     // Highlight the table in orange to indicate data changed. 
     eventArgs.binding.getDataAsync({ 
      startRow: startRow, 
      rowCount: rowCount, 
      ***startColumn***: startColumn, 
      columnCount: columnCount 
     }, function (result) { 
      // Do whatever you need with result.value. 
      console.log(result.value); 
      // You might want to compare and update your in-memory representation of the data. 
     }); 
    }); 
} 
相关问题