VBA宏快速删除行

时间:2013-03-13 00:47:05

标签: excel excel-vba optimization row vba

我有几个非常大的ex​​cel数据文件,我需要仔细检查它们并删除T列中单元格值为1的所有行。现在我的代码看起来像:

Sub test()
    Dim cell As Range

    For Each cell In Worksheets("Sheet1").Range("T5", "T900000")
        If cell.Value = 1 Then
            cell.EntireRow.Delete
        End If
    Next cell
End Sub

它似乎有效,但需要永远运行,我将不得不这样做很多次。有没有更好的方法来做到这一点,或者某种方式来优化我已经拥有的东西以使其运行得更快?

4 个答案:

答案 0 :(得分:9)

这不会像您想象的那样工作......当您在遍历它们时删除行时,最终会跳过行。示例:假设您的行在A列中的数字为1 ... 10.您查看第一行并决定删除它。现在你看第二行。它有3号!你从未看过第2行!!

更好的方法是根据列T的条件过滤电子表格,复制它,将其粘贴到新工作表(带格式等)。

您可以打开微距录制并手动执行此操作;那么你将拥有确切的VBA代码。我相信会更快。

即使你不这样做,如果你想要删除的东西for each,也要反转顺序(从最后开始向后工作)

答案 1 :(得分:3)

如果您想使用循环,则以下内容不应跳过项目。 我认为@Floris Filter方法可能会更快。

Sub Main()
    Dim Row As Long
    Dim Sheet As Worksheet
    Row = 5
    Set Sheet = Worksheets("Sheet1")
    Application.ScreenUpdating = False
    Do
        If Sheet.Cells(Row, 20).Value = 1 Then
            Sheet.Rows(Row).Delete xlShiftUp
        Else
            Row = Row + 1
        End If
    Loop While Row <= 900000
    Application.ScreenUpdating = True
End Sub

<强>更新 我已经在循环周围切换Application.ScreenUpdating,这通常会加速这样的事情!

答案 2 :(得分:1)

如果您像数据库一样管理数据并希望从中删除特定行并且可以对其进行过滤,则可以加快删除过程。与简单的循环过程相比,这是非常快的:

我比较不同例子的时间(4806行)。

  • 标准循环删除:2:25
  • 范围删除:0:20​​
  • 过滤器删除:0:01

示例:我在'Tabelle5'中有数据,想要删除特定的行。数据从第6行开始。第1列中以“OLD#”开头的每一行都应删除。

1)这里是标准解决方案(最长时间):

Dim i As Integer, counter As Integer
Dim strToRemove As String, strToRemoveRange As String
strToRemove = "OLD#"
strToRemoveRange = ""
counter = 0

With Tabelle5
    For i = .UsedRange.Rows.Count To 6 Step -1
        If Mid(.Cells(i, 1).value, 1, 4) = strToRemove Then
            .Rows(i).Delete Shift:=xlUp
        End If
    Next i
End With

2)这里是Range解决方案(中间时间):

Dim i As Integer, counter As Integer
Dim strToRemove As String, strToRemoveRange As String
strToRemove = "OLD#"
strToRemoveRange = ""
counter = 0

With Tabelle5
    For i = .UsedRange.Rows.Count To 6 Step -1
        If Mid(.Cells(i, 1).value, 1, 4) = strToRemove Then
            If strToRemoveRange = "" Then
                strToRemoveRange = CStr(i) & ":" & CStr(i)
            Else
                strToRemoveRange = strToRemoveRange & "," & CStr(i) & ":" & CStr(i)
            End If
            counter = counter + 1
        End If
        If counter Mod 25 = 0 Then
            If counter > 0 Then
                .Range(strToRemoveRange).Delete Shift:=xlUp
                strToRemoveRange = ""
                counter = 0
            End If
        End If
    Next i
    If Len(strToRemoveRange) > 0 Then
        '.Range(strToRemoveRange).Delete Shift:=xlUp
    End If
End With

3)过滤器溶液(最短时间):

Dim i As Integer, counter As Integer
Dim strToRemove As String, strToRemoveRange As String
strToRemove = "OLD#"
strToRemoveRange = ""
counter = 0

With Tabelle5
    For i = .UsedRange.Rows.Count To 6 Step -1
        If Mid(.Cells(i, 1).value, 1, 4) = strToRemove Then
            .Cells(i, 1).Interior.Color = RGB(0, 255, 0)
            counter = counter + 1
        End If
    Next i
    If counter > 0 Then
        .Rows("5:5").AutoFilter
        .AutoFilter.Sort.SortFields.Clear
        .AutoFilter.Sort.SortFields.Add( _
            Range("A5"), xlSortOnCellColor, xlAscending, , xlSortNormal).SortOnValue.Color = RGB(0, 255, 0)
        .AutoFilter.Sort.Header = xlYes
        .AutoFilter.Sort.MatchCase = False
        .AutoFilter.Sort.Orientation = xlTopToBottom
        .AutoFilter.Sort.SortMethod = xlPinYin
        .AutoFilter.Sort.Apply
        .Rows("6:" & CStr(counter + 5)).Delete Shift:=xlUp
        .Rows("5:5").AutoFilter
    End If
End With

此处绿线将排在顶部,绿色点击范围将作为整体删除。这是我所知道的最快的方式! : - )

我希望它会帮助别人!

祝你好运 汤姆

答案 3 :(得分:0)

我发现最快的方法是清除行数据(.clear)然后排序。 例如,我想摆脱显示为&#34; =========&#34;

I=20
Do While i <= lRow3
    If Left(Trim(ws3.Cells(i, 1)), 1) = "=" Then
        ws3.Range(Rows(i - 7), Rows(i + 2)).Clear
        'i = i - 7
        'lRow3 = lRow3 - 10
    End If
    i = i + 1
Loop

现在排序然后做一个xlUp的最后一行(ws3.Range(&#34; A1000000&#34;)。End(xlUp).Row)等。

删除行(在我的一个文件中,约为220,000行)需要3分钟。清除内容的时间不到10秒。

问题就变成了如何去除&#39;如果您需要在完成此操作之前将数据从行下方移动到上面的行,则为空行。 :)

干杯, BJ