等待使用循环引用以

时间:2017-07-11 20:44:03

标签: c# excel excel-vba excel-interop vba

我有一些单元格(让我们称之为源单元格)由另一个单元格引用(让我们称之为目标单元格)。我更改了源单元格中的值,我希望在重新计算目标单元格中​​的公式后得到结果值。

我暂时将计算设置为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的解决方案,还是应该解决循环引用?

1 个答案:

答案 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