Sql VBA UDF是否有一种方法可以;“知道”;将运行哪些其他功能?

Sql VBA UDF是否有一种方法可以;“知道”;将运行哪些其他功能?,sql,excel,user-defined-functions,excel-2010,vba,Sql,Excel,User Defined Functions,Excel 2010,Vba,假设我有一个自定义项,它将在工作表中使用100000次以上。在函数中,是否有一种方法可以让它知道在批处理中还要调用多少次?基本上我想做的是让每个函数创建一个待办事项列表。我想做一些类似的事情: IF remaining functions to be executed after this one = 0 then ... 有办法做到这一点吗 背景: 我想创建一个UDF,它将执行SQL查询,用户只需给出参数(日期、小时、节点、类型)。如果您愿意在每次运行函数时实际执行SQL查询,那么这很容易做

假设我有一个自定义项,它将在工作表中使用100000次以上。在函数中,是否有一种方法可以让它知道在批处理中还要调用多少次?基本上我想做的是让每个函数创建一个待办事项列表。我想做一些类似的事情:

IF remaining functions to be executed after this one = 0 then ...
有办法做到这一点吗

背景:

我想创建一个UDF,它将执行SQL查询,用户只需给出参数(日期、小时、节点、类型)。如果您愿意在每次运行函数时实际执行SQL查询,那么这很容易做到。我知道这很容易,因为我这样做了,速度慢得可笑。我的新想法是让函数首先查看它正在查找的数据是否存在于全局缓存变量中,以及是否将其添加到全局变量“作业列表”中


我想让它做的是调用最后一个函数,然后遍历作业列表,执行最少数量的SQL查询并填充全局缓存变量。一旦缓存变量已满,它将进行一次表刷新,使所有其他函数再次被调用,因为在随后的调用中,它们将在缓存中找到所需的数据。

从Excel电子表格执行100000 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所建议的,最好在函数周围添加一个额外的缓存层。

首先:
VBA UDF性能对UDF的编码方式极其敏感: 请参阅我关于编写高效VBA UDF的系列文章:

您还应该考虑使用数组UDF返回多个结果:


其次:
本系列的第12篇文章概述了AfterCalculate事件和缓存的使用



基本上,您需要的方法是让UDF检查缓存&如果不是最新的或可用的,则向队列添加请求
然后使用after calculation事件处理队列,必要时触发另一个recalc。

听起来这个控件应该在函数之外。如果函数知道这一点,那将是一个糟糕的设计。这些信息在批处理中是如何获得的?我很确定UDF无法访问此类信息。@Bulat,我所说的批处理只是指,要运行的函数队列,就像用户将同一个函数粘贴到一堆单元格中一样。Charles建议的应用程序事件似乎可以达到目的,只是不确定如何实现它。我将尝试一下,看看我学到了什么。我采用了一种需要100000个SQL查询的方法,只是为了看看它的性能有多差,而且速度慢得令人无法接受,正如预期的那样。您的伪代码是我需要的最明显的解决方案,但问题是“复杂处理”部分,这是我问题的核心。我的函数将做三件事中的一件,从缓存中检索数据(easy),创建/附加到作业列表(easy),或者从作业列表中创建缓存(doable),但困难的部分是在最后一次func调用期间创建缓存。(即,如果用户将func粘贴到10k单元格中,它应该只创建一次缓存)执行“硬部分”的简单方法不是函数本身,而是AfterCalculate事件