删除表格中的空白行

问题描述 投票:0回答:9

我正在尝试运行一个宏,该宏选择表列中的空白单元格并删除整行。

下面的脚本执行了除删除部分之外的所有操作,从而提示以下错误:

运行时错误 1004 - “删除 Range 类的方法失败”

我使用了以下代码:

Sub test()
Range("Table1[[New]]").Activate
Selection.SpecialCells(xlCellTypeBlanks).Select
Selection.EntireRow.Delete
End Sub
excel vba
9个回答
15
投票

问得好!如果没有桌子,

.EntireRow.Delete
总是有效,但在桌子内它看起来就像不起作用。

这有效:

Sub Test()
  Dim Rng As Range
  On Error Resume Next
  Set Rng = Range("Table1[[New]]").SpecialCells(xlCellTypeBlanks)
  On Error Goto 0
  If Not Rng Is Nothing Then
    Rng.Delete Shift:=xlUp
  End If
End Sub

3
投票

您实际上可以一次性完成,但需要使用

ListObject
对象及其
DataBodyRange
ListColumns
属性:

Sub ClearBlankCellsInColumnNew()
Dim rngBlanks As Excel.Range

With Worksheets("Sheet1").ListObjects("Table1")
    On Error Resume Next
    Set rngBlanks = Intersect(.DataBodyRange, .ListColumns("New").Range).SpecialCells(xlCellTypeBlanks)
    On Error GoTo 0
    If Not rngBlanks Is Nothing Then
        rngBlanks.Delete
    End If
End With
End Sub

1
投票

第 1 步:在表中创建一个辅助列,您可以在其中检查该行中是否有任何空白字段。例如,如果表中有 3 列:A(价格)、B(数量)和 C(成本),您可以添加第四列 D 并将其标记为“有空白吗?”。 等式为

=IF(OR(ISBLANK([@Price]),ISBLANK([@Quantity]),ISBLANK([@Cost])),"Yes","No")

这将为您提供一列进行过滤以查看所有空白。

第 2 步:在 VBA 中,您将执行以下操作:

Range("MyTableNameHere").AutoFilter Field:=Range("MyTableNameHere[Any Blanks?]").Column, Criteria1:="Yes"
Application.DisplayAlerts = False
Range("MyTableNameHere").ListObject.DataBodyRange.SpecialCells(xlCellTypeVisible).Delete
Application.DisplayAlerts = True
Range("MyTableNameHere").AutoFilter Field:=Range("MyTableNameHere[Any Blanks?]").Column

这本质上是使用辅助列过滤到表中要删除的行,选择表中的所有可见数据,然后取消过滤表。 我正在搜索如何删除表中的所有可见行,并找到了这个并摆弄直到我发现这可行。 将其与辅助列结合起来以选择带有任何空白的所有行似乎也是您想要的。


1
投票

改编之前的答案:

On Error Resume Next
Set Rng = ListObjects(1).DataBodyRange.SpecialCells(xlCellTypeBlanks)
On Error GoTo 0
If Not Rng Is Nothing Then
Rng.Delete Shift:=xlUp
End If

1
投票

这个 One 衬垫也会有帮助

on error resume next '如果表中没有找到空行则继续宏 .Range("Table1").Columns(1).SpecialCells(xlCellTypeBlanks).EntireRow.Delete

'此删除空使用第一列作为检查空白的参考 '为表使用自定义名称,以便在代码中轻松操作


0
投票

在 Excel 中使用 ListObjects 可以轻松使用以下内容删除空白行。

Sub RemoveBlankRow(ByVal SheetName As String, TableName As String)
Dim rng As Integer

rng = Sheets(SheetName).ListObjects(TableName).DataBodyRange.Rows.Count

For i = 1 To rng
    If Application.WorksheetFunction.CountA(Rows(i)) = 0 Then Rows(i).EntireRow.Delete
Next
End Sub

0
投票

