我注意到每当我删除单元格时,我的 UDF 都会重新计算。这会在删除整个列时导致大量延迟,因为 UDF 会为使用它的每个单元格调用。因此,如果您使用 1000 个 UDFS,则删除列或单元格将调用 1000 次。
例如,将以下 UDF 放入模块中,然后使用 =HelloWorld() 从工作表中多次调用它
Function HelloWorld()
HelloWorld = "HelloWorld"
Debug.Print Now()
End Function
然后删除一行。如果你的经验和我一样,你会看到每次使用都会调用一次。
有人知道这种行为是否可以停止吗?我也很感兴趣为什么它应该被调用。对我来说,这似乎是 Excel 依赖树中的一个缺陷,但很可能有一个很好的理由。
编辑:经过实验,我发现了更多触发 UDFS 的操作:
- 通过调整大小(但不是行)对 ListObject(即 Excel 表)跨越的列数进行的任何更改。即使 UDF 本身不在相关的 ListObject 中,或者实际上根本不在任何ListObject 中。
- 在工作表的任何位置(但不是行)添加新的单元格或列。
请注意,手动计算模式在多个方面都不是一个选项。
首先,鉴于这是一个应用程序级别的设置,它只会带来太大的风险,即有人会使用他们碰巧打开的任何一个电子表格的输出而没有意识到它们处于手动计算模式。
其次,我实际上并不是在设计一个特定的电子表格,而是在写一本关于非开发人员如何利用编写良好的现成代码(如 UDF)来完成原本超出他们能力范围的事情的书。示例包括动态连接或拆分文本,或 Charles Williams 在https://fastexcel.wordpress.com/2011/07/22/developing-faster-lookups-part-2-how-to-中概述的完全匹配二进制搜索 UDF build-a-faster-vba-lookup/ (是的,我给了他们很多警告,通常基于原生公式的解决方案会胜过 UDF。但正如您从我上面引用的线程中看到的那样,精心编写的函数可以很好地发挥作用)。
我不知道用户将如何使用这些。
在没有编程解决方案的情况下,看起来我只需要在书中指出,如果用户使用资源密集型 UDFS,则在添加或删除单元格或调整 ListObjects 大小时可能会遇到明显的延迟。即使这些 UDF 是有效编写的。