首页 > 解决方案 > 如何在过滤运行时错误 1004 后删除可见行

问题描述

尝试创建一个宏,在其中我根据列制作工作表的副本,并删除不等于我正在循环的当前值的内容。

我的数据可能在也可能不在原始工作表的表格中。我需要制作原始工作表的副本,然后删除以维护我在原始工作表中创建的列组。

Sub FilterCopy()
    Dim cl As Range
    Dim Ws As Worksheet

    Set Ws = ActiveSheet
    If Ws.FilterMode Then Ws.ShowAllData
    With CreateObject("scripting.dictionary")
       For Each cl In Ws.Range("A2", Ws.Range("A" & Rows.Count).End(xlUp))
       If Not .exists(cl.Value) Then
        .Add cl.Value, Nothing
        Ws.Copy
        Range("A1").AutoFilter 1, "<>" & cl.Value
        'The code below gives me the error
        ActiveSheet.AutoFilter.Range.Offset(1).SpecialCells(xlVisible).EntireRow.Delete
        Range("A1").AutoFilter
        Range("A1").AutoFilter
        ActiveWorkbook.SaveAs "U:\Test\" & cl.Value & ".xlsx", 51
        ActiveWorkbook.Close False
     End If
  Next cl
End With
End Sub

运行时错误“1004”:

Range 类的删除方法失败

标签: excelvba

解决方案


您的问题似乎是由于您尝试删除的行不连续而引起的。实际上,Excel-VBA 在处理不接触和形成不同区域的范围时会遇到困难。

为了解决这个问题,您可以像这样处理范围一个区域:

Dim MyRange As Range
Set MyRange = <Your Range Specification>

For i = MyRange.Areas.Count To 1 Step -1
    MyRange.Areas(i).EntireRow.Delete
Next i

通过按降序使用 for 循环从最后一个(底部)到第一个区域,这一点很重要。这将避免由于先前的行被删除而导致要删除的行在向上移动后更改了编号的问题。

关于范围,我会避免使用AutoFilter. 即使它可以返回一个范围,这个功能似乎也没有很好的记录(参见 MSDN 页面)。出于这个原因和简单起见,我建议您这样定义范围:

Set MyRange = ActiveSheet.Range(ActiveSheet.Range("A2"), ActiveSheet.Cells.SpecialCells(xlCellTypeLastCell)).SpecialCells(xlVisible).EntireRow

请注意,重要的是在您制作工作表副本后立即包含此内容,以确保ActiveSheet引用正确的工作表。


推荐阅读