VBA一次性使用xlCellTypeVisible在AutoFilter之后删除多行将引发错误

我有一个表上的自动filter,正确过滤表中的列不等于所提供的string值。 然后,我想要删除所有未经过滤的可见行(一次最多可能有1000到2000行)。 但是,我在EntireRow.Delete方法上得到一个错误。 这是我的代码,我怎样才能一次成功地删除这些行?

 Dim columnFilter As String columnFilter = "Foo" Set tbl = ActiveCell.CurrentRegion tbl.AutoFilter tbl.AutoFilter Field:=columnNum, Criteria1:="<>" & columnFilter '***Error thrown here tbl.Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow.Delete 

给出的错误是: Run-time error '1004': Delete method of Range class failed.

不要像这样使用。 坚持Range.CurrentRegion属性,而偏移保留标题。

在执行AutoFilter方法之后,删除可见的行也是一个警告。 您应该始终检查以确保在删除操作之前应用了条件后,至less有一行是可见的。 有很多方法可以做到这一点; 这是涉及本机工作表SUBTOTAL函数的能力,从计算中排除不可见的行。

另一个问题是将结构化的Table ListObject对象与常规工作表数据混淆。 结构化表格需要特别考虑。 我在下面的例程中添加了代码,以testing过滤的区域是一个ListObject表,并根据这个确定来决定两种删除行的方法。

 Sub fooFilter() Dim columnFilter As String, columnNum As Long columnFilter = "Foo" columnNum = 1 With Sheets("Sheet1") If .AutoFilterMode Then .AutoFilterMode = False With .Cells(1, 1).CurrentRegion .AutoFilter Field:=columnNum, Criteria1:="<>" & columnFilter With .Resize(.Rows.Count - 1, .Columns.Count).Offset(1, 0) If CBool(Application.Subtotal(103, .Columns(columnNum))) Then 'very simple test to see if we are in a ListObject or not If .ListObject Is Nothing Then .SpecialCells(xlCellTypeVisible).EntireRow.Delete Else .EntireRow.Delete End If End If End With 'leave filter there but clear the filter .AutoFilter Field:=columnNum End With End With End Sub 

如果你试图一直删除工作表底部¹,你应该得到一个

 Run-time error: '1004' Application-defined or object-defined error 

上面的错误与您可以删除多less行的限制无关。 问题是,您正在尝试使用Range.Offset属性之前调整关联的范围。 如果不resize,您尝试按照.Offset中的行数从表单中移除范围。 首先减less一行,然后偏移保存您的标题。

.UsedRange属性有一定的波动性 ,我对它的使用越来越less。

有一个关于这个问题的MS KB白皮书,试图删除没有显示的行。 请参阅删除或修改已过滤的Excel 2007工作表中隐藏行上方和下方的行也删除或修改隐藏行以了解详细信息。

¹将工作表合法地填充到最后一行是非常罕见的。 工作表由于stream氓值或过分热心的格式而显示错误的xlCellTypeLastCell属性的可能性更大。 在调整编码以补偿工作表中的问题之前,应该纠正工作表以正确反映实际数据的范围。