【问题标题】:Takes 4+ hours to delete 600k rows [duplicate]删除 600k 行需要 4 个多小时 [重复]
【发布时间】:2018-10-21 15:33:25
【问题描述】:

下面的代码需要 4 个多小时才能从我的工作簿中删除 600,000 行。我需要我的代码花费更少的时间来删除相同数量的数据。

Sub Loop_Example()
    Dim Firstrow As Long, Lastrow As Long, Lrow As Long
    Dim CalcMode As Long, ViewMode As Long
    With Application
        CalcMode = .Calculation
        .Calculation = xlCalculationManual
        .ScreenUpdating = False
    End With
    With ActiveSheet
        .Select 'select sheet so we can change the window view
        ViewMode = ActiveWindow.View 'go to normal view, for speed
        ActiveWindow.View = xlNormalView
        .DisplayPageBreaks = False 'Turn off Page Breaks
        Firstrow = .UsedRange.Cells(1).Row  'Set first & last row
        Lastrow = .UsedRange.Rows(.UsedRange.Rows.Count).Row
        For Lrow = Lastrow To Firstrow Step -1  'loop bottom to top
            With .Cells(Lrow, "A")
                If Not IsError(.Value) Then
                    Select Case .Value
                        Case Is <> "jelle", "ron", "dave": .EntireRow.Delete
                    End Select
                End If
            End With
        Next Lrow
    End With
    ActiveWindow.View = ViewMode
    With Application
        .ScreenUpdating = True
        .Calculation = CalcMode
    End With
End Sub

【问题讨论】:

  • 您是否尝试过基准测试delete multiple rows at the same time。例如,在最后一个空列中标记 X,按列中的 X 值过滤,突出显示行并单击 DEL。这样做会明显更快吗?
  • 你想知道为什么你删除了 600k 行,但处理现在空的工作表仍然需要很长时间吗?如果是这样,那是因为 Excel 仅在您保存文件时截断 UsedRange
  • 我是 VBA 新手。我看过一些网站并复制了这段代码。我需要使用 vba 删除大量数据。我不确定它在哪里需要这么长时间。请帮帮我。
  • 我遇到了同样的问题,Excel 最消耗的操作是删除。我最终做的实际上是将所有需要的数据保存在一个数组中,然后将数组复制到一个新的工作表中——速度更快。
  • 为什么要检查该值是否错误?如果该值为“jelle”、“ron”或“dave”,则表明该单元格不是错误。这只是一个不需要的额外步骤。

标签: excel vba delete-row


【解决方案1】:

尝试在循环期间构建一个范围(使用Union),然后在循环之后一次删除该范围内的所有行。未经测试,但类似:

Sub Loop_Example()
    Dim Firstrow As Long
    Dim Lastrow As Long
    Dim Lrow As Long
    Dim CalcMode As Long
    Dim ViewMode As Long

    With Application
        CalcMode = .Calculation
        .Calculation = xlCalculationManual
        .ScreenUpdating = False
    End With

    'We use the ActiveSheet but you can replace this with
    'Sheets("MySheet")if you want
    With ActiveSheet

        'We select the sheet so we can change the window view
        .Select

        'If you are in Page Break Preview Or Page Layout view go
        'back to normal view, we do this for speed
        ViewMode = ActiveWindow.View
        ActiveWindow.View = xlNormalView

        'Turn off Page Breaks, we do this for speed
        .DisplayPageBreaks = False

        'Set the first and last row to loop through
        Firstrow = .UsedRange.Cells(1).Row
        Lastrow = .UsedRange.Rows(.UsedRange.Rows.Count).Row

        Dim rowsToDelete As Range

        'We loop from Lastrow to Firstrow (bottom to top)
        For Lrow = Lastrow To Firstrow Step -1

            'We check the values in the A column in this example
            With .Cells(Lrow, "A")
                If Not IsError(.Value) Then
                    Select Case .Value
                        Case Is <> "jelle", "ron", "dave"
                        If Not (rowsToDelete Is Nothing) Then
                            Set rowsToDelete = Application.Union(rowsToDelete, .EntireRow)
                        Else
                            Set rowsToDelete = .EntireRow
                        End If
                    End Select
                End If
            End With
        Next Lrow
    End With

    rowsToDelete.EntireRow.Delete

    ActiveWindow.View = ViewMode
    With Application
        .ScreenUpdating = True
        .Calculation = CalcMode
    End With
End Sub

为了加快速度,可以做的另一件事是将 A 列(您正在检查/比较的)中的单元格读入一个数组——然后循环遍历数组本身,而不是进行 600k 次调用到工作表。在遍历数组时,您将使用Union 构建一个范围,然后在最后一次调用中删除该范围。

【讨论】:

  • 嗨,chillin..,它正在挂起我的系统。
猜你喜欢
  • 2018-12-07
  • 2020-05-09
  • 1970-01-01
  • 2021-05-20
  • 1970-01-01
  • 1970-01-01
  • 2021-06-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多