【问题标题】:Excel running slowly when Excel the active windowExcel 在活动窗口时运行缓慢
【发布时间】:2018-04-27 05:32:49
【问题描述】:

我在任何地方都找不到这个问题的答案,所以我希望你们能帮助我。我的 excel 宏经历了几次数据迭代。它自动过滤源文件、提取信息、处理数据,然后再次执行大约 50 次 - 每人一次。这是我的意思的一些代码,所有单独的子方法都可以正常工作并且非常快:

For j = 1 To names.Count
   'filter the source by name, generate sheet
   FilterName names(j) 
   'prepare data with the necessary dates
   FillMasterDates dates(), j

   Dim i As Long
   Dim ending As Long
   ending = Sheets("Daten").Rows.End(xlDown).Row
   Dim cellvalue As String

   'check dates, etc
   For i = 1 To ending
       cellvalue = Sheets("Daten").Cells(i, 1)
       If cellvalue = "" Then
           Exit For
       End If
       ColorCell (i)
       FilterDate CStr(dates(i)), names(j)
   Next i

   'user data has been successfully gathered, copy over to final sheet
   FillColumns j
Next j

整个代码运行大约需要 4~ 秒(假设我有大约 2000 行并且我为 50~ 人创建了一个新工作表),这很好。令人费解的是,尽管使用了Application.ScreenUpdating = False(在宏中较早,但此时仍处于活动状态),当 Excel 保持我的活动窗口时,运行宏的必要时间上升到惊人的 25~ 秒。一样的输入,一样的输出。所以简单地说 - 运行宏,从 excel 中跳出 - 宏需要大约 4-5 秒才能运行。运行宏但留在 excel 中并等待 - 25 秒。

我试过Application.WindowState = Application.WindowStateActiveWindow.SmallScrollDoEventsApplication.CalculateFull()。我尝试了不同的计算设置,但我并没有真正使用 Excel 固有的任何公式计算 - 我必须使用 Excel 作为接口,因为源文件是 *.xls 文件,最终输出必须保持这种格式。

如果您需要我提供更多代码 sn-ps 来理解它,请尽管提问。我已经被难住了两天了。

【问题讨论】:

    标签: vba excel


    【解决方案1】:

    您总是可以尝试多行几行来禁用计算和警报等。

    Application.ScreenUpdating = false
    Application.Calculations = xlManual
    Application.DisplayAlerts = False
    

    但是,如果您真的想绕过所有后台废话,excel 似乎会通过不直接通过循环访问工作表,如果您不习惯这个概念可能会很棘手,但它值得每一点,并且会加快您的代码如此之快,你会想知道为什么你一开始就没有这样做。

    我没有你的代码,所以我只是举例说明它是如何工作的

    Dim RangeArray as Variant 'This will store your range as a values array
    
    RangeArray = Sheet1.Range("A1:G100000").Value 'this will put the entire ranges values into the array
    
    If Not IsArray(RangeArray) Then ExitSub 'If your range is only 1 cell it will not create an array so be careful, handle this as needed
    
    'This Array always starts lowerbound 1, RangeArray(1,1) = First Cell
    

    现在,您可以像使用单元格或范围一样遍历数据并操作和修改数组,除了没有开销,它只是值而不是对象。

    一旦您完成了您需要做的所有事情,您只需将值放回工作表范围

    Sheet1.Range("A1:G100000").value = RangeArray
    

    就是这样,很简单也很有效,而且这种从数组到范围的转移不管有多大都是即时的。

    如果这有帮助,请告诉我

    谢谢 保罗·S

    ---------------新消息-------

    你可以尝试一些可能有点过度和冒险的东西,如果你只是在窗口处于活动状态时遇到这个问题并显示如何让它不可见,问题是如果你的代码失败并且你没有捕获错误,它会在您转到任务管理器并将其关闭之前保持不可见。

    Application.Visible = false
    

    这也应该停用窗口(尽管我从未测试过)

    这应该模拟您隐藏窗口并在您的代码完成后将其带回来..

    ---------------新消息-------

    Application.Windowstate = xlMinimized 
    

    这应该可以解决问题:D,应该先提到这个哈哈

    我也刚刚看到你尝试了类似的东西,但是那里的代码不正确,试试这个

    【讨论】:

    • 嗨,保罗,感谢您的回答。我目前仅使用范围和使用对象来完成我的工作的问题是我想在一个范围内使用自动过滤的数据并使用它,但到目前为止我的尝试没有成功。我知道我可以将所有时间缩短到毫秒以下,但最初的 4 秒足以满足我的目的,也让客户满意。难道没有其他方法可以简单地阻止这种不稳定的行为吗?如果您查看我的帖子,我已经尝试了这些代码示例来禁用警报,
    • 哈哈天哪,谢谢保罗!这有点不合常规,但效果很好。也许有一个不那么“激烈”的命令来将活动窗口切换到另一个当前打开的窗口,比如 ALT + TAB 的工作方式?
    • 谢谢老兄!它完美地工作。我一直在尝试让 ALT TAB 工作,但它更加繁琐。你帮了大忙
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-23
    • 2017-09-05
    • 2016-01-25
    相关资源
    最近更新 更多