在下面的代码中,我试图检查2个日期值。如果存在,则计算BG列之间的天数。如果它们不存在或结果小于0则删除该行。
我遇到的问题是,一旦删除了一行,它就会使用Next I,并在它之后直接跳过该行。例如:第1行和第1行2个人错过了约会。第1行被删除。第2行被推到第1行,然后是第i行,所以我们现在在第2行(这是3)并跳过第2行的结果。使用i = i-1似乎会使我的程序崩溃。另外,还有什么方法可以使我的代码更有效率,以便它可以更快地遍历项目的数量吗?
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
答案 0 :(得分:0)
Comintern和Shai Rado在评论中回答了第一个问题:
始终反向循环浏览项目,因为从范围中删除项目会将剩余项目移回。通过反向循环,删除的项目不会影响其余项目。
第二个问题,为了加快速度,请阅读这篇博文:
https://blogs.office.com/2009/03/12/excel-vba-performance-coding-best-practices/
特别是下面的部分: 在单次操作中读/写大块单元
如果您在数组中处理数据,将数据读回写入数组,如本博客示例所示,它将更快。特别是有数以千计的物品,这将是非常重要的!
答案 1 :(得分:0)
要解决第一个问题,您可以反向运行循环。这样,删除只会移动已经迭代过的行。
typings
第二个问题有点开放。本指南提供了一些有关如何使代码更快的建议:
http://datapigtechnologies.com/blog/index.php/ten-things-you-can-do-to-speed-up-your-excel-vba-code/
指南中的一些项目对我来说最为突出,与您的代码相关。
将以下内容放在代码周围,特别是如果您预计会删除大量行。
For i = N To 2 Step -1
这最好通过阅读专栏" AB"和" AE"进入一个数组,并迭代它而不是工作表上的单元格。这是一个解决方案:
Fastest way to read a column of numbers into an array
Application.ScreenUpdating = False
Application.ScreenUpdating = True
答案 2 :(得分:-1)
将For i = 2 To N
更改为Do until i > N
,将Next i
更改为Loop
(不要事先忘记分配i = 2
),然后在下方注明该行删除行