VBA复制Word表格丢失数据

3
我接到一个VBA代码继承任务,任务是将Word文档中表格的内容复制到Excel中。该代码来自Excel的插件,使用后期绑定调用Word以避免在旧版本的Excel中使用时出现引用错误。该插件在Office 2016中进行维护,同时也可在Office 2016、2013和2010中使用。
程序的核心如下:
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真正完成了操作,然后再开始下一个迭代?

你的代码中有一些缺失的部分,比如:内部循环中的vcont是什么意思?如果你的表格格式良好,复制粘贴解决方案就不应该有任何问题。此外,你是如何在Word和Excel之间设置绑定的? - Kazimierz Jawor
CellContents() 的代码是什么? - jsotola
CellContents() 函数分解内容控件并返回一个字符串数组。 - V. V. Kozlov
1个回答

1
请尝试一下:

更改:

; 回答不要超过200个字符。
For Each tbl In doc.Tables
    prev = -42

至:

For Each tbl In doc.Tables
    tbl.Select ' < add this
    prev = -42

我遇到了类似的问题:使用VBA打开一个超过300页和200个表格的Word文档。当代码循环浏览文档时,它从表格中收集数据。我在调试时使用了.Select语句以便知道代码在文档中的位置,但后来在调试后注释掉该语句后,发现代码会运行,但不会触及每个表格。
我还尝试添加了一个等待循环,以确保文档在运行我的代码之前完全加载,但这没有帮助。
您也可以在代码顶部附近添加一行Application.ScreenUpdating = False,以避免.Select引起的屏幕闪烁。
这并不真正回答您的问题,但也许它能让您的代码正常工作。

嗯,虽然不是特别鼓励(https://dev59.com/3Ggv5IYBdhLWcg3wSe0f),但我想还是值得一试的... - David Rogers
初步测试表明这样做是可以的。也许通过显式的 .Select Word 填充缓冲区或其他什么东西。这个解决方案比显式的 4 秒延迟运行得更快一些。 - V. V. Kozlov
关于不太鼓励使用select,我有同样的看法。然而,链接的文章是关于Excel的,我的经验表明它比Word要少得多的错误(“几乎完美”)。 - V. V. Kozlov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接