I've inherited some VBA code which copies the contents of tables in a Word document to Excel. The code itself is from an Excel addin which invokes Word using late binding to avoid the reference error when used in older versions of Excel. The addin itself is maintained in Office 2016 while also being used in Office 2016, 2013, and 2010.
The heart of the program is the following:
tc = 1                                                     ' table counter
For Each tbl In doc.Tables
    prev = -42                                             ' previous row
    Application.Wait DateAdd("s", 2, Now)                  ' Note this line
    For Each cel In tbl.Range.Cells
        cont = CellContents(cel.Range)                     ' dim cont() as string
        txt = cont(0)
        xx = cel.ColumnIndex
        yy = cel.RowIndex
        If yy <> prev Then
            xtra = 1                                       ' extra x cell counter
            prev = yy                                      ' reset for new row
        End If
        xtra = xtra - 1
        For Each v In cont                                 ' dim v as variant
            txt = CStr(v)
            ActiveSheet.Cells(xlrow + yy, xtra + xx).Activate
            ActiveCell = txt
            ActiveCell.Font.Bold = cel.Range.Bold
            colr = cel.Range.Font.Color
            ActiveCell.Font.Color = colr
            colr = cel.Shading.BackgroundPatternColor
            If colr <> -16777216 Then ActiveCell.Interior.Color = colr
            Select Case cel.Range.ParagraphFormat.Alignment
                Case 2 ' wdAlignParagraphRight
                    ActiveCell.HorizontalAlignment = xlRight
                Case 1 ' wdAlignParagraphCenter
                    ActiveCell.HorizontalAlignment = xlCenter
                Case 0, 3 ' wdAlignParagraphLeft, wdAlignParagraphJustify
                    ActiveCell.HorizontalAlignment = xlLeft
                Case Else
            End Select
            xtra = xtra + 1
        Next v
    Next cel
    xlrow = xlrow + tbl.rows.Count + 1
    Application.StatusBar = "Table " & tc & " in " & nm
    DoEvents
    tc = tc + 1
Next tbl
No, copy paste from Word to Excel won't do as it does not do any processing, does not handle text copy from cell to cell well, does not handle cell breaks well, nor does it handle content controls.
I've observed a problem when this procedure is copying a large number of large tables from Word, it will miss a table.  However, when I slow down the process, either by forcing a stop in the debugger or adding an Application.Wait in the loop, the problem disappears.
The code does the following:
- For a document, loop over all tables in the document
- Then for a table, loop over all cells in that table and copy them over to Excel, preserving the background and foreground colours
A typical document may have 10 to 20 tables with 50 or more cells each.
It's almost as if when iterating through the tables, if VBA is still busy, subsequent tables are returned empty.
I have tried the following:
- Changing to Word Automation using Early Binding
- Getting rid of the ActiveSheet.Cells(...).Activatething and usingCells(y, x)instead
- For loop using counter and set tbl = doc.tables(tc)andset tbl = Nothingat the end of the loop
- Multiple DoEvents
- Just setting the cell's text and nothing else, minimal work in the loop (Here I lost less data)
There was no change to the behaviour. Simply treacherous. ужас.
Is there a better way to do this, without Application.Wait or sleep?  How to determine that Excel is really done before starting on the next iteration?
 
    