4

我有几个非常大的 excel 数据文件,我需要遍历它们并删除 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

4 回答 4

10

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

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

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

即使你不这样做,如果你想做一个for each删除东西的地方,颠倒顺序(从最后开始并向后工作)

于 2013-03-13T00:53:59.587 回答
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了循环,这通常会加快这样的速度!

于 2013-03-13T01:11:41.870 回答
2

如果您像数据库一样管理数据并希望从中删除特定行并且可以过滤它们,那么有一个技巧可以加快您的删除过程。与简单的循环过程相比,这非常快:

我比较了不同示例的时间(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)这里是范围解决方案(中间时间):

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

在这里,绿线将被排在最前面,一系列的绿色命中将被整体删除。这是我知道的最快的方法!:-)

我希望它会帮助别人!

最好的问候汤姆

于 2016-06-08T11:18:27.157 回答
0

我发现最快的方法是清除行数据(.clear)然后排序。例如,我想摆脱显示为“=========”的分页符

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("A1000000").End(xlUp).Row) 等。

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

如果您需要在完成之前将数据从行下方移动到上方,那么问题就变成了如何“删除”空行。:)

干杯, BJ

于 2015-11-06T22:20:34.837 回答