仅在工作表级别进行Excel自动计算

时间:2016-05-03 09:07:05

标签: excel vba

我有一张excel表变得很慢。 出于某种原因,无论我在文档中的哪个位置,如果我将计算设置为手动并在任何更改后刷新当前工作表,它就足够快并且符合我的目的。

然而,这并不是很舒服。

我想在更改单元格时刷新当前工作表(而不是整个文档)。无论我在哪张床单上都应该这样做。我怎么能这样做?

编辑:很明显,我并不是在寻求有关如何更快地制作工作簿的线索,而只是提供了上下文信息。我只对autorefresh感兴趣。

3 个答案:

答案 0 :(得分:1)

查尔斯威廉姆斯在他的网站http://decisionmodels.com上有大量的计算信息,技术和代码。引自this page

  

另一种方法使用worksheet.enablecalculation属性。什么时候   此属性已更改工作表上的所有公式都已标记   如未计算,所以将属性切换为false然后再返回   对于所有打开的工作簿中的所有工作表都将为true   计算是一个完整的计算。

> Dim oSht as worksheet Application.Calculation=xlCalculationManual
> 
> for each oSht in Worksheets oSht.enablecalculation=false
> osht.enablecalculation=true next osht
> 
> Application.calculate
  

您还可以将此方法用于单个工作表以执行完整工作表   计算

您可以轻松地将此技术应用到Worsheet_Change事件中,如下所示:

Private Sub Worksheet_Change(ByVal Target As Range)

Application.Calculation = xlCalculationManual

Me.EnableCalculation = False
Me.EnableCalculation = True
Me.Calculate

End Sub

这将仅对当前工作表进行完整计算,并且不会计算所有其他工作表。

答案 1 :(得分:0)

我相信计算事件可能发生在应用程序,工作表或范围级别(但不是工作簿级别)。

如果您将计算模式设置为手动但希望在输入内容时更新当前工作表(仅限),则可以添加工作表更改事件(将代码放在相关工作表中。)

Private Sub Worksheet_Change(ByVal ChangedRng As Range)
    ChangedRng.Worksheet.Calculate
End Sub

这将重新计算工作表,而不是工作簿的其余部分或任何其他工作簿。

答案 2 :(得分:0)

由于提供的答案并不完全让我满意,这是我自己的,借鉴他们的赞赏。我可能错过了teylyn的回答中的一些细微差别。如果相关,我很乐意编辑。

似乎没有办法在APPLICATION级别处理更改事件。

因此,所有更改都必须在SHEET级别处理。

这可以通过在工作簿的每个Sheet对象中复制和粘贴这段代码来完成(并且记得在添加新工作表时将其复制并粘贴):

Private Sub worksheet_change(ByVal Target As Range)
    Me.Calculate
End Sub

然而,由于我们不得不做的繁琐的复制粘贴,我们可能希望在不返回每个工作表对象的情况下轻松关闭此功能。

如果我们在一张纸上进行质量变换(例如通过微距,拖放和ctrl + H),我们可能还想避免进入地狱循环。

为此,我们添加了一个名为WS_refresh的新工作表,其中我们设置了3个值:

    A2中的
  • :是/否以启用/禁用我们的新功能
  • A4中的
  • :最新刷新时间
  • 在A6:允许刷新的最小间隔,以秒为单位(我将其设置为1)

现在,当我们按时间短时间更改几个单元格中的值时,autorefresh将仅对第一次更改起作用,避免先前提到的地狱循环。如果你喜欢危险地将A6设置为0。

这是应该在每个工作表对象中复制和粘贴的内容:

Private Sub worksheet_change(ByVal Target As Range)
auto_refresh = ThisWorkbook.Worksheets("WS_refresh").Range("A2")
If auto_refresh = "Yes" Then
    last_refresh = ThisWorkbook.Worksheets("WS_refresh").Range("A4")
    refresh_interval_sec = ThisWorkbook.Worksheets("WS_refresh").Range("A6")
    refresh_interval_tv = TimeValue("0:00:" & refresh_interval_sec)
    If Application.Calculation = xlCalculationManual And Now() > last_refresh + refresh_interval_tv Then
        ThisWorkbook.Worksheets("WS_refresh").Range("A4") = Now()
        Me.Calculate
    End If
End If
End Sub