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

时间:2016-09-23 20:06:45

标签: excel vba excel-vba volatile udf

似乎Application.Volatile和ActiveSheet.Calculate不是我认为的那样,我需要帮助创建一个在相关数据更改时正确重新计算的函数。这就是我现在要做的事情:

 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

正如你所看到的,它需要一个单元格并使用该单元格进行求和以提供条件和条件列,使用函数所在的列为实际数字求和(我知道这看起来像重新发明轮子,但我只是构成我问题最简单的形式)。它基本上在每一行上执行这些计算。

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

但是每当我对标准或总和范围进行更改,而不是重新计算以解释标识符或数字的变化时,似乎忘记了受影响的行存在(即使我只是将其更改为MATCH标准)或者只是抛出#VALUE错误。通过单击“= Availability(A#)”函数并按Enter键可以很容易地解决这个问题,但我不想写一个额外的宏来刷新所有这些单元格,当它们遍布电子表格时。切换波动率有所帮助,但没有解决问题,也没有在下面的换页事件中添加一些变化:

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

肯定有一些方法可以让一个函数在任何细胞被改变时自我刷新,而不仅仅是它自己。

3 个答案:

答案 0 :(得分:1)

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

问题的第二部分是您正在引用活动单元格。如果更改数据,则活动单元格是刚刚更改的单元格,而不是公式所在的单元格。使用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 而不是调用另一个函数来查找列字母。单元格允许数字引用。

{{1}}

答案 1 :(得分:1)

恕我直言,使用Application.Volatile作为无意中忽略Excel重新计算规则的绑定是错误的 - 为什么不正确执行并将UDF需要的所有范围作为参数传递给UDF ?
然后你不会需要应用程序volatile等,你的工作簿和UDF会更干净地计算。

答案 2 :(得分:0)

由于计算已经是自动的,并且整点不是要添加更多要定义的参数(即除了sumif的标准之外全部都是自动的),唯一必要的变化是将Application.ActiveCell变为Appplication.ThisCell。 Application.Caller也可能有用,但这种方式似乎更加确定。感谢Tim和Scott的帮助!