2016-09-28 49 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. 
     }); 
    }); 
}