循环迭代问题的VBA
在下面的代码中,我尝试检查2个日期值。如果存在,请计算BG列中的间隔天数。如果它们不存在或结果小于0,则删除该行 我遇到的问题是,一旦它删除了一行,它就会使用Next I,并直接跳过该行后面的内容。例:第1行和第2行缺少日期。第1行被删除。第2行被推到第1行。接下来是我,我们现在在第2行(第3行),跳过第2行的结果。使用i=i-1似乎会使我的程序崩溃。还有,有没有进一步的方法来提高我的代码的效率,使它能够更快地遍历大量的项目循环迭代问题的VBA,vba,excel,for-loop,Vba,Excel,For Loop,在下面的代码中,我尝试检查2个日期值。如果存在,请计算BG列中的间隔天数。如果它们不存在或结果小于0,则删除该行 我遇到的问题是,一旦它删除了一行,它就会使用Next I,并直接跳过该行后面的内容。例:第1行和第2行缺少日期。第1行被删除。第2行被推到第1行。接下来是我,我们现在在第2行(第3行),跳过第2行的结果。使用i=i-1似乎会使我的程序崩溃。还有,有没有进一步的方法来提高我的代码的效率,使它能够更快地遍历大量的项目 Sub Func4() Dim N As Long, i As Lo
Sub Func4()
Dim N As Long, i As Long, j As Long, cnt As Long, date1 As Date, date2 As Date, date3 As Long ', iold As Long
N = Cells(Rows.Count, "A").End(xlUp).Row
j = 2
cnt = 0
For i = 2 To N 'main
j = j + 1
'iold = i
If Not IsEmpty(Cells(i, "AB").Value) And Not IsEmpty(Cells(i, "AE").Value) Then
date1 = Cells(i, "AB").Value 'AB=Entry Date
date2 = Cells(i, "AE").Value 'AE=Rec'd
date3 = Work_Days(date2, date1)
cnt = cnt + 1
If date3 >= 0 Then
Cells(i, "BG").Value = date3
Else
Rows(i).EntireRow.Delete
'i = i - 1 'HERE
End If
Else
Rows(i).EntireRow.Delete
'i = i - 1 'HERE
End If
'End If
'If i = iold Then
Next i
'Else
'Next
'End If
End Sub
答复:
Sub Func4()
Dim N As Long, i As Long, j As Long, cnt As Long, date1 As Date, date2 As Date, date3 As Long
N = Cells(Rows.Count, "A").End(xlUp).Row
j = 2
For i = N To 2 Step -1
j = j + 1
If Not IsEmpty(Cells(i, "AB").Value) And Not IsEmpty(Cells(i, "AE").Value) Then
date1 = Cells(i, "AB").Value 'AB=Entry Date
date2 = Cells(i, "AE").Value 'AE=Rec'd
date3 = Work_Days(date2, date1)
cnt = cnt + 1
If date3 >= 0 Then
Cells(i, "BG").Value = date3
Else
Rows(i).EntireRow.Delete
End If
Else
Rows(i).EntireRow.Delete
End If
Next i
End Sub
将i=2的
改为N
改为直到i>N
为止,并将下一个i
改为循环
(不要忘记事先指定i=2
),然后对删除行下方的行进行注释共产国际和Shai Rado在注释中回答了第一个问题:
始终反向循环项目,因为从范围中删除项目会将其余项目移回。通过反向循环,已删除的项目不会影响剩余的项目
第二个问题,为了加快速度,请阅读以下博文:
特别是以下部分:
在一次操作中读取/写入大块单元
如果您以数组的形式处理数据,并将数据读写到数组中(如本博客中的示例所示),那么速度会快得多。特别是对于成千上万的物品,这将是非常重要的 要解决第一个问题,可以反向运行循环。这样,删除只会移动已经迭代过的行
For i = N To 2 Step -1
第二个问题有点不确定。本指南对如何加快代码速度提出了一些建议:
本指南中与您的代码相关的几个项目对我来说最为突出
- “禁用工作表屏幕更新”
Application.ScreenUpdating = False
Application.ScreenUpdating = True
- “避免过度访问工作表”
如果要删除行,则需要向后循环。如Comintern对i=N到2步骤1所说的
,谢谢你的提示!我从来没有这样想过。我似乎已经让它工作完美!请提交您的简单回答作为答案,我将奖励您分数!关键是,删除循环中的行会移动项目,导致您“错过”某些迭代。从循环项目列表中删除项目时,始终反向循环。我同意,在几乎所有情况下,您都应该反向循环,但并不总是-存在某些例外情况确保始终存在例外情况,但最佳做法是-在VBA中,从您迭代的集合中删除项目时,读取到始终-反向循环。请相信我,这是人们开始开发Office对象模型时犯的最大错误之一。所以,要小心教导刚起步的Office开发人员不要这样做
Dim Ar as Variant
Ar = Sheets("Sheet").Range("A1:A10000").Value