我有一些单元格(让我们称之为源单元格)由另一个单元格引用(让我们称之为目标单元格)。我更改了源单元格中的值,我希望在重新计算目标单元格中的公式后得到结果值。
我暂时将计算设置为XlCalculation.xlCalculationManual
,并使用Application.Calculate
强制进行全面重新计算。
问题在于,当在循环内部执行此操作时,有时公式的计算速度不够快,并且代码会获取较旧的值。所以我想要的是等待强制重新计算结束。
我尝试了Application.CalculationState
方法,但始终是xlPending
,这使程序陷入无限循环。 excel文件有一些循环引用,设置了计算迭代,我可以不断地在Excel状态栏中看到“计算”警告(即使我手动重新计算)。
我还尝试将Application.AfterCalculate事件与Autoreset事件结合使用,但我又一次无限地等待(我怀疑发出事件并等待事件发生在同一个线程上,所以当等待执行时首先执行程序挂起):
public static AutoResetEvent AutoEvent;
public static void StartMonitoring()
{
AutoEvent?.Close();
AutoEvent = new AutoResetEvent(false);
Globals.ThisAddIn.Application.AfterCalculate += Application_AfterCalculate;
}
public static void StopMonitoring()
{
Globals.ThisAddIn.Application.AfterCalculate -= Application_AfterCalculate;
AutoEvent?.Close();
AutoEvent = null;
}
public static void WaitForCalculations()
{
AutoEvent.WaitOne();
StopMonitoring();
}
private static void Application_AfterCalculate()
{
AutoEvent.Set();
}
...
StartMonitoring();
Globals.ThisAddIn.Application.Calculate()
WaitForCalculations();
有更好的想法吗?我是否希望找到具有给定excel的解决方案,还是应该解决循环引用?
答案 0 :(得分:0)
如果所有其他选项都失败了 您可以尝试将公式设置为手动并使用vb代码分别在每个单元格中执行公式:
Application.Calculation = xlManual
Range("NAMED_RANGE_1").Formula = "=10 + NAMED_RANGE_2"
Range("NAMED_RANGE_2").Formula = "=10 + NAMED_RANGE_1"
(很容易将细胞命名为Ranges 1st) 如果要抑制循环引用警告,可以始终从其中一个单元格中删除公式:
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False