I\'ve noticed that my UDFs recalculate whenever I delete cells. This causes massive delays when deleting entire columns, because the UDF gets called for each and every cell
Inserting or deleting a row or column or cell will always trigger a recalc in automatic mode. (You can check this by adding =NOW() to an empty workbook and inserting or deleting things)
The question should be what (unexpected) circumstances flag a cell as dirty so that it gets recalced.
There is a (probably incomplete) list of such things at
http://www.decisionmodels.com/calcsecretsi.htm
Looks like I need to add some words about VBA UDFs (have not tested XLL UDFs
- they may behave differently since they are registered in a different way to VBA UDFs)
Unfortunately, I don't believe it's possible to prevent a UDF from being recalculated when "unrelated" cells are deleted. The reason for this is that the argument passed to the UDF is in fact a Range
object (not just the value within the cell(s)). Deleting "unrelated" cells can actually modify the Range
.
For example, users can write this kind of UDF:
Function func1(rng)
func1 = rng.Address & " (" & Format(Now, "hh:mm:ss") & ")"
End Function
Admittedly, this is not the common (and recommended) approach to write a UDF. It should normally depend on the content (value) and not the container (range).
Here I'm just returning the address of the argument. I also append a timestamp to signal when the UDF is recalculated. If you delete any column on the worksheet, all cells with this UDF are recalculated. But not if you insert a column, leaving the cells on the right (of this new column) unchanged and with the wrong value (cell address). The results are the same with inserting/deleting rows. Strangely, inserting a single cell does force recalculation of all UDF's.
I tried to remove the "dependency" on the Range
. But the behavior is also the same even if the UDF's argument is typed as double
(instead of leaving it as a Variant like in my example).
As you explained, deleting a column will force UDFs to be recalculated. This makes sense because a UDF can depend on the Range
argument. Wether this is a smart design for a UDF is a different matter.