我接到一个VBA代码继承任务,任务是将Word文档中表格的内容复制到Excel中。该代码来自Excel的插件,使用后期绑定调用Word以避免在旧版本的Excel中使用时出现引用错误。该插件在Office 2016中进行维护,同时也可在Office 2016、2013和2010中使用。
程序的核心如下:
不,从Word复制粘贴到Excel不行,因为它不进行任何处理,无法很好地处理单元格之间的文本复制、换行和内容控件。
当从Word中复制大量大表格时,我发现了一个问题:会漏掉一些表格。但是,当我减慢过程速度(通过在调试器中强制停止或在循环中添加Application.Wait),问题就消失了。
代码执行以下操作:
- 遍历文档中的所有表格 - 对于每个表格,遍历该表格中的所有单元格,并将它们复制到Excel中,保留背景和前景颜色
一个典型的文档可能有10到20个表格,每个表格有50个或更多单元格。
这似乎就像是当迭代表格时,如果VBA还在忙碌,后续表格就会返回为空。
我尝试了以下方法:
- 使用早期绑定的Word Automation(Early Binding) - 摆脱ActiveSheet.Cells(...).Activate的东西,改用Cells(y,x) - 使用计数器的For循环和set tbl = doc.tables(tc)以及循环结束时的set tbl = Nothing - 多个DoEvents - 仅设置单元格的文本,最小化循环中的工作量(在这里,我丢失的数据较少)
但是,行为没有改变。非常危险。是否有更好的方法来完成这个任务,而不使用Application.Wait或sleep?如何确定Excel真正完成了操作,然后再开始下一个迭代?
程序的核心如下:
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
不,从Word复制粘贴到Excel不行,因为它不进行任何处理,无法很好地处理单元格之间的文本复制、换行和内容控件。
当从Word中复制大量大表格时,我发现了一个问题:会漏掉一些表格。但是,当我减慢过程速度(通过在调试器中强制停止或在循环中添加Application.Wait),问题就消失了。
代码执行以下操作:
- 遍历文档中的所有表格 - 对于每个表格,遍历该表格中的所有单元格,并将它们复制到Excel中,保留背景和前景颜色
一个典型的文档可能有10到20个表格,每个表格有50个或更多单元格。
这似乎就像是当迭代表格时,如果VBA还在忙碌,后续表格就会返回为空。
我尝试了以下方法:
- 使用早期绑定的Word Automation(Early Binding) - 摆脱ActiveSheet.Cells(...).Activate的东西,改用Cells(y,x) - 使用计数器的For循环和set tbl = doc.tables(tc)以及循环结束时的set tbl = Nothing - 多个DoEvents - 仅设置单元格的文本,最小化循环中的工作量(在这里,我丢失的数据较少)
但是,行为没有改变。非常危险。是否有更好的方法来完成这个任务,而不使用Application.Wait或sleep?如何确定Excel真正完成了操作,然后再开始下一个迭代?
v
和cont
是什么意思?如果你的表格格式良好,复制粘贴解决方案就不应该有任何问题。此外,你是如何在Word和Excel之间设置绑定的? - Kazimierz Jawor