Reputation: 209
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:
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:
ActiveSheet.Cells(...).Activate
thing and using Cells(y, x)
insteadset tbl = doc.tables(tc)
and set tbl = Nothing
at the end of the loopThere 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?
Upvotes: 3
Views: 445
Reputation: 26
Please give this a try:
Change:
For Each tbl In doc.Tables
prev = -42
To:
For Each tbl In doc.Tables
tbl.Select ' < add this
prev = -42
Had a similar issue: Using VBA, I open a Word Document with > 300 pages and > 200 tables. While the code loops through the document, it collects data from the tables. I used the .Select
line for debugging purposes so I knew where in the Document the code was working, but found when I commented it out later after debugging, the code would run, but not hit every table.
I also tried adding a Wait loop, to ensure the Document fully loaded prior to running my code, but that did not help.
You can also add a line Application.ScreenUpdating = False
near the top of your code to avoid the screen flash .Select
causes.
This does not really answer your question, but perhaps it will get your code working.
Upvotes: 1