Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
728 views
in Technique[技术] by (71.8m points)

excel - VBA Deleting rows with the Like operator

Simple thing is not simple. I am trying to delete rows based on a specific column having data that begins with "2L". So I wrote this code (LastRow is understood):

Sub Cleanup()

For i = 1 To LastRow
    If Range("F" & i) Like "2L*" Then Rows(i).delete
Next i
End Sub

The problem is that it does delete rows. I have no idea what it's criteria is for deleting rows but I know it does not get every row with a cell that starts with "2L" in that column as it was written. I start out with 1100 row and it goes down to 677.

I did not create the excel that I am scripting in. the only clue I have is that I did try to format the column and when the format window opens, they don't have a single type. I did try formatting the column of data before I ran the code to be Text but it did not seem to do the trick.

Thoughts?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

First, some mandetory house keeping.....

  1. Add Option Explicit
  2. Add Option Explicit
  3. Qualify all objects (Range) with a worksheet

You should avoid deleting rows as you loop for a few reasons. The main reason is that it can be highly inefficient. Say, for instance, that you have 500 cells that are Like "2L*". That means you will have 500 iterations of rows being deleted.

Instead, add every instance of Like "2L*" to a Union (collection) of cells and once your loop is complete, delete the entire Union all at once. Now you just have 1 instance of rows being deleted.

Another reason to avoid deleting rows inside your loop is that it forces you to loop backwards. There is nothing wrong with this, it just tends to give people a hard time since it is not intuitive at first. When you delete a row, you shift the range you are looping through up and this causes rows to be skipped. The method below does not need to be looped backwards.


Option Explicit

Sub Cleanup()

Dim ws As Worksheet: Set ws = ThisWorkbook.Sheets("???")
Dim i As Long, DeleteMe As Range

'Gather up union of CELLS like 2L*
For i = 1 To ws.Range("F" & ws.Rows.Count).End(xlUp).Row
    If ws.Range("F" & i) Like "2L*" Then
        If DeleteMe Is Nothing Then
            Set DeleteMe = ws.Range("F" & i)
        Else
            Set DeleteMe = Union(DeleteMe, ws.Range("F" & i))
        End If
    End If
Next i

'Delete collection of cells here (if any exist)
If Not DeleteMe Is Nothing Then DeleteMe.EntireRow.Delete

End Sub

For learning purposes, this is how you would loop backwards. It has less lines than the above method, but is less efficient. If you do decide to go this route, be sure to toggle off ScreenUpdating to speed things up

Sub CleanUp2()

Dim ws As Worksheet: Set ws = ThisWorkbook.Sheets("???")
Dim i As Long

For i = ws.Range("F" & ws.Rows.Count).End(xlUp).Row to 1 Step -1 '<===== Backwards!
    If ws.Range("F" & i) Like "2L*" Then ws.Rows(i).Delete
Next i

End Sub

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...