Performance 如果找到子字符串,如何加快代码查找和删除行的速度
下面的代码工作得很好,正如预期的那样。唯一的缺点是速度慢,因为我使用它搜索子字符串的所有实例,如果在整个工作簿的任何单元格中找到,则删除整行 目标很简单,如果在任何单元格字符串中找到输入的字符串,只需删除entirerow即可Performance 如果找到子字符串,如何加快代码查找和删除行的速度,performance,vba,excel,search,Performance,Vba,Excel,Search,下面的代码工作得很好,正如预期的那样。唯一的缺点是速度慢,因为我使用它搜索子字符串的所有实例,如果在整个工作簿的任何单元格中找到,则删除整行 目标很简单,如果在任何单元格字符串中找到输入的字符串,只需删除entirerow即可 Dim wo As Worksheet, ws As Worksheet Dim I As Long, j As Long, m As Long Dim toFind As String, testStr As String Dim pos As Long Dim lst
Dim wo As Worksheet, ws As Worksheet
Dim I As Long, j As Long, m As Long
Dim toFind As String, testStr As String
Dim pos As Long
Dim lstRow As Long, cutRow As Long
Dim WS_Count As Integer
Dim Cell As Range
Option Compare Text
Option Explicit
Sub SearchDelete()
toFind = InputBox("Enter the substring you want to search for.", "Welcome", "AAAA")
toFind = Trim(toFind)
j = 0
If toFind = "" Then
MsgBox "Empty String Entered.Exiting Sub Now."
Exit Sub
Else
WS_Count = ActiveWorkbook.Worksheets.Count
'Begin the loop.
For I = 1 To WS_Count
Label1:
For Each Cell In Worksheets(I).UsedRange.Cells
If Trim(Cell.Text) <> "" Then
pos = 0
pos = InStr(1, Trim(Cell.Text), toFind, vbTextCompare)
If pos > 0 Then 'match Found'
cutRow = Cell.Row
Worksheets(I).Rows(cutRow).EntireRow.Delete
j = j + 1
GoTo Label1
Else: End If
Else: End If
Next Cell
Next I
End If
MsgBox "Total " & j & " Rows were deleted!"
End Sub
Dim wo作为工作表,ws作为工作表
我一样长,j一样长,m一样长
Dim toFind作为字符串,testStr作为字符串
变暗位置尽可能长
变暗的一行一样长,剪切的一行一样长
Dim WS_计数为整数
暗淡单元格作为范围
选项比较文本
选项显式
子搜索删除()
toFind=InputBox(“输入要搜索的子字符串。”、“欢迎”、“AAAA”)
toFind=修剪(toFind)
j=0
如果toFind=“”,则
MsgBox“输入了空字符串。正在退出子项。”
出口接头
其他的
WS\u Count=ActiveWorkbook.Worksheets.Count
'开始循环。
对于I=1到WS\u计数
标签1:
对于工作表(I)中的每个单元格,请使用drange.Cells
如果Trim(Cell.Text)“,则
pos=0
pos=InStr(1,修剪(Cell.Text),toFind,vbTextCompare)
如果位置>0,则“找到匹配项”
cutRow=单元格。行
工作表(I).行(cutRow).EntireRow.Delete
j=j+1
后藤标签1
否则:如果
否则:如果
下一个细胞
接下来我
如果结束
MsgBox“总计”&j&“行已删除!”
端接头
问题的答案:“如果找到子字符串,如何加速此代码以查找和删除行”
是-在找到并删除行后,不要从工作表顶部重复搜索 单个操作通常比大容量操作慢得多,并且也不例外。使用a收集匹配行,然后整体执行删除操作将显著加快操作速度
Option Explicit
Option Compare Text
Sub searchDelete()
Dim n As Long, w As Long
Dim toFind As String, addr As String
Dim fnd As Range, rng As Range
toFind = InputBox("Enter the substring you want to search for.", "Welcome", "AAAA")
toFind = Trim(toFind)
If Not CBool(Len(toFind)) Then
MsgBox "Empty String Entered.Exiting Sub Now."
GoTo bm_Safe_Exit
End If
'appTGGL bTGGL:=False 'uncomment this line when you have finsihed debugging
With ActiveWorkbook
For w = 1 To .Worksheets.Count
With .Worksheets(w)
Set fnd = .Cells.Find(what:=toFind, lookat:=xlPart, _
after:=.Cells.SpecialCells(xlCellTypeLastCell))
If Not fnd Is Nothing Then
Set rng = .Rows(fnd.Row)
n = n + 1
addr = fnd.Address
Do
If Intersect(fnd, rng) Is Nothing Then
n = n + 1
Set rng = Union(rng, .Rows(fnd.Row))
End If
Set fnd = .Cells.FindNext(after:=fnd)
Loop Until addr = fnd.Address
Debug.Print rng.Address(0, 0)
rng.Rows.EntireRow.Delete
End If
End With
Next w
End With
Debug.Print "Total " & n & " rows were deleted!"
bm_Safe_Exit:
appTGGL
End Sub
Public Sub appTGGL(Optional bTGGL As Boolean = True)
Application.ScreenUpdating = bTGGL
Application.EnableEvents = bTGGL
Application.DisplayAlerts = bTGGL
Application.Calculation = IIf(bTGGL, xlCalculationAutomatic, xlCalculationManual)
Debug.Print Timer
End Sub
暂时挂起某些应用程序环境处理程序也会有所帮助。删除行时不需要激活;只有在您完成操作之后
Option Explicit
Option Compare Text
Sub searchDelete()
Dim n As Long, w As Long
Dim toFind As String, addr As String
Dim fnd As Range, rng As Range
toFind = InputBox("Enter the substring you want to search for.", "Welcome", "AAAA")
toFind = Trim(toFind)
If Not CBool(Len(toFind)) Then
MsgBox "Empty String Entered.Exiting Sub Now."
GoTo bm_Safe_Exit
End If
'appTGGL bTGGL:=False 'uncomment this line when you have finsihed debugging
With ActiveWorkbook
For w = 1 To .Worksheets.Count
With .Worksheets(w)
Set fnd = .Cells.Find(what:=toFind, lookat:=xlPart, _
after:=.Cells.SpecialCells(xlCellTypeLastCell))
If Not fnd Is Nothing Then
Set rng = .Rows(fnd.Row)
n = n + 1
addr = fnd.Address
Do
If Intersect(fnd, rng) Is Nothing Then
n = n + 1
Set rng = Union(rng, .Rows(fnd.Row))
End If
Set fnd = .Cells.FindNext(after:=fnd)
Loop Until addr = fnd.Address
Debug.Print rng.Address(0, 0)
rng.Rows.EntireRow.Delete
End If
End With
Next w
End With
Debug.Print "Total " & n & " rows were deleted!"
bm_Safe_Exit:
appTGGL
End Sub
Public Sub appTGGL(Optional bTGGL As Boolean = True)
Application.ScreenUpdating = bTGGL
Application.EnableEvents = bTGGL
Application.DisplayAlerts = bTGGL
Application.Calculation = IIf(bTGGL, xlCalculationAutomatic, xlCalculationManual)
Debug.Print Timer
End Sub
尝试
范围。是否查找?编辑:但这可能更适合于代码审查。一个非常简单的速度提升是在sub的开始处使用Application.ScreenUpdate=False
,在sub的结尾处使用Application.ScreenUpdate=True
。这只会在sub的结尾处更新屏幕,而不是每次删除一个行。@findwindow我会这样做,但我不知道Range.Find
是否会返回找到的部分匹配的所有行号,以及如何在循环中使用它?在这种情况下,任何实现的示例都将帮助我,谢谢!这里有range.findnext
@newguyrange.Find
将找到您搜索的任何内容的第一个实例Range.FindNext
将返回下一个匹配的单元格,并继续执行此操作,直到该区域中没有更多的单元格与搜索匹配为止,此时它将返回Nothing
Yes我知道为此我引入了一个Goto
语句,该语句基本上会在删除后再次重复此过程。您知道如何为每个单元格反向循环?因为我没有。伙计,现在你让我重新思考我的建筑。如果您正在搜索的字符串都紧密地分组在一起(在6000行的工作表中,彼此之间的行数不超过40行),该怎么办。使用findnext
会更快吗?或者你可以只find
然后从该行向前循环吗?@findwindow-我不确定如何确定包含子字符串的字符串被分组在一起,但假设它们正在缩小要查看的行,则会加快速度。然而,这导致了一种可能性,即简单地确定较小的区域可能需要与简单循环相同或更多的计算。e、 g.find(正向)然后find(反向)是否比find和FindNext更快地确定进一步FindNext的“缩小”范围?如果没有更多的处理,看起来是一样的。它本质上是一个数字顺序的列表,每个ID都分组在块中,所以一旦我找到第一个匹配项,我知道其余的都在下面的行中。它正试图确定驱动体系结构的区域(范围)。它实际上更复杂,因为每个ID块可能需要划分。听起来我的建筑足够好了^ u^;谢谢