For Each c In oSheet.Range("A1:A1000")
If InStr(c.Value, "VALUE") Then
c.EntireRow.Delete()
End If
Next
This will only delete a few of the rows within the specified range, what could the problem be?
For Each c In oSheet.Range("A1:A1000")
If InStr(c.Value, "VALUE") Then
c.EntireRow.Delete()
End If
Next
This will only delete a few of the rows within the specified range, what could the problem be?
Dont use loops, use a method such as
AutoFilter
Here are two common patterns for deleting entire rows based on a condition. The main idea is that you cannot delete from a collection while you iterate it. This means that
Delete
should not appear in aFor Each
This is fairly standard across most programming languages and some even throw an error to prevent it.Option 1, use an integer to track the rows and have it work from the end to the beginning. You need to go backwards because it is the easy way to avoid skipping rows. It is possible to go forwards, you just need to account for not incrementing when you delete.
Option 2, use the
Union-Delete
pattern to build a range of cells and then delete them all in one step at the end.Notes on the code
For Option 2, there is an extra conditional there to create
rng_delete
when it starts at the first item.Union
does not work with aNothing
reference, so we first check that and if so,Set
to the first item. All others come through and getSet
by theUnion
line.Preference
When choosing between the two, I always prefer Option 2 because I much prefer to work with
Ranges
in Excel instead of iterating throughCells
with a counter. There are limitations to this. The second option also works for discontinuousRanges
and all other variety of weirdRanges
(e.g. after a call toSpecialCells
) which can make it valuable when you are not sure what data you will be dealing with.Speed
I am not sure about a speed comparison. Both can be slow if
ScreenUpdating
and calculations are enabled. The first option makesN-1
calls toDelete
whereas the second option does a single one.Delete
is an expensive operation. Option 2 does however makeN-1
calls toUnion
andSet
. I assume it's faster than the first one based on that (and it seems to be here), but I did not profile it.Final note:
InStr
returns an integer indicating where the value was found. I always like to make the boolean covnersion explicit here and compare to>0
.