假设我有一个将在工作表中使用100,000次以上的UDF。在函数中是否有一种方法可以让它知道在批处理中要调用多少次?基本上我想要做的就是让每个函数都创建一个待办事项列表。我想做点什么:
IF remaining functions to be executed after this one = 0 then ...
有办法做到这一点吗?
背景:
我想创建一个UDF,它将在用户只提供参数(日期,小时,节点,类型)的情况下执行SQL查询。如果您愿意在每次运行函数时实际执行SQL查询,这很容易实现。我知道这很简单,因为我做到了这一点,而且速度非常慢。我的新想法是让函数首先查看它所查找的数据是否存在于全局缓存变量中,以及是否不将其添加到全局变量“job-list”。
我想要它做的是调用最后一个函数然后遍历作业列表并执行最少数量的SQL查询并填充全局缓存变量。一旦缓存变量已满,它就会进行表刷新,以便再次调用所有其他函数,因为在后续调用中,它们将在缓存中找到所需的数据。
答案 0 :(得分:2)
首先:
VBA UDF性能对UDF编码方式极为敏感:
请参阅我关于编写高效VBA UDF的系列文章:
http://fastexcel.wordpress.com/2011/05/25/writing-efficient-vba-udfs-part-1/
您还应该考虑使用Array UDF返回多个结果:
http://fastexcel.wordpress.com/2011/06/20/writing-efiicient-vba-udfs-part5-udf-array-formulas-go-faster/
其次:
本系列的第12篇文章概述了使用AfterCalculate事件和缓存
http://fastexcel.wordpress.com/2012/12/05/writing-efficient-udfs-part-12-getting-used-range-fast-using-application-events-and-a-cache/
基本上你需要的方法是UDF检查缓存和放大器。如果不是最新的或可用的,则向队列添加请求。
然后使用计算后事件处理队列,如果需要,则触发另一个重新计算。
答案 1 :(得分:0)
从Excel电子表格执行100,000个SQL查询似乎是一个糟糕的设计。在这些之上创建缓存机制似乎使问题复杂化,使其变得比它可能需要的更复杂。在某些情况下这可能是合适的,但我会考虑采用其他设计方法。
最明显的是从Excel电子表格中获取数据并将其加载到数据库中的表中。然后使用数据库对所有行进行处理。最后一步是将结果读回Excel。
我发现从Excel中将大量行存入数据库的最佳方法是将Excel文件另存为csv并批量插入。
此方法可能不适用于您的问题。但是,一般而言,在数据库中运行的基于集合的方法将会表现得更好。
至于cach'ing机制,如果你必须走那条路。我可以想象一个具有以下伪代码的函数:
Check if input values are in cache.
If so, read values from cache.
Else do complex processing.
Load values in cache.
这个逻辑可以进入函数。正如@Bulat建议的那样,最好在函数周围添加一个额外的缓存层。