如何删除具有垂直合并的一个或多个单元格的表中的空格的空行或行?

时间:2013-02-13 10:57:56

标签: vba ms-word word-vba

当表包含垂直和水平合并的单元格时,我需要一个vba脚本或帮助我正在编写的内容,以便不退出迭代。

表格示例:

---------
|   |   | <-- I don't want these rows deleted, they can be skipped
|---|   |
|   |   | <-- I don't want these rows deleted, they can be skipped
|---|---|
|   |   | <-- this must be checked for emptiness in order to decide to delete or not
|---|---|
|   |   | <-- this must be checked for emptiness in order to decide to delete or not
|---|---|

到目前为止我在VBA中的脚本:

Public Sub DeleteEmptyRows()
    Dim c As String
    c = ""
    Dim oTable As Table, oRow As Integer
    ' Specify which table you want to work on.
    For Each oTable In ActiveDocument.Tables

        For oRow = oTable.Rows.Count To 1 Step -1
            'On Error GoTo NextIteration
            MsgBox oTable.Rows(oRow).Range.Text
            'If Len(oTable.Rows(oRow).Range.Text) = oTable.Rows(oRow).Cells.Count * 2 + 2 Then
            If Len(Replace(oTable.Rows(oRow).Range.Text, Chr(13) & Chr(7), vbNullString)) = 0 Then
                oTable.Rows(oRow).Delete
            End If
        Next oRow
    Next oTable
    MsgBox c
End Sub

如何重现错误: 创建一个5x5表。选择单元格(0,0)和单元格(1,0)并合并它们。选择单元格(0,1)和单元格(0,2)并合并。运行脚本并获得5991错误..

问题是我收到运行时错误5991:无法访问此集合中的各个行,因为存在垂直合并的单元格。

我真的不知道该怎么做,因为如果发生这个错误,就不会有任何行被照顾。通常我的表有一个标题,它有垂直合并的单元格,而正文行则没有,所以我什么也做不了......

for Word。

2 个答案:

答案 0 :(得分:3)

这就是我想要删除表中不包含任何合并单元格但不包含任何文本的所有行。

包含合并单元格的表的问题不是删除行,而是识别实际合并的单元格,然后删除剩下的内容。

我接近这个的方法是循环遍历表格中的所有单元格,并为每一行锻炼计算多少列(水平合并的单元格和从上面垂直合并的单元格被忽略)并且感谢此页面({{3} }) 如果行中的任何单元格是我们可以告诉的垂直合并单元格的顶部。

最后,我们还检查行中是否有任何文字。

这是我提出的代码,希望评论应该是直截了当的。不幸的是,由于Word处理这些东西的方式,单元格必须选择而不是仅使用范围 - 这不是理想的,因为它会显着减慢速度。它在我的所有测试中都有效。

Option Explicit

Public Sub DeleteEmptyRows()
    Dim oTable As Table, oCol As Integer, oRows As Integer
    Dim iMergeCount() As Integer, dCellData() As Double
    Dim MyCell As Cell
    Dim iCurrentRow As Integer, iRowCounter As Integer

    'Watching this happen will slow things down considerably
    Application.ScreenUpdating = False

    ' Specify which table you want to work on.
    For Each oTable In ActiveDocument.Tables
        'We need to store the number of columns to determine if there are any merges
        oCol = oTable.Columns.Count

        ReDim dCellData(1 To oTable.Rows.Count, 1 To 3)
        'The first column will count the number of columns in the row if this doesn't match the table columns then we have merged cells
        'The second column will count the vertical spans which tells us if a vertically merged cell begins in this row
        'The third column will count the characters of all the text entries in the row.  If it equals zero it's empty.

        iCurrentRow = 0: iRowCounter = 0
        For Each MyCell In oTable.Range.Cells
            'The Information property only works if you select the cell. Bummer.
            MyCell.Select

            'Increment the counter if necessary and set the current row
            If MyCell.RowIndex <> iCurrentRow Then
                iRowCounter = iRowCounter + 1
                iCurrentRow = MyCell.RowIndex
            End If

            'Check column index count
            If MyCell.ColumnIndex > VBA.Val(dCellData(iRowCounter, 1)) Then dCellData(iRowCounter, 1) = MyCell.ColumnIndex

            'Check the start of vertically merged cells here
            dCellData(iRowCounter, 2) = dCellData(iRowCounter, 2) + (Selection.Information(wdEndOfRangeRowNumber) - Selection.Information(wdStartOfRangeRowNumber)) + 1

            'Add up the length of any text in the cell
            dCellData(iRowCounter, 3) = dCellData(iRowCounter, 3) + VBA.Len(Selection.Text) - 2 '(subtract one for the table and one for cursor(?))

            'Just put this in so you can see in the immediate window how Word handles all these variables
            Debug.Print "Row: " & MyCell.RowIndex & ", Column: " & MyCell.ColumnIndex & ", Rowspan = " & _
                (Selection.Information(wdEndOfRangeRowNumber) - _
                Selection.Information(wdStartOfRangeRowNumber)) + 1
        Next MyCell

        'Now we have all the information we need about the table and can start deleting some rows
        For oRows = oTable.Rows.Count To 1 Step -1
            'Check if there is no text, no merges at all and no start of a vertical merge
            If dCellData(oRows, 3) = 0 And dCellData(oRows, 1) = oCol And dCellData(oRows, 2) = oCol Then
                'Delete the row (we know it's totally unmerged so we can select the first column without issue
                oTable.Cell(oRows, 1).Select
                Selection.Rows.Delete
            End If
        Next oRows
    Next oTable

    Application.ScreenUpdating = True
End Sub

答案 1 :(得分:1)

您应该检查条件Range.MergeCells属性,如果合并范围中的单元格,则会返回TRUE