Summary:
- Updating values in large Word tables (larger than 10 by 10) is very slow. Performance gets exponentially worse with table size.
- I'm using
myTable.values = arrNewValues
. I've also triedmyTable.addRows("end", rows, arrNewValues)
. Where arrNewValues is a 2D array. - I've also tried using updating via getOoxml() and insertOoxml(), but ran into other issues I haven't been able to resolve, but has good performance.
- Slow performance seems to be caused by "ScreenUpdating" (same issue exists in VBA and is solved via ScreenUpdating=false). I believe it is critically important to add the ability to temporarily turn off ScreenUpdating.
- Is there another way to improve table updating performance?
Background:
My add-in (https://analysisplace.com/Solutions/Document-Automation) performs document automation (updates content in a variety of Word docs). Many customers want to be able to update text in largish tables. Some documents have dozens of tables (appendices). I have run into the issue where updating these documents is unacceptably slow (well over a minute) due to the table updates.
Update time by table size:
- 2 rows by 10 columns: .33 seconds
- 4 rows by 10 columns: .52 seconds
- 8 rows by 10 columns: 1.5 seconds
- 16 rows by 10 columns: 5.5 seconds
- 32 rows by 10 columns: 20.8 seconds
- 64 rows by 10 columns: 88 seconds
Sample Office.js Code (Script Lab):
function updateTableCells() {
Word.run(function (context) {
var arrValues = context.document.body.tables.getFirst().load("values");
return context.sync().then(
function () {
var rows = arrValues.values.length;
var cols = arrValues.values[0].length;
console.log(getTimeElapsed() + "rows " + rows + "cols " + cols);
var arrNewValues = [];
for (var row = 0; row < rows; row++) {
arrNewValues[row] = [];
for (var col = 0; col < cols; col++) {
arrNewValues[row][col] = 'r' + row + ':c' + col;
}
}
console.log(getTimeElapsed() + 'Before setValues ') ;
context.document.body.tables.getFirst().values = arrNewValues;
return context.sync().then(
function () {
console.log(getTimeElapsed() + "Done");
});
});
})
.catch(OfficeHelpers.Utilities.log);
}
Sample Word VBA Code:
VBA performance is similar to the Office.js performance without ScreenUpdating = False. With ScreenUpdating = False, performance is instant.
Sub PopulateTable()
Application.ScreenUpdating = False
Dim nrRow As Long, nrCol As Long
Dim tbl As Word.Table
Set tbl = ThisDocument.Tables(1)
For nrRow = 1 To 32
For nrCol = 1 To 10
tbl.Cell(nrRow, nrCol).Range.Text = "c" & nrRow & ":" & nrCol
Next nrCol
Next nrRow
End Sub
Article explaining slow performance: see "Improving Performance When Automating Tables": https://msdn.microsoft.com/en-us/library/aa537149(v=office.11).aspx?cs-save-lang=1&cs-lang=vb#code-snippet-3
Posts indicating there is no "ScreenUpdating = False" in Office.js: ScreenUpdating Office-js taskpane and Equivalent to Application.ScreenUpdating Property in office-js Excel add-in Sounds like we won't see it any time soon.
Post related to the updating tables via getOoxml() and insertOoxml(): Word Office.js: issues with updating tables in ContentControls using getOoxml() and insertOoxml()