易失性用户定义函数不按预期重新计算(VBA / Excel)

看起来Application.Volatile和ActiveSheet.Calculate不是我认为的那样,我需要帮助创build一个函数,当相关数据改变时能够正确地重新计算。 以下是我现在正在做的事情:

Public Function Availability(EmpName As Range) Application.Volatile (True) ColLetter = Cletter(EmpName.Column) Set NameRange1 = Range("$" & ColLetter & "$1:$" & ColLetter & "$" & (Application.ActiveCell.Row - 1)) Set SumRange1 = Range(Cletter(Application.ActiveCell.Column) & "1:" & Cletter(Application.ActiveCell.Column) & (Application.ActiveCell.Row - 1)) Sum1 = Application.SumIfs(SumRange1, NameRange1, EmpName) Availability = Sum1 End Function 

所以你可以看到,它需要一个单元格,并使用该单元格的sumifs来提供条件和标准列,使用函数所在的列来为实际的数字求和(我知道这似乎是重新发明轮子,但我只是提出了我的问题最简单的forms)。 它基本上每行都执行这些计算。

CLetter只是另一个将Column#转换成字母的小函数,因为我懒得调用R1C1,并且发现它更具可读性。

但是每当我修改标准或总和范围,而不是重新计算标识符或数字的变化,似乎忘记了受影响的行存在(即使我只是改变它匹配的标准),或只是抛出一个#VALUE错误。 通过点击“= Availability(A#)”函数并点击回车就可以很容易地解决这个问题,但是我不愿意写一个额外的macros来刷新所有这些单元格,当他们遍布电子表格时。 切换波动有一点帮助,但没有解决问题,在下面的换页事件上也没有添加一些变化:

  Private Sub Worksheet_Change(ByVal Target As Range) ActiveSheet.Calculate End Sub 

当然,有一些方法可以让函数在任何单元格被更改时刷新自己,而不仅仅是自己。

首先确保您的计算在选项中设置为自动。 如果您的计算设置为自动,则每次更改引用的数据时都会更改。

问题的第二部分是您正在引用活动单元格。 如果更改数据,则活动单元格是刚更改的单元格,而不是公式所在的单元格。请使用Application.Caller ,它指向调用Function的单元格。

第三次使用Cells而不是调用另一个函数来查找列字母。 单元格允许参考号码。

 Public Function Availability(EmpName As Range) Application.Volatile Set NameRange1 = Range(Cells(1, EmpName.Column), Cells(Application.Caller.Row - 1, EmpName.Column)) Set SumRange1 = Range(Cells(1, Application.Caller.Column), Cells(Application.Caller.Row - 1, Application.Caller.Column)) Sum1 = Application.SumIfs(SumRange1, NameRange1, EmpName) Availability = Sum1 End Function 

恕我直言,这是一个错误,使用Application.Volatile作为一个无用的Excel的重新计算规则
– 为什么不正确地将UDF所需的所有范围都作为parameter passing给UDF?
那么你将不需要应用程序易失性等,你的工作簿和UDF将计算得更干净。

由于计算已经是自动的,并且整点不是要添加更多的参数来定义(即除了sumif的标准外,它们都是自动的),唯一必要的改变是使Application.ActiveCell进入Appplication.ThisCell。 Application.Caller也可能工作,但这种方式似乎更确定。 感谢您的帮助蒂姆和斯科特!