2015-10-18 47 views
0

下面的代码通过记录进行循环,并从每个记录的高级过滤器/计算中返回某些值。我有大约2000条记录需要它通过。问题是处理时间是10-15秒的记录,这太慢了。改进高级过滤器处理时间

Sub EquityAutomatedDallas() 
Dim Counter As Integer 
Dim LogNo As String 

Dim LogNoRange As Range 
Dim NoRange As Range 
Dim FilterRange As Range 
Dim FilterCriteriaRange As Range 
Dim ValueRange As Range 
Dim FullSortRange As Range 
Dim SortValueRange As Range 
Dim FullSortRangeValues 

Dim EquityRankRange As Range 
Dim EquityOutOfRange As Range 
Dim MedianRange As Range 
Dim PropertyValueRange As Range 
Dim DifferenceRange As Range 
Dim MinRange As Range 
Dim MaxRange As Range 
Dim AverageRange As Range 
Dim DallasRes As Worksheet 

Set LogNoRange = Worksheets("EquitySpreadsheet").Range("B10") 
Set NoRange = Worksheets("Dallas Res").Range("A10:A647649") 
Set FilterRange = Worksheets("Dallas Res").Range("A9:T647649") 
Set FilterCriteriaRange = Worksheets("Dallas Res").Range("A1:T2") 
Set ValueRange = Worksheets("Dallas Res").Range("T10:T647649") 
Set FullSortRange = Worksheets("Dallas Res").Range("A9:S647649") 
Set SortValueRange = Worksheets("Dallas Res").Range("T9") 
Set FullSortRangeValues = Worksheets("Dallas Res").Range("A10:T647649") 
Set DallasRes = Worksheets("Dallas Res") 

Set EquityRankRange = Worksheets("EquityList").Range("P5") 
Set EquityOutOfRange = Worksheets("EquityList").Range("P4") 
Set MedianRange = Worksheets("EquityList").Range("O6") 
Set PropertyValueRange = Worksheets("EquityList").Range("D5") 
Set DifferenceRange = Worksheets("EquityList").Range("O7") 
Set MinRange = Worksheets("EquityList").Range("O8") 
Set MaxRange = Worksheets("EquityList").Range("O9") 
Set AverageRange = Worksheets("EquityList").Range("O10") 

Application.ScreenUpdating = False 



For Counter = 558 To 565 
LogNo = Worksheets("Hirschy").Cells(1 + Counter, 1).Value 
LogNoRange = LogNo 
    NoRange.ClearContents 
    Application.Calculate 
     If Not Application.CalculationState = xlDone Then 
      DoEvents 
     End If 
    Application.Calculation = xlManual 
    FilterRange.AdvancedFilter Action:=xlFilterInPlace, CriteriaRange:=FilterCriteriaRange, Unique:=False 
    Application.Calculation = xlCalculationAutomatic 
    NoRange.SpecialCells(xlCellTypeVisible).FormulaR1C1 = "=Subtotal(3,R10C2:RC[1])" 
    ValueRange.SpecialCells(xlCellTypeVisible).Formula = "=INDEX(EquitySpreadsheet!$C$12:$GT$29,16,(MATCH(INDIRECT(ADDRESS(ROW(),1)),EquitySpreadsheet!$C$12:$GS$12)+1))" 
    DallasRes.Select 
    FullSortRange.Select 
    SortValueRange.Activate 
    ActiveWorkbook.Worksheets("Dallas Res").Sort.SortFields.Clear 
    ActiveWorkbook.Worksheets("Dallas Res").Sort.SortFields.Add Key:=ValueRange, SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal 
    With ActiveWorkbook.Worksheets("Dallas Res").Sort 
     .SetRange FullSortRangeValues 
     .Header = xlYes 
     .MatchCase = False 
     .Orientation = xlTopToBottom 
     .SortMethod = xlPinYin 
     .Apply 
    End With 
Worksheets("Dallas Res").Calculate 
Worksheets("EquitySpreadsheet").Calculate 
Worksheets("EquityList").Calculate 
Worksheets("Hirschy").Cells(1 + Counter, 6) = EquityRankRange 
Worksheets("Hirschy").Cells(1 + Counter, 7) = EquityOutOfRange 
Worksheets("Hirschy").Cells(1 + Counter, 8) = MedianRange 
Worksheets("Hirschy").Cells(1 + Counter, 9) = PropertyValueRange 
Worksheets("Hirschy").Cells(1 + Counter, 10) = DifferenceRange 
Worksheets("Hirschy").Cells(1 + Counter, 11) = MinRange 
Worksheets("Hirschy").Cells(1 + Counter, 12) = MaxRange 
Worksheets("Hirschy").Cells(1 + Counter, 13) = AverageRange 
Next Counter 
Application.ScreenUpdating = True 
End Sub 

有没有反正我可以加快这个宏?

+0

反正你可以发布工作簿?有了这样的问题,如果没有它,在你面前真的很难。 –

+0

如果您不需要**查看**每次迭代所做的更改,请将'ScreenUpdating'移到循环外部。避免'.Select','.Activate'。使用适当的变量来访问工作表和范围,并在访问同一对象的代码中使用'With ... End With'多次。如果可能,也使用命名范围。 – PatricK

+0

我接受了你的建议并清理了代码。请参阅上面的更新代码。还有什么我可以做的吗?它仍然需要约10秒的记录。 Excel英雄,不幸的是,我不能因为它太大。虽然我感谢你的帮助。 – Shawn007

回答

1

正如在评论解释,开启和关闭的计算循环内可能是不需要的,除非你有依赖于更新值

你的代码清理帮助其他计算,我清理了多一点,但可能会影响性能的主要变化是取消循环外部的计算切换

这是未经测试的,因此请确保最终获得预期值;如果它的工作原理可能使其更快

Sub EquityAutomatedDallas() 
    Dim i As Long, LogNoRng As Range 
    Dim wsHi As Worksheet:   Set wsHi = Worksheets("Hirschy") 
    Dim wsES As Worksheet:   Set wsES = Worksheets("EquitySpreadsheet") 
    Dim wsEL As Worksheet:   Set wsEL = Worksheets("EquityList") 
    Dim wsDa As Worksheet:   Set wsDa = Worksheets("Dallas Res") 
    Dim subTotalsDa As Range:  Set subTotalsDa = wsDa.Range("A10:A647649") 
    Dim fltrRng As Range:   Set fltrRng = wsDa.Range("A9:T647649") 
    Dim fltrCritRng As Range:  Set fltrCritRng = wsDa.Range("A1:T2") 
    Dim valRngDa As Range:   Set valRngDa = wsDa.Range("T10:T647649") 
    Dim fullSrtRng As Range:  Set fullSrtRng = wsDa.Range("A9:S647649") 
    Dim sortValRng As Range:  Set sortValRng = wsDa.Range("T9") 
    Dim fullSortRngVal As Range: Set fullSortRngVal = wsDa.Range("A10:T647649") 
    Dim equityRankRng As Range:  Set equityRankRng = wsEL.Range("P5") 
    Dim equityOutOfRng As Range: Set equityOutOfRng = wsEL.Range("P4") 
    Dim medianRng As Range:   Set medianRng = wsEL.Range("O6") 
    Dim propValRng As Range:  Set propValRng = wsEL.Range("D5") 
    Dim diffRng As Range:   Set diffRng = wsEL.Range("O7") 
    Dim minRng As Range:   Set minRng = wsEL.Range("O8") 
    Dim maxRng As Range:   Set maxRng = wsEL.Range("O9") 
    Dim avgRng As Range:   Set avgRng = wsEL.Range("O10") 

    xlEnableWB False 'Turns OFF everything, including automatic calculations 
    For i = 558 To 565 
     LogNoRng = wsHi.Cells(1 + i, 1).Value2 
     subTotalsDa.ClearContents 
     fltrRng.AdvancedFilter Action:=xlFilterInPlace, _ 
      CriteriaRange:=fltrCritRng, Unique:=False 
     subTotalsDa.SpecialCells(xlCellTypeVisible).FormulaR1C1 = _ 
      "=Subtotal(3,R10C2:RC[1])" 
     valRngDa.SpecialCells(xlCellTypeVisible).Formula = _ 
      "=INDEX(EquitySpreadsheet!$C$12:$GT$29,16,(MATCH(INDIRECT(ADDRESS(ROW(),1)),EquitySpreadsheet!$C$12:$GS$12)+1))" 
     With wsDa.Sort 
      .SortFields.Clear 
      .SortFields.Add Key:=valRngDa, SortOn:=xlSortOnValues, _ 
       Order:=xlAscending, DataOption:=xlSortNormal 
      .SetRng fullSortRngVal 
      .Header = xlYes 
      .MatchCase = False 
      .Orientation = xlTopToBottom 
      .Apply 
     End With 
     With wsHi 
      .Cells(1 + i, 6) = equityRankRng: .Cells(1 + i, 7) = equityOutOfRng 
      .Cells(1 + i, 8) = medianRng:  .Cells(1 + i, 9) = propValRng 
      .Cells(1 + i, 10) = diffRng:  .Cells(1 + i, 11) = minRng 
      .Cells(1 + i, 12) = maxRng:   .Cells(1 + i, 13) = avgRng 
     End With 
    Next 
    Application.Calculate 
    xlEnableWB True  'Turns ON everything, including automatic calculations 
End Sub 

功能打开和关闭Excel功能(屏幕,计算等)

Public Sub xlEnableWB(Optional ByVal opt As Boolean = True) 
    With Application 
     .Calculation = IIf(opt, xlCalculationAutomatic, xlCalculationManual) 
     .DisplayAlerts = opt 
     .DisplayStatusBar = opt 
     .EnableAnimations = opt 
     .EnableEvents = opt 
     .ScreenUpdating = opt 
    End With 
    xlEnableWS , opt 
End Sub 
Public Sub xlEnableWS(Optional ws As Worksheet = Nothing, Optional opt As Boolean = True) 
    If ws Is Nothing Then 
     For Each ws In Application.ActiveWorkbook.Sheets: EnableWS ws, opt: Next 
    Else 
     EnableWS ws, opt 
    End If 
End Sub 
Private Sub EnableWS(ByVal ws As Worksheet, ByVal opt As Boolean) 
    With ws 
     .DisplayPageBreaks = False 
     .EnableCalculation = opt 
     .EnableFormatConditionsCalculation = opt 
     .EnablePivotTable = opt 
    End With 
End Sub 
+0

我将纳入这些更改。但是,我无法关闭计算,因为这些值会从基于返回结果重新计算的网格中拉出。 – Shawn007

+0

计算仅在执行期间关闭;他们会重新开启,并在最后2行中重新计算整个工作表,结尾 –

+0

它会使用该代码一遍又一遍地将相同的值返回到单元格值。我认为这是因为我需要工作簿中的公式来运行(计算)每次循环。如果我需要通过循环每次刷新工作簿,是否有其他选择?我感谢您的帮助。 – Shawn007