2

In Word 2016 VBA I want to set the shading of each cell of a table with a loop. This seems to work for tables up to a size of about 15*15. With tables such as 20*20 or larger Word does not respond any more. Program execution seems to be correct though when using single step. I tried this for tables of ca. 50*50. ScreenRefresh and ScreenUpdating seem to have no influence. In the code example, setting the shading of each cell to the same background color is only for demonstration, finally I want to apply more complex settings.

Sub TableCells_SetBackgroundColors()
' Set background color for each cell in Word table
' Application does not respond if table is larger than about 20*20
' debug  single step works in any case
'Application.ScreenUpdating = False

Dim i, k, cntCol, cntRow As Integer
cntCol = 15 ' 20 is not ok
cntRow = 15 ' 20 is not ok
If ActiveDocument.Tables.Count <> 0 Then
    ActiveDocument.Tables(1).Delete
End If
ActiveDocument.Tables.Add Range:=Selection.Range, _
                             numRows:=cntRow, _
                             NumColumns:=cntCol

Dim myTable As Word.Table
Set myTable = Selection.Tables(1)
With myTable.Borders
 .InsideLineStyle = wdLineStyleSingle
 .OutsideLineStyle = wdLineStyleSingle
End With
For i = 1 To cntRow Step 1
    For k = 1 To cntCol Step 1
        myTable.Cell(i, k).Shading.BackgroundPatternColor = wdColorRed
        'Application.ScreenRefresh
    Next k
Next i

'Application.ScreenUpdating = True

End Sub
ht2016
  • 21
  • 1
  • Have you just tried waiting when the application doesn't respond anymore? When the execution of code takes longer then a certain time all office applications show this behaviour as far as I am concerned but usually you are still fine if you just wait. – Xam Eseerts Nov 19 '16 at 13:24

2 Answers2

0

Intro: The guy who commented here. Your problem occurs because the execution of the code takes to long doing stuff where to application itself doesn't do any events as far as I know. If this takes longer then a specific timespan the application just says it's not responding anymore. On my machine for example the application doesn't respond anymore even with only 15 rows and columns. There is one method that prevents this from happening: DoEvents. Below is your code with 3 more lines I added which works georgously on my machine. Below the code is a little more explanation.

Sub TableCells_SetBackgroundColors()
' Set background color for each cell in Word table
' Application does not respond if table is larger than about 20*20
' debug  single step works in any case
'Application.ScreenUpdating = False

    Dim i, k, cntCol, cntRow As Integer


    cntCol = 21 ' 20 is not ok
    cntRow = 21 ' 20 is not ok
    If ActiveDocument.Tables.Count <> 0 Then
        ActiveDocument.Tables(1).Delete
    End If
    ActiveDocument.Tables.Add Range:=Selection.Range, _
                                 numRows:=cntRow, _
                                 NumColumns:=cntCol

    Dim myTable As Word.Table
    Set myTable = Selection.Tables(1)
    With myTable.Borders
     .InsideLineStyle = wdLineStyleSingle
     .OutsideLineStyle = wdLineStyleSingle
    End With
    For i = 1 To cntRow Step 1

        'New
        Application.StatusBar = "Row " & i & " of " & cntRow
        'New

        For k = 1 To cntCol Step 1
            'New and important
            DoEvents
            'New and important
            myTable.Cell(i, k).Shading.BackgroundPatternColor = wdColorRed
        Next k
    Next i

    'New
    Application.StatusBar = False
    'New

End Sub

More Explanation: So for some reason Word is very slow with looping through all the cells of a table and applying some shading to them. This triggers the behaviour I described above. To prevent the application from not responding I inserted the line DoEvents in your column loop, so that the application "realizes that it is still alive" during every cell iteration. I did not test how much of an performance cost the DoEvents method has in this case but if you find it to be significant you can try to move DoEvents to the row loop and see if you are still fine. As for the other two lines with the StatusBar, these are not necessary to prevent the application from not responding but I find them very usefull because they prevent the user/you/me from worrying that the application crashed. It will tell you in the statusbar in which row the code currently is.

The statusbar during execution:

enter image description here

Xam Eseerts
  • 367
  • 3
  • 19
0

@Xam Eseerts

Thank you for your answer which solves the problem. (It is still surprising how slow Word seems to work here. For my task of creating a big colorful table I finally switched to Excel).

ht2016
  • 21
  • 1