用户定义的函数不重新计算

时间:2011-04-19 16:32:31

标签: excel vba user-defined-functions xlsx xlsm

我最近获得了一个大而稳定的XLSM文件,并将其拆分为XLAM和XLSX。 XLSX调用中的数千个单元(udfs)在XLAM中起作用,每个这样的udf都以“Application.Volatile”语句开头(过度杀戮,强制重新计算)。

XLSX不会通过Ctrl-Alt-Shift F9重新计算F9,也不会通过Application.CalculateFull重新计算Cell.Calculate。 XLSX单元格只是“死”......但是......如果我点击F2编辑公式然后点击ENTER,我可以逐个重新唤醒它们。以这种方式重新唤醒的细胞似乎保持清醒,之后通常会重新调整。

是否有人遇到过这种奇怪的行为,还有其他方法可以强制Excel从头开始重建calc图吗?我应该尝试一下?

一个附加说明,如果它很重要:我通过文件打开打开了XLAM和XLSX,并且没有使用File ... Options ... Addins route安装XLAM - 因为在过去我已经这样做了,一旦你“取消选中”并安装了XLAM,那么所有的UDF引用都会被完整的路径名链接取代 - 非常难看。或者,如果有人可以概述安装XLAM插件的解决方法,但不会在任何地方创建断开的链接。

11 个答案:

答案 0 :(得分:7)

这有效:

CountDownTimer

答案 1 :(得分:6)

想出来 - 不确定为什么微软有这个“功能”:

在打开XLAM之前打开/创建使用XLAM功能的原始XLSX时会出现这种情况。在这种情况下,任何数量的哄骗都不会导致XLSX公式绑定到并执行那些XLAM函数,除非您进入每个单元格&触摸公式栏&点击ENTER(或者,正如我所发现的那样,通过全局替换这样做 - 在我的情况下,所有的funcs都以“k”开头,所以全局用“k”替换“k”修复了错误)。如果首先打开XLAM,则不会出现此问题。

答案 2 :(得分:4)

您可以通过搜索并在所有公式开头的=上替换来强制重新计算。您也可以将其转换为宏并将其映射到组合键。

已编辑添加

请参阅Greg Glynn在his answer中的宏。

答案 3 :(得分:2)

一种可能的解决方案:将计算模式设置为手动,然后返回自动

    Application.Calculation = xlCalculationManual
    Application.Calculation = xlCalculationAutomatic

答案 4 :(得分:2)

对于可以访问Application实例的 UDF ,可以使用:

Application.CalculateFull()

MSDN来源here

答案 5 :(得分:1)

这是我发现的。我没有对它进行过测试,但我相信可能会有解决方法。

这是直接引用: “Excel依赖于对函数的输入参数的分析,以确定何时需要通过重新计算来评估函数。”

来自http://www.decisionmodels.com/calcsecretsj.htm

以下是我今天晚些时候要尝试的内容。 我将在我的函数中动态地生成表的特定地址。 基于我们在这里的原因,如果计算出的地址的值发生变化,我不应该得到更新。

通过将整个表作为参数包含在内,即使不使用该参数,如果表中的任何内容发生变化,该函数也应该更新。

通过这种方式,无论您是否实际处理整个表,您的函数都会遇到依赖关系树。

答案 6 :(得分:1)

按CTRL + ALT + SHIFT + F9

这可能比想要的更重要,但它更新了我的UDF。

Source

答案 7 :(得分:0)

我的屏幕截图:

enter image description here

我遇到了同样的问题。查找和替换工作,但不是很好。我的解决方案是:

转到数据标签>修改链接>单击“打开源”将解决此问题

答案 8 :(得分:0)

Excel会监控公式中提到的任何变化的范围,我今天面对这个,我正在思考并意识到这一点。所以要修复它,在函数中创建一个伪参数,它接受你想要监视的范围或创建一个虚函数。在我的情况下,我称它为monitorRange,它不返回任何内容

Function monitorRange(rng As Range)
End Function

我在公式示例中提到了

=myfunction(a,b) & monitorRange(RANGE_TO_MONITOR)

这非常有效,它应该适用于任何其他功能

答案 9 :(得分:0)

在最初的问题上出现了很多年,但直到今天我遇到了一个类似的问题,我创建了一个UDF来确定选择了数据透视表过滤器的值。在宏编辑器中运行以及直接更新使用UDF的字段时,UDF都可以正常工作,但是在更新工作表或数据透视表时,它会抛出“ #VALUE!”。

直到我将原始UDF中的内容逐步添加到Ali的简单monitorRange函数中之前,这一直使我丧命。然后,我发现我的UDF有一个数据透视表刷新语句,该语句在删除后消除了“ #VALUE!”错误。以下是UDF的特定违规行,但我的一般规则是UDF在其调用链中不能包含任何代码来更新其他工作簿内容。也就是说,UDF必须仅获取值,而不能设置值。

我在以下两种情况下对此进行了验证,这两种情况均会导致此错误:

  1. 刷新数据透视表,例如:pt.PivotCache.Refresh
  2. 更改另一个单元格的值,例如:Range("AA1").Value = "Test"

奇怪的是,我测试并发现,UDF可以包含一个MsgBox调用来毫无问题地显示对话框,这是绝对可以的(实际上有点酷)。这将允许UDF监视范围,然后弹出msgbox对话框以显示要包含在UDF中的任何条件。在其他情况下,我会记住这一点。

希望这可以帮助其他人解决这个令人讨厌的垃圾问题。

答案 10 :(得分:-1)

我遇到了同样的问题......我发现(在另一篇文章中)将Application.Volatile添加到功能代码中,使用电子表格计算(f9)