【问题标题】:Removing duplicates in a for loop crashes Excel在 for 循环中删除重复项会使 Excel 崩溃
【发布时间】:2020-11-21 15:56:48
【问题描述】:

我有一个 for next 循环,它运行了几十万行,对大部分内容进行了更改。数组可以让这段代码运行得更快吗?

我的 for 循环示例。有时它会超载并使 Excel 崩溃。 (仅供参考,我的循环必须从下到上运行才能达到预期目的。)

Sub RemoveDuplicates()

Dim shWorkBook As Worksheet
Dim wkb As Workbook
Dim FullYearData As Worksheet
Set wkb = ThisWorkbook

With wkb
    Set shWorkBook = .Sheets("Workbook")
    Set shFullYearData = .Sheets("FullYearData")
End With

Dim i As Long
Dim LastRowW As Long

On Error Resume Next

Call TurnOffCalc

FirstRowW = shWorkBook.Cells(1, 1).Row
FirstColW = shWorkBook.Cells(1, 1).Column
LastRowW = shWorkBook.Cells(Rows.Count, 1).End(xlUp).Row
LastColW = shWorkBook.Cells(2, Columns.Count).End(xlToLeft).Column

i = LastRowW

Sum = 0
shWorkBook.Activate

For i = LastRowW To 1 Step -1
    If shWorkBook.Cells(i, 7) = shWorkBook.Cells(i - 1, 7) Then
        shWorkBook.Cells(i, 26) = vbNullString
    End If
    
    If shWorkBook.Cells(i, 26).Value <> "" Then
        shWorkBook.Cells(i, 27) = Sum + Cells(i, 25).Value
        Sum = 0
    ElseIf shWorkBook.Cells(i, 26).Value = "" Then

        Sum = shWorkBook.Cells(i, 25).Value + Sum
    End If
Next

p = FirstRowW + 1
For p = FirstRowW + 1 To LastRowW Step 1
    shWorkBook.Cells(p, 28) = Application.WeekNum(shWorkBook.Cells(p, 3))
Next

shWorkBook.Cells(1, 28).Value = "Week Number"
Call TurnOnCalc
 
End Sub

【问题讨论】:

  • 好的,这里有很多事情要做,所以我首先将Option Explicit 添加到模块顶部并正确声明所有变量。 FirstRowW 和 FirstColW 的用途是什么?这些总是1。然后你去制作p = FirstRowW + 1,它总是2,然后在下一行将它用作迭代(所以这是没有意义的)。 shFullYearData 有什么意义?我没有看到它在任何地方使用。最后,您需要删除 On Error Resume Next 以查看您是否真的遇到错误,而不是 Excel 只是“过载和崩溃”。
  • 你需要清楚——有一次你说你想使用一个数组来让你的代码更快,但是你声称你的代码根本不起作用?如果您的代码甚至无法编译/运行,为什么还要担心速度?
  • 所以代码确实有效,只是在运行整个数据集时需要很长时间,所以我想看看是否有一种方法可以更有效地完成我的 for next 循环所做的事情。 shFullYearData 是工作簿中的另一张表,我想在那里没有任何目的
  • 为什么不在你的循环中移动shWorkBook.Cells(p, 28) = Application.WeekNum(shWorkBook.Cells(p, 3))而只使用i而不是p?除非这些单元格是基于您的第一个循环的结果的公式?

标签: arrays excel vba for-loop


【解决方案1】:

试试这样的:

Sub RemoveDuplicates()

    Dim shWorkBook As Worksheet
    Dim wkb As Workbook
    Dim FullYearData As Worksheet
    Dim i As Long, Sum
    Dim LastRowW As Long, LastColW As Long, tbl As Range, data
    
    
    Set wkb = ThisWorkbook
    With wkb
        Set shWorkBook = .Sheets("Workbook")
        'Set shFullYearData = .Sheets("FullYearData")
    End With
    
    LastRowW = shWorkBook.Cells(Rows.Count, 1).End(xlUp).Row
    LastColW = shWorkBook.Cells(2, Columns.Count).End(xlToLeft).Column
    
    Set tbl = shWorkBook.Range("A1").Resize(LastRowW, 28) 'include "Week number" (?)
    data = tbl.Value 'get the range value as an array
    data(1, 28) = "Week Number"

    Sum = 0
    For i = LastRowW To 1 Step -1
        
        If data(i, 7) = data(i - 1, 7) Then data(i, 26) = vbNullString
        
        If data(i, 26).Value <> "" Then
            data(i, 27) = Sum + data(i, 25).Value
            Sum = 0
        Else
            Sum = data(i, 25).Value + Sum
        End If
        
        If i > 1 Then data(i, 28) = CLng(Format(data(i, 3), "ww"))
        
    Next

    tbl.Value = data 'return the data

End Sub

【讨论】:

  • 快速提问,当使用这个宏时,它粘贴的一列包括邮政编码,有时有前导 0 的数组不记录(例如,邮政编码 01234 将被粘贴为 1234)你知道吗?我可以防止这种情况发生吗?
  • 这些单元格是否格式化为文本?一种方法是确保所有值都以 ' 开头(单引号)
  • 我没有看到这种行为 - 任何带有前导零的东西在将范围值分配给数组然后将数组分配回原始范围后仍然具有零。
猜你喜欢
  • 2019-03-14
  • 1970-01-01
  • 2023-01-25
  • 2017-04-17
  • 1970-01-01
  • 2013-09-26
  • 2021-11-27
  • 2014-06-28
  • 1970-01-01
相关资源
最近更新 更多