关于 Frej Lindstrom 解决方案的两个注释,我使用过但必须稍作调整:

(1) 在 Next 之前添加 End If

(2) 在 End If 之前添加“i = i - 1”

Why?
,因为如果您有一层一层的空白行,您将跳过一行,因为所有行的数字都向上移动一位。本质上,如果您删除了
row [N]
,则另一行现在是
row [N]
,您还需要对其进行测试,而不是立即移至
row [N + 1]

重要警告:如果你的最后一行是空白,这会给你一个卡住的循环。不过,我可能会放入一个 IF 来处理它。

我知道这是一个旧线程,但我想我会添加这个,以防其他人来寻找类似的解决方案。感谢 Frej - 你的代码真的很有帮助!


0
投票

这是我的解决方案:

Public Sub remove_blank_rows(sh As Worksheet)

    Dim tbl As ListObject
    Set tbl = sh.ListObjects(1)
    Dim i As Long
    Dim ii As Long
    
    Application.EnableEvents = False
    
    ii = tbl.Range.rows.Count
    For i = 2 To ii
        If WorksheetFunction.CountA(rows(i)) = 0 Then
            
            rows(i).EntireRow.Delete
            
            ii = tbl.Range.rows.Count
            If i >= ii Then
                GoTo A
            End If
            
            If i > 1 Then
                i = i - 1
            End If
    
        End If
    Next
A:
    
    Application.EnableEvents = True
End Sub

请注意,当您删除一行时,该行下面的所有行都会上移 1,这就是索引

i
递减以便在下一次迭代中再次检查同一行的原因!但请注意,
i
不需要超过一定的限制,这是通过两个
If
句子完成的。


0
投票

感谢您的合作。我不断得到一个额外的空白行,因此我必须进行一些修改。总之,DeleteBlankTableRows 宏使用 GetMyTableName UDF 从活动单元格获取表名称。如果活动单元格不在表格内,则返回“N/A”,并向用户发送一条消息以选择表格内的任何单元格。

Option Explicit

Function GetMyTableName(myActiveCell As Range) As String
    Dim myTableName As String

    myTableName = ""
    On Error GoTo ErrorHndler
    myTableName = myActiveCell.ListObject.Name
    GetMyTableName = myTableName
    Exit Function

ErrorHndler:
    GetMyTableName = "N/A"
End Function

Sub DeleteBlankTableRows()
    Dim myBook As Workbook, mySheet As Worksheet, myRange As Range 
    Dim myActiveCell As Range, myTableName As String
    Dim i As Long, j As Long, myCount As Long, myTable As ListObject

    Set myBook = ActiveWorkbook
    Set mySheet = myBook.ActiveSheet
    Set myActiveCell = ActiveCell
    myTableName = GetMyTableName(myBook.Worksheets(mySheet.Name).Range(myActiveCell.Address))

    If Not myTableName = "N/A" Then
        Set myTable = myBook.Sheets(mySheet.Name).ListObjects(myTableName)
        i = myTable.Range.Rows.Count
    
        For j = 2 To i
            If Application.WorksheetFunction.CountA(Rows(j)) = 0 Then
                Rows(j).EntireRow.Delete
            
                i = myTable.Range.Rows.Count
                myCount = myCount + 1
                If j > i Then
                    Exit For
                End If

                j = j - 1
            End If
        Next j
        MsgBox myCount & " blank rows deleted. " & Chr(10) & Chr(10) & _
            "TableName: " & myTableName & Chr(10) & _
            "Worksheet: '" & mySheet.Name & "'" & Chr(10) & _
            "TableRange: " & myTable.Range.Address, _
            vbInformation + vbOKOnly, "DeleteBlankTableRows Macro"
    Else
        MsgBox "Cell " & myActiveCell.Address & " is not within a table. Please select a cell within the table and run this macro again.", vbInformation + vbOKOnly, "DeleteBlankTableRows Macro"
    End If
End Sub
© www.soinside.com 2019 - 2024. All rights reserved.