Mik*_*ill 5 excel vba vsto excel-vba
当您打开多个Excel文件,并且VBA/VSTO代码调用该Calculate函数或打开自动计算时,Excel将痛苦地重新计算所有打开的工作簿,而不仅仅是活动工作簿.
这是一个众所周知且报道良多的问题,已存在多年,但微软似乎并不想修复它.
可笑的是,在VBA和VSTO中,微软让我们有能力:
...但是没有选择只重新计算一个特定的工作簿.
在我工作的金融公司,这是一个巨大的问题.我们的精算师有大,笨重的Excel文件,充分公式,当他们点击计算上一个工作簿或我们保存文件前进行计算,然后他们必须等待几分钟到其他所有打开的Excel文件也得到计算.
有两种方法可以解决这个问题.
你可以像这样运行一些VBA:
Application.Calculation = xlManual
For Each sh In ActiveWorkbook.Worksheets
sh.Calculate
Next sh
Run Code Online (Sandbox Code Playgroud)
..但这不能保证有效.您的"Sheet1"可能包含指向"Sheet2"中单元格的公式,但"Sheet2"中的其他单元格可能依赖于"Sheet1".因此,计算每个工作表一次可能不足以在工作簿上执行完整计算.
或者,您可以在单独的实例中打开每个Excel文件(通过在打开Excel图标时按住ALT).但是,你失去了完整的Excel cut'n'pasting功能,如下所述:
所以,我的问题是......有没有人找到解决这个问题的方法?
我只想重新计算Active Excel工作簿中的单元格.
我想知道是否可以添加一些VBA或VSTO,在我启动Active Workbook上的计算之前将所有非活动工作簿设置为"只读",从而防止其他工作簿被重新计算.但这是不可能的.Workbook.ReadOnly只能读取" ",而不能以编程方式设置.
或者可能在Worksheet_Calculate事件中添加一个处理程序,它检查正在运行的VBA代码是否属于Active Workbook,如果没有,它会中止尝试计算......?但这个事件实际上被拉开序幕后,该工作表已被计算,所以一切都太迟了.
我们公司不可能是唯一遭受这个问题的人......
任何建议(除了升级到Lotus 1-2-3)?
此方法使用 Excel 的另一个实例来避免多个工作簿计算。使用新实例的几行代码取自此 SO 问题,该问题涉及类似的主题,您可能会感兴趣。
您必须在具体情况下测试其速度,因为关闭/打开时间可能不会超过避免的计算!
宏观步骤
运行该脚本的要点:
代码- 详细信息请参阅评论
Sub CalculateWorkbook(WB As Workbook)
' Store path of given workbook for opening and closing
Dim filepath As String
filepath = WB.FullName
' Turn off calculation before saving
Dim currentCalcBeforeSave As Boolean
currentCalcBeforeSave = Application.CalculateBeforeSave
Application.CalculateBeforeSave = False
' Store current calculation mode / screen update and then set it to manual
Dim currentCalcMode As Integer, currentScreenUpdate As Integer
currentCalcMode = Application.Calculation
currentScreenUpdate = Application.ScreenUpdating
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False
' Close and save the given workbook
WB.Close savechanges:=True
' Open a new INSTANCE of Excel - meaning seperate calculation calls
Dim newExcel As Excel.Application
Set newExcel = CreateObject("Excel.Application")
' Could make it visible so that any problems don't leave it hidden in the background
' newExcel.Visible = False
' Set the calculation mode to manual in the new instance sothat the workbook isn't calculated on opening.
' This can't be done without an existing workbook object.
Dim tempWB As Workbook
Set tempWB = newExcel.Workbooks.Add
newExcel.Calculation = xlCalculationManual
newExcel.CalculateBeforeSave = False
' Open the workbook in the new instance of Excel
Dim newWB As Workbook
Set newWB = newExcel.Workbooks.Open(filepath)
' Calculate workbook once
newExcel.Calculate
' Close and save the workbook, tempworkbook and quit new instance
newWB.Close savechanges:=True
tempWB.Close savechanges:=False
newExcel.Quit
' Re-open in the active instance of Excel
Application.Workbooks.Open filepath
' Reset the application parameters
Application.CalculateBeforeSave = currentCalcBeforeSave
Application.ScreenUpdating = currentScreenUpdate
Application.Calculation = currentCalcMode
End Sub
Run Code Online (Sandbox Code Playgroud)
通过向其传递您希望重新计算的工作簿对象来调用上面的子程序(这可以通过按钮等完成)。
这已经在一个非常简单的示例工作簿上进行了测试,并且该概念有效。但是,请先在工作簿的副本上进行测试,因为它尚未经过完全的稳健性测试,并且没有错误处理。
| 归档时间: |
|
| 查看次数: |
2459 次 |
| 最近记录: |