首页 > 解决方案 > 使用VBA将所有段落转换为Word文档中的表格后如何重新缩进?

问题描述

我经常处理大型 Word 文档。我必须将所有段落转换为表格。

源文档结构示例:

在此处输入图像描述

转换后(插入 -> 表格 -> 将文本转换为表格)Word 会丢失有关随机段落缩进的信息。目标文件:

在此处输入图像描述

如您所见,段落“c”和“d”的缩进消失了。不知道为什么,但它经常发生。

它应该与源文档中的完全相同:

在此处输入图像描述

查找和纠正非常大的文档的错误需要几个小时,所以我认为我可以通过从源段落中获取缩进值来修复目标文档中损坏的缩进。

这是我第一次尝试使用 VBA,我是这样开始的:

Dim sourceDocument, targetDocument As Document
Dim myRange As Range
Set sourceDocument = ActiveDocument
Set targetDocument = Documents.Add(ActiveDocument.FullName)
Set myRange = targetDocument.Range(Start:=targetDocument.paragraphs(1).Range.Start, End:=targetDocument.paragraphs(targetDocument.paragraphs.Count).Range.End)
myRange.converttotable Separator:=wdSeparateByParagraphs
Dim i As Integer
For i = 1 To targetDocument.Tables(1).Range.Rows.Count
    targetDocument.Tables(1).Range.Rows(i).Range.Cells(1).Range.paragraphs(1).LeftIndent = sourceDocument.paragraphs(i).LeftIndent
    targetDocument.Tables(1).Range.Rows(i).Range.Cells(1).Range.paragraphs(1).FirstLineIndent = sourceDocument.paragraphs(i).FirstLineIndent
Next i

该脚本对简单段落按预期工作,因为段落数与目标表中的行数相匹配。但是对于源文档中存在的表,它会变得混乱。在表格中,段落的数量增加了一倍。

源表嵌套在一个目标单元格中​​,这很好,它们没有问题,也不必更正。

所以我的问题是如何将源段落与表中的目标段落匹配(省略源表和目标嵌套表)?

或者也许还有另一种将段落转换为具有正确缩进的表格的方法?

标签: vbams-word

解决方案


有很多方法可以解决这个问题。经过一番考虑,我决定一个相当直接的方法是从源文档中获取不在表格中的所有段落的数组。

循环目标文档中的行时,段落数仅在包含嵌套表的行中大于 1。在这种情况下,Range设置为结尾(最后一段)。

然后使用循环计数器从数组中的相应段落应用缩进(加 1,因为数组是从 0 开始的)。

Sub RestoreParaIndents()
    Dim sourceDocument As Document, targetDocument As Document
    Dim myRange As Range
    Set sourceDocument = ActiveDocument
    Set targetDocument = Documents.Add(ActiveDocument.FullName)
    Set myRange = targetDocument.content  

    'Get an array of all paragraphs not in a table in the source document
    'This will provide the indent information in the loop for the target document
    Dim aParas() As Paragraph, para As Paragraph
    Dim counterPara As Long
    counterPara = 0
    For Each para In sourceDocument.Paragraphs
        If Not para.Range.Information(wdWithInTable) Then
            ReDim Preserve aParas(counterPara)
            Set aParas(counterPara) = para
            counterPara = counterPara + 1
        End If
    Next

    myRange.ConvertToTable Separator:=wdSeparateByParagraphs

    Dim i As Long
    Dim rw As Row, rng As Range
    For i = 1 To targetDocument.Tables(1).Range.Rows.Count
        Set rw = targetDocument.Tables(1).Range.Rows(i)
        Set rng = rw.Range.Cells(1).Range

        'If the cell contains multiple paragraphs then in contains
        'a nested table. Skip the table and go to the end (last paragraph)
        If rng.Paragraphs.Count > 1 Then
            Set rng = rng.Paragraphs.Last.Range
        End If
        rng.Paragraphs(1).LeftIndent = aParas(i - 1).LeftIndent
        rng.Paragraphs(1).FirstLineIndent = aParas(i - 1).FirstLineIndent 
    Next i
End Sub

推荐阅读