基本上我需要遍历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
答案 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