.find vba慢慢跑

时间:2016-11-09 16:19:18

标签: excel vba

基本上我需要遍历1,566行并为每一行执行.find并与10,691行进行比较。问题是,我将三个值连接在一起以获得我的搜索值。它工作得很慢,所以我试着按照10,691上的第一个值进行过滤,这样它的工作速度会更快 - 但没有快乐!我正在使用一些函数,字母检索列的字母。

Option Explicit

Sub validate()
Dim gbe As Worksheet, mp As Worksheet, PnS As Worksheet
Dim rng As Range, Frng As Range
Dim ITC, TT, BC, y, GCell, sz, t, vList

t = Timer
OptimizeVBA True
ShDel ("Garbage"): Sheets.Add.name = "Garbage": Set gbe = Sheets("Garbage"): Set mp = Sheets("Master"): Set PnS = Sheets("PS")


    ITC = Letter(PnS, "Code"): TT = Letter(PnS, "Type"): BC = Letter(PnS, "BCode")
    mp.Range("M2:O" & mp.Range("A1").SpecialCells(xlCellTypeLastCell).Row).ClearContents
    PnS.Range((ITC & ":" & ITC & "," & TT & ":" & TT & "," & BC & ":" & BC)).Copy Destination:=gbe.Range("A1")
    gbe.Range("$A$1:$C$" & PnS.Range("A1").SpecialCells(xlCellTypeLastCell).Row).RemoveDuplicates Columns:=Array(1, 2, 3), _
        Header:=xlYes

        gbe.Range("A1:C" & gbe.Range("A1").End(xlDown).Row).AutoFilter
        gbe.Range("A1:C" & gbe.Range("A1").End(xlDown).Row).AutoFilter Field:=1, Criteria1:="='", _
            Operator:=xlOr, Criteria2:="='FC"
        gbe.rows("2:" & gbe.Range("A1").End(xlDown).Row).EntireRow.Delete
        gbe.Range("A1:C" & gbe.Range("A1").End(xlDown).Row).AutoFilter

        Set rng = gbe.Range("A2:A" & gbe.Range("A1").SpecialCells(xlCellTypeLastCell).Row)
        For Each y In rng
        mp.Range("A1:K" & gbe.Range("A1").End(xlDown).Row).AutoFilter Field:=3, Criteria1:="=" & y
        With mp.Range("A2:A" & mp.Range("A1").SpecialCells(xlCellTypeLastCell).Row).SpecialCells(xlCellTypeVisible)
        Set GCell = .Find(What:=sz, LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByColumns, SearchDirection:=xlNext, MatchCase:=True)
            If GCell Is Nothing Then
                mp.Range("O100000").End(xlUp) = PnS.Range(ITC & y.Row)
                mp.Range("O100000").End(xlUp).Offset(0, 1) = PnS.Range(TT & y.Row)
                mp.Range("O100000").End(xlUp).Offset(0, 2) = PnS.Range(BC & y.Row)
            End If
            Set GCell = Nothing
            mp.ShowAllData
        End With

        Next y

    ShDel ("Garbage")

OptimizeVBA False
MsgBox Timer - t

End Sub

1 个答案:

答案 0 :(得分:2)

在Excel工作表上执行操作的常见建议是在执行代码时以编程方式停用某些设置。

这是我在许多项目中使用的一小段代码:

Public Sub ExcelDefaultSettings(ByVal isActive As Boolean)

    With Application
        .ScreenUpdating = isActive
        .DisplayAlerts = isActive
        If isActive Then
            .Calculation = xlCalculationAutomatic
        Else
            .Calculation = xlCalculationManual
        End If
    End With

End Sub

然后你会在执行之前和之后进行这两个调用:

ExcelDefaultSettings isActive:=False  'Before

ExcelDefaultSettings isActive:=True  'After

它不是一个完美的解决方案,但它可以在更大的项目中提供巨大的帮助。

正如@Kyle和@Ralph所说,重构代码也可能有助于提高执行速度。

另一个常见建议是:1)将范围的内容转换为数组,2)仅在数组上执行操作,然后3)将数组转换回您的范围。

这比添加一些代码更复杂,但可以找到关于它的一个很好的解释{。{3}}。

这是他们为基本循环提供的示例:

Dim Arr() As Variant
Arr = Range("A1:B10")
Dim R As Long
Dim C As Long
For R = 1 To UBound(Arr, 1) ' First array dimension is rows.
    For C = 1 To UBound(Arr, 2) ' Second array dimension is columns.
        Debug.Print Arr(R, C)
    Next C
Next R