【问题标题】:Excel-VBA-Query Is there a way to improve Excel VBA speed with a Refresh.All with a lot of query?Excel-VBA-Query 有没有办法通过 Refresh.All 来提高 Excel VBA 的速度?
【发布时间】:2021-08-18 08:51:24
【问题描述】:

我有一个标签和几个数据透视表。一切正常,但现在因为我在选项卡中添加了 vlookup 以及一些公式,它使文件非常慢。 请注意,我与 ODBC 和 SQL 建立了连接,可以提取 30,000 行和 32 列的数据。

有什么方法可以提高性能吗?

我试过了: 取消选中后台更新 添加了等待查询

它仍然很慢...大约需要 15 分钟才能完成并打开!任何有助于减少这种情况的帮助将不胜感激!

谢谢,

Private Sub Workbook_Open()

Application.ScreenUpdating = False
Application.DisplayStatusBar = False
ActiveSheet.DisplayPageBreaks = False
Application.Calculation = xlCalculationManual
Application.EnableEvents = False

DoEvents

ActiveWorkbook.RefreshAll
Application.CalculateUntilAsyncQueriesDone
If Not Application.CalculationState = xlDone Then
DoEvents
End If
DoEvents

    Range("A3:P3").Select
    Sheets("FRQ-4").Select
     Range("A6").Select
    With ActiveSheet.PivotTables("Tableau croisé dynamique1").PivotFields("STATUT")
        .PivotItems("INACTIF").Visible = False
        .PivotItems("(blank)").Visible = False
    End With
    ActiveSheet.Range("$A$3:$P$385").AutoFilter Field:=14, Criteria1:="=1", _
    Operator:=xlOr, Criteria2:="=BESOIN-ACHAT " & Chr(10) & "1=OUI 0=NON"

    DoEvents
    Range("A3:P3").Select
    Sheets("FRQ-3").Select
        With ActiveSheet.PivotTables("Tableau croisé dynamique1").PivotFields("STATUT")
        .PivotItems("INACTIF").Visible = False
        .PivotItems("(blank)").Visible = False
    End With
    ActiveSheet.Range("$A$3:$P$385").AutoFilter Field:=14, Criteria1:="=1", _
    Operator:=xlOr, Criteria2:="=BESOIN-ACHAT " & Chr(10) & "1=OUI 0=NON"
        Range("A6").Select


    DoEvents
    Range("A3:P3").Select
    Sheets("FRQ-2").Select
        With ActiveSheet.PivotTables("Tableau croisé dynamique1").PivotFields("STATUT")
        .PivotItems("INACTIF").Visible = False
        .PivotItems("(blank)").Visible = False
    End With
    ActiveSheet.Range("$A$3:$P$385").AutoFilter Field:=14, Criteria1:="=1", _
    Operator:=xlOr, Criteria2:="=BESOIN-ACHAT " & Chr(10) & "1=OUI 0=NON"
        Range("A6").Select


    DoEvents
    Range("A3:P3").Select
    Sheets("FRQ-1").Select
        With ActiveSheet.PivotTables("Tableau croisé dynamique1").PivotFields("STATUT")
        .PivotItems("INACTIF").Visible = False
        .PivotItems("(blank)").Visible = False
    End With
    ActiveSheet.Range("$A$3:$P$385").AutoFilter Field:=14, Criteria1:="=1", _
    Operator:=xlOr, Criteria2:="=BESOIN-ACHAT " & Chr(10) & "1=OUI 0=NON"
        Range("A6").Select
    
    Sheets("FRQ-4").Select
    With ActiveSheet.Columns("E:S")
      .HorizontalAlignment = xlCenter
    End With
    With ActiveSheet.Columns("A:D")
        .HorizontalAlignment = xlLeft
    End With

    Sheets("FRQ-3").Select
    With ActiveSheet.Columns("E:S")
      .HorizontalAlignment = xlCenter
    End With
    With ActiveSheet.Columns("A:D")
        .HorizontalAlignment = xlLeft
    End With
    
    Sheets("FRQ-2").Select
    With ActiveSheet.Columns("E:S")
      .HorizontalAlignment = xlCenter
    End With
    With ActiveSheet.Columns("A:D")
        .HorizontalAlignment = xlLeft
    End With
    
    Sheets("FRQ-1").Select
    With ActiveSheet.Columns("E:S")
      .HorizontalAlignment = xlCenter
    End With
    With ActiveSheet.Columns("A:D")
        .HorizontalAlignment = xlLeft
    End With

MsgBox "Ready"

End Sub

【问题讨论】:

  • 在任何事情之前,请参阅How to avoid using Select in Excel VBA(尤其是第一个和第二个最佳答案)。
  • 可以,但速度较慢的部分是更新数据表中的公式和 vlookup,数据透视表的选择部分是最后一部分,速度较快。但是,我会更改它以防止出现问题
  • 你为什么要调用多个DoEvents?谨慎使用它,主要用于背景/外部需求。请参阅MSDN docs page 上的备注。
  • 通常使用 DoEvents 来确保代码的每个部分都有时间完成,直到完成剩余的代码。无论如何,我已经删除了所有的 DoEvents,它仍然很慢,并且仍然在从 SQL/ODBC 查询中检索的超过 30K 行数据的 vlookup/公式中。如果我删除所有的 vlookup,它会很快。所以问题在于使用检索到的数据更新公式......
  • 有这么多行,Vlookup 会很慢。如果您能找到一种方法将该查找预加载到字典中(将需要初始时间来加载,但只需执行一次),那么它可能会快得多。

标签: sql vba excel-formula odbc ms-query


【解决方案1】:

提高性能的方法

(没有工作簿辅助,很难从底部找出真正的罪魁祸首)......

似乎您已经涵盖了大部分通用 VB 部分:

Application.screenupdating=falss
Application.calculationmode = xlManualClaculation

等等,所以继续讨论可能的罪魁祸首*:

*(虽然你意识到“Doevents”会减慢宏的速度


1) VLOOKUP

1.1) 使用索引匹配

我个人很讨厌 VLOOKUP,并且自从 Excel 2000 之类的之后就没有使用过它,因为当时我不知道有什么更好的方法。虽然 XLOOKUP 看起来很有希望,但通常情况下 VLOOKUP 对索引/匹配的限制过于严格,因为它只能搜索查找列的右侧(排除例外情况)。

你猜怎么着?它也比索引/匹配慢很多!

请参阅here(Kyd,n.a,浏览量超过 40k,可下载 Excel 工作簿/示例)

"对于未排序的数据,VLOOKUP 和 INDEX-MATCH 的计算时间大致相同。...对于已排序的数据和近似匹配,INDEX-MATCH 比 VLOOKUP 快约 30%。对于已排序的数据和快速找到精确匹配的技术,INDEX-MATCH 比 VLOOKUP 快 13%。"

关于偏移/匹配与索引匹配的优点的讨论(性能方面)可以找到here(Ed,2003 年)

1.2) 限制范围

无论你使用VLOOKUP/INDEX-MATCH/OTHER,尝试:

  • 限制适用范围 - 例如如果您已经这样做了,请不要突出显示整个列,或者使用动态范围(Cheusheva,2021 年)

2.1) 其他

  • 您的 VB - 您是否尝试过执行程序的不同部分(第一、第二、第三关键区域)?即发现哪个耗时最长?
  • 什么时候开始“陷入困境”?在导入阶段,还是在进行计算时?或创建/更新枢轴
  • excel 文件有多大?如果超过 40MB,这可能是个问题。如果您还没有保存为文件类型 .xlsb,您将拥有相同的 VB 访问权限,除非您使用 SQL 输出(您可能会),否则您可以将文件大小减少 ~40-50%!
  • 鉴于您确实有 SQL 连接,最近您的网络连接是否有一些奇怪/有趣的地方(如果适用?)您能否将数据导入完全独立的工作簿,然后使用数据导入来操作本地数据文件(我知道你可以,我的意思是,试试这个,看看它是否会减少时间)
  • 输入枢轴然后“重新枢轴”的计算可能会导致实质性延迟

【讨论】:

  • 问题是 refresh.all 和所有从 sql 填充的数据表中的 vlookup。我认为它会因为超过 30k vlookup x 3 列而缓慢更新,这意味着要更新然后更新数据透视表需要 90k vlookup。
  • stackoverflow.com/questions/18656808/… CTRL+SHIFT+ENTER 找到 vbalookupcode 来验证代码,但我无法使其工作。 {=vbalookup(A2:A2;sheet2!B3:C99999;2)} A2 = 001-00108 SHEET2 B3 = 代码列表(即 001-00108) SHEET2 C3 = 日期,因此 vbalookup 必须找到最后日期 请注意代码列表已排序且最后重复的代码 = 最后日期
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-11
  • 1970-01-01
  • 2020-06-03
  • 2015-02-02
  • 2013-02-18
相关资源
最近更新 更多