1

当表格包含垂直和水平合并的单元格时,我需要一个 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 表。选择 cell(0,0) 和 cell(1, 0) 并合并它们。选择 cell(0, 1) 和 cell(0, 2) 并合并。运行脚本并得到 5991 错误..

问题是我得到一个运行时错误 5991: Can't access to individual lines in this collection 因为有垂直合并的单元格。

我真的不知道该怎么办,因为如果发生此错误,将不会处理任何行。通常我的表格有一个垂直合并单元格的标题,而正文行没有,所以我不能做任何事情......

对于字。

4

2 回答 2

3

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

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

我解决这个问题的方法是遍历表中的所有单元格,并且对于每一行锻炼计算多少列(水平合并的单元格和从上方垂直合并的单元格被忽略)并且感谢这个页面(http://word.mvps .org/FAQs/MacrosVBA/GetRowColSpan.htm)如果行中的任何单元格是我们可以判断的垂直合并单元格的顶部。

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

这是我想出的代码,希望注释应该是直截了当的。不幸的是,由于 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
于 2013-02-14T05:46:19.690 回答
1

您应该检查您的条件Range.MergeCells属性,如果范围内的单元格被合并,它将返回TRUE

于 2013-02-13T11:17:22.453 回答