Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance 如果找到子字符串,如何加快代码查找和删除行的速度_Performance_Vba_Excel_Search - Fatal编程技术网

Performance 如果找到子字符串,如何加快代码查找和删除行的速度

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

下面的代码工作得很好,正如预期的那样。唯一的缺点是速度慢,因为我使用它搜索子字符串的所有实例,如果在整个工作簿的任何单元格中找到,则删除整行

目标很简单,如果在任何单元格字符串中找到输入的字符串,只需删除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 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
@newguy
range.Find
将找到您搜索的任何内容的第一个实例
Range.FindNext
将返回下一个匹配的单元格,并继续执行此操作,直到该区域中没有更多的单元格与搜索匹配为止,此时它将返回
Nothing
Yes我知道为此我引入了一个
Goto
语句,该语句基本上会在删除后再次重复此过程。您知道如何为每个单元格反向循环
?因为我没有。伙计,现在你让我重新思考我的建筑。如果您正在搜索的字符串都紧密地分组在一起(在6000行的工作表中,彼此之间的行数不超过40行),该怎么办。使用
findnext
会更快吗?或者你可以只
find
然后从该行向前循环吗?@findwindow-我不确定如何确定包含子字符串的字符串被分组在一起,但假设它们正在缩小要查看的行,则会加快速度。然而,这导致了一种可能性,即简单地确定较小的区域可能需要与简单循环相同或更多的计算。e、 g.find(正向)然后find(反向)是否比find和FindNext更快地确定进一步FindNext的“缩小”范围?如果没有更多的处理,看起来是一样的。它本质上是一个数字顺序的列表,每个ID都分组在块中,所以一旦我找到第一个匹配项,我知道其余的都在下面的行中。它正试图确定驱动体系结构的区域(范围)。它实际上更复杂,因为每个ID块可能需要划分。听起来我的建筑足够好了^ u^;谢谢