VBA For循环迭代问题

时间:2016-09-14 12:28:32

标签: vba excel-vba for-loop excel

在下面的代码中,我试图检查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

3 个答案:

答案 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),然后在下方注明该行删除行

相关问题