简体   繁体   中英

Excel vba excessive run time, but no issues using step into

I have some code to delete duplicate rows while keeping the first instance the particular string appears.

When I step into the code to delete duplicates, the macro runs without a hitch. However, once I hit run macro, my excel freezes and stops responding. I'm not quite sure why...

If anyone could shed some light. That would be greatly appreciated. (Also I added a breakline to show where I attempt to run to).

Sub CleanUp()

Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual

Dim lastRow As Integer
Dim i As Integer, j As Integer, k As Integer
Dim stakedItem As String
Dim sortCell As Range, allCell As Range, sortcell2 As Range
Dim currentItem As String, baseItem As String

lastRow = Sheet2.Range("A" & Sheet2.Rows.Count).End(xlUp).Row
Set sortCell = Sheet2.Range("A1")
Set sortcell2 = Sheet2.Range("B1")
Set allCell = Sheet2.Range("A1:Z" & lastRow + 1)
baseItem = Sheet2.Range("B2")

allCell.Sort key1:=sortcell2, order1:=xlAscending, Header:=xlYes

For i = 3 To lastRow
    currentItem = Sheet2.Range("B" & i)
    If currentItem = baseItem Then
        Sheet2.Rows(i).Delete
        i = i - 1
        lastRow = lastRow - 1
    Else
        baseItem = Sheet2.Range("B" & i)
    End If
Next i

Breakline here...


allCell.AutoFilter field:=2, Criteria1:=Array("*G*", "*HUB*"), Operator:=xlFilterValues

allCell.Sort key1:=sortCell, order1:=xlAscending, Header:=xlYes

Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic


End Sub

Thank you!

Francis

This will never exit if it finds a row to delete. The reason is that in a For loop, the exit condition is fixed when that line of code evaluates. That means lastRow will always be whatever it was when you entered the loop.

This code illustrates:

Sub example()
    Dim x As Long, i As Long
    x = 5
    For i = 1 To x
        Debug.Print i  'This runs 5 times...
        x = 1          '...even though you change x here.
    Next
End Sub

So, the only thing lastRow = lastRow - 1 does is decrement the variable . After you've deleted the first row, you're guaranteed that at the end of the sheet that currentItem = BaseItem . And inside that condition, you decrement the loop counter, which gives you an infinite loop.

As @TimWilliams mentions in the comments, you should loop backward if you are deleting rows. Something like this:

For i = lastRow To 3 Step -1
    currentItem = Sheet2.Range("B" & i)
    If currentItem = BaseItem Then
        Sheet2.Rows(i).Delete
    Else
        BaseItem = Sheet2.Range("B" & i)
    End If
Next i

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM