3

I am looping through rows of a table and deleting rows if certain conditions are not met. For some reason my for loop never exits even when its done. What am I doing wrong?

lastr = Range("a2").End(xlDown).Row
For r = 2 To lastr
    If Cells(r, 1).Value <> "SHORT POSITIONS" And Cells(r, 7).Value = 0 And Cells(r, 10).Value <> "Yes" Then
        Rows(r).Delete
        r = r - 1
        lastr = lastr - 1
    End If
Next r
6
  • What's the value of lastr if you put a breakpoint a the For line? Commented Oct 27, 2015 at 12:48
  • 3
    Usually, when deleting rows if a for loop, it is easier to do i starting by the end: For r = lastr to 2 step -1. This way, you don't have to bother with r = r-1 and lastr = lastr -1 Commented Oct 27, 2015 at 12:51
  • How do I check what the value of lastr is ? I set the breakpoint Commented Oct 27, 2015 at 12:53
  • 1
    There is multiple ways. You can mouse over the name, look in the Local variables windows, set a spy, type ? lastrin the immediate window... Commented Oct 27, 2015 at 12:55
  • 2
    In a For... loop, the end value is saved when the For code is evaluated. If you run the code step by step, you will see that when reaching the Next, who go back to the line following the For, not the for itself. So you can't modify the end value inside the loop., the loop will run 123 times. Commented Oct 27, 2015 at 13:04

4 Answers 4

3

ALWAYS start at the bottom and work towards the top when deleting rows. Failing to work from the bottom to the top will result in skipped rows as the position of the rows are reset after the row deletion.

NEVER reset your counter in a For ... Next Statement. Changing r mucks things up. Changing lastr has no effect. It will still go to the lastr that was the original value when you entered the loop.

lastr = Range("a" & ROWS.COUNT).End(xlUP).Row
For r = lastr To 2 STEP -1   '<~~ VERY IMPORTANT
    If Cells(r, 1).Value <> "SHORT POSITIONS" And Cells(r, 7).Value = 0 And Cells(r, 10).Value <> "Yes" Then
        Rows(r).Delete
    End If
Next r

TYPICALLY, it is better to look for the last populated cell from the bottom up,

Sign up to request clarification or add additional context in comments.

Comments

0

if you want to loop and delete its best to mark the rows first and delete them at once or use an array.

lastr = Range("a2").End(xlDown).Row
dim DR() as long
dim c as long
For r = 2 To lastr
    If Cells(r, 1).Value <> "SHORT POSITIONS" And Cells(r, 7).Value = 0 And Cells(r, 10).Value <> "Yes" Then
        c = c +1
        redim preserve DR(c)
        dr(c-1) = R
    End If
Next r
'delete the rows one by one, or you could build a string and delete once.
For r = 0 to UBound(DR)
    Rows(dr(i).delete ' or entirerow delete 
next i

Comments

0

You are subtracting 1 from the loop variable, so it loops forever.

In Visual Basic for loops, "from" and "to" are calculated once at the beginning (they are fixed), but the loop variable is increased each time. So

For r = fromExp to toExp
  SomeCode()
End For

       behaves the same as

    Dim f = fromExp
    Dim t = toExp

    r = f

    While (r < t)
       SomeCode()
       r = r + 1
    End While

In your example, the code changes toExp

For r = fromExp to toExp
   toExp = toExp + 1
   r = r - 1
EndFor

       but that doesn't affect the loop:

    Dim f = fromExp
    Dim t = toExp

    r = f

    While (r < t)
       toExp = toExp + 1   // does not affect the loop
       r = r - 1
       r = r + 1           // r is unchanged
    End While

The loop variable is unchanged, so it loops forever.

Best practice: do not alter the loop variable within a For loop.

Comments

-1

Instead of using the variable for the loop (r), create a your own variable to track your position and update.

lastr = Range("a2").End(xlDown).Row
CurrentPosition = 2
For r = 2 To lastr
    If Cells(CurrentPosition, 1).Value <> "SHORT POSITIONS" And Cells(CurrentPosition, 7).Value = 0 And Cells(CurrentPosition,10).Value <> "Yes" Then
        Rows(CurrentPosition).Delete
        CurrentPosition = CurrentPosition - 1
    End If
    CurrentPosition = CurrentPosition + 1
Next r

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.