Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
VBA-为什么VBA UDF与本机Excel函数相比速度如此之慢?_Excel_Vba_Excel Formula - Fatal编程技术网

VBA-为什么VBA UDF与本机Excel函数相比速度如此之慢?

VBA-为什么VBA UDF与本机Excel函数相比速度如此之慢?,excel,vba,excel-formula,Excel,Vba,Excel Formula,假设我编写了以下VBA UDF: Function TestFunction() TestFunction = 0 End Function 然后我将其用于我的工作表中的前100000行。执行需要几分钟 相反,如果我今天使用相同数量的行,执行只需3-4秒 有谁能告诉我为什么,如果有一种方法可以加速UDF 谢谢大家! 有几个原因 VBA函数需要在UI/主线程之外按顺序运行,编译的p代码需要由VBA运行时解释 本机函数是本机函数。他们大概是用C++编写的,已经编译成机器代码,这些代码易于执

假设我编写了以下VBA UDF:

Function TestFunction()
    TestFunction = 0
End Function
然后我将其用于我的工作表中的前100000行。执行需要几分钟

相反,如果我今天使用相同数量的行,执行只需3-4秒

有谁能告诉我为什么,如果有一种方法可以加速UDF

谢谢大家!

有几个原因

VBA函数需要在UI/主线程之外按顺序运行,编译的p代码需要由VBA运行时解释

本机函数是本机函数。他们大概是用C++编写的,已经编译成机器代码,这些代码易于执行,不需要重新编译和/或解释。一些本机函数还可以利用多线程和后台计算

至于加快你的自定义项,我们需要看看你的自定义项。一个函数除了分配一个文本返回值之外什么都不做,没有太多的优化空间,是吗

UDF很棒。但它们不是银弹。如果我想将值0写入A1:A1000000,我会执行Sheet1.RangeA1:A1000000.value=0,这几乎是即时的

如果要计算数十万个宏,请考虑查看宏而不是自定义项。

有几个原因

VBA函数需要在UI/主线程之外按顺序运行,编译的p代码需要由VBA运行时解释

本机函数是本机函数。他们大概是用C++编写的,已经编译成机器代码,这些代码易于执行,不需要重新编译和/或解释。一些本机函数还可以利用多线程和后台计算

至于加快你的自定义项,我们需要看看你的自定义项。一个函数除了分配一个文本返回值之外什么都不做,没有太多的优化空间,是吗

UDF很棒。但它们不是银弹。如果我想将值0写入A1:A1000000,我会执行Sheet1.RangeA1:A1000000.value=0,这几乎是即时的


如果要计算数十万个宏,请考虑查看宏而不是自定义项。

原因有很多

例如,解释VBA UDF,而编译本机Excel工作表函数。例如,如果您将VBA代码编译为VB6,则速度会大大提高。VBA和VB6代码要么相同,要么几乎完全相同。因此,速度大幅提高的原因是VB6代码是编译的,而不是像VBA代码那样解释的

VBA代码也不会生成与Excel相同类型的工作表函数。例如,VBA UDF缺少工作表智能感知。您无法通过VBA以任何方式获取此信息。您可以通过其他地方的外部加载项获取,例如Excel DNA

另一个原因是VBA不是编写高性能UDF的最佳API。这就是C API。但是C API比VBA更难编写UDF

还有许多其他因素可能会影响速度,比如底层硬件,或者UDF中使用的算法。在没有看到代码的情况下,很难给出有用的建议

你确定你需要自定义项吗?无论如何,我知道UDF相对于宏的唯一优势是它们在调用后不会删除undostack,而大多数宏会这样做。它们可以动态地重新计算,而在调用宏之后,您必须不断地重新运行宏,除非您使用的是工作表事件或其他东西


如果要对一系列单元格进行大量计算,最好是将该区域写入数组,在VBA中进行操作,然后将其写回该区域。

原因有很多

例如,解释VBA UDF,而编译本机Excel工作表函数。例如,如果您将VBA代码编译为VB6,则速度会大大提高。VBA和VB6代码要么相同,要么几乎完全相同。因此,速度大幅提高的原因是VB6代码是编译的,而不是像VBA代码那样解释的

VBA代码也不会生成与Excel相同类型的工作表函数。例如,VBA UDF缺少工作表智能感知。您无法通过VBA以任何方式获取此信息。您可以通过其他地方的外部加载项获取,例如Excel DNA

另一个原因是VBA不是编写高性能UDF的最佳API。这就是C API。但是C API比VBA更难编写UDF

还有许多其他因素可能会影响速度,比如底层硬件,或者UDF中使用的算法。在没有看到代码的情况下,很难给出有用的建议

你确定你需要自定义项吗?UDF相对于宏的唯一优势 无论如何,我知道它们在被调用后不会删除撤消堆栈,而大多数宏会这样做。它们可以动态地重新计算,而在调用宏之后,您必须不断地重新运行宏,除非您使用的是工作表事件或其他东西


如果要在一系列单元格上进行大量计算,最好只将该范围写入数组,在VBA中进行操作,然后将其写回该范围。

如果能够显示实际的慢速函数,我认为这将更有指导意义。VBA函数可能非常快,但您确实需要注意使其快速运行在执行时关闭自动计算,使用数组而不是直接操作单元格..等等答案基本上是因为native是native,而VBA不是。我认为如果您能够显示实际的慢速函数,将更有指导意义。VBA函数可能非常快,但您确实需要注意使其快速运行在执行时关闭自动计算,使用数组而不是直接操作单元格..等等答案基本上是因为本机是本机的,而VBA不是。是的,我认为需要解释VBA代码才是真正的问题。非常感谢您的支持!难道你不认为互操作实际上是像这个例子这样的简单函数的罪魁祸首吗?也就是说,UDF需要对工作表进行10000次读/写操作,而不是像宏那样只读/写一次,这是它速度慢的主要原因,而不是因为多线程或编译代码与解释代码。我认为计时是一件非常棘手的事情,但我感觉调用函数的开销比它包含或不包含的代码的实际执行时间更重要,在这种情况下!。是的,我认为需要解释VBA代码才是真正的问题。非常感谢您的支持!难道你不认为互操作实际上是像这个例子这样的简单函数的罪魁祸首吗?也就是说,UDF需要对工作表进行10000次读/写操作,而不是像宏那样只读/写一次,这是它速度慢的主要原因,而不是因为多线程或编译代码与解释代码。我认为计时是一件非常棘手的事情,但我感觉调用函数的开销比它包含或不包含的代码的实际执行时间更重要,在这种情况下!。嗯。。。没有VBA不被解释,它被编译成PCode,然后在运行时被解释。公式也会被解释,但可能确实链接到已编译的C函数。@Sancarn compiled通常意味着它被编译成EXE或DLL之类的东西,而VBA代码从来都不是。我的声明是基于Chip Pearson:Performance-CAI是一个ActiveX DLL,编译成本机代码。CAI的运行速度比VBA.Erm的解释代码快得多。。。没有VBA不被解释,它被编译成PCode,然后在运行时被解释。公式也会被解释,但可能确实链接到已编译的C函数。@Sancarn compiled通常意味着它被编译成EXE或DLL之类的东西,而VBA代码从来都不是。我的声明是基于Chip Pearson:Performance-CAI是一个ActiveX DLL,编译成本机代码。CAI的运行速度比VBA的解释代码快得多。