【发布时间】:2017-04-04 09:13:34
【问题描述】:
当您打开多个 Excel 文件,并且您的 VBA/VSTO 代码调用 Calculate 函数或打开自动计算时,Excel 将痛苦地重新计算所有打开的工作簿,而不仅仅是活动工作簿。
这是一个众所周知且广为人知的问题,已经存在多年,但微软似乎对修复它并不感兴趣。
Calculate only the active workbook before saving
Microsoft Excel wishlist: Workbook level calculation
可笑的是,在 VBA 和 VSTO 中,Microsoft 让我们能够:
- 重新计算特定的工作表
- 重新计算所有打开的工作簿
...但是没有选择只重新计算一个特定的工作簿。
在我工作的金融公司,这是一个大问题。我们的精算师拥有庞大而庞大的 Excel 文件,其中充满了公式,当他们在一个工作簿上单击“计算”或我们在保存文件之前执行计算时,他们必须等待几分钟才能将所有其他打开的 Excel 文件也 计算出来。
有两种解决方法。
你可以像这样运行一些 VBA:
Application.Calculation = xlManual
For Each sh In ActiveWorkbook.Worksheets
sh.Calculate
Next sh
..但这不能保证有效。您的“Sheet1”可能包含指向“Sheet2”中单元格的公式,但“Sheet2”中的其他单元格可能依赖于“Sheet1”。因此,计算每个 Worksheet 一次 可能不足以对您的 Workbook 执行完整计算。
或者,您可以在单独的实例中打开每个 Excel 文件(在打开 Excel 图标时按住 ALT)。但是,您将失去完整的 Excel 剪切和粘贴功能,如下所述:
Can't fully cut'n'paste between Excel instances
那么,我的问题是……有没有人找到解决方法来解决这个问题?
我只是想重新计算 Active Excel 工作簿中的单元格。
我想知道是否可以添加一些 VBA 或 VSTO,在我开始对活动工作簿进行计算之前,将所有非活动工作簿设置为“只读”,从而防止其他工作簿能够被重新计算。但这是不可能的。 “Workbook.ReadOnly”只能读取,不能以编程方式设置。
或者可能向Worksheet_Calculate 事件添加一个处理程序,该处理程序检查正在运行的VBA 代码是否属于活动工作簿,如果不属于,它会中止尝试计算...?但是这个事件实际上是在计算完 Worksheet 之后开始的,所以为时已晚。
我们公司不可能是唯一遭受这个问题的公司......
任何建议(升级到 Lotus 1-2-3 除外)?
【问题讨论】:
-
鉴于您可以在 VBA 中使用trace a cells' dependends,我的第一个想法是您可以对相关单元格进行树搜索,首先计算最后一个分支并向后工作......这将解决问题你提到使用
sh.Calculate。您可以将其与rng.Calculate通话配对。可能需要一些真正的思考来为此编写一个优雅的函数! -
谢谢 Wolfie.. 是的,我们确实考虑过这个.. 但它会是一段噩梦般的代码编写,这就是为什么我认为以某种方式“禁用”会更安全计算期间所有其他打开的工作簿。问题是,当你重新启用它们的计算时,无论如何它都会开始计算,所以我们又回到了开始的地方!!
-
您可以使用 VBA 以只读方式打开工作簿 (msdn.microsoft.com/en-us/library/office/ff194819.aspx)
-
@Luuklag 以只读方式打开它们需要先关闭它们,对于 OP 来说并不是很理想(我认为)!
-
@MikeGledhill 是的,当我在写这个建议时,我意识到让健壮和快速(这是重点!)可能会很棘手,我认为 Excel 的计算功能做了类似但高度优化的事情。我会考虑一下,我也感受到了这种痛苦。