使用匹配工作表函数引用多列来评估函数缓慢



通常,Excel VBA的Evaluate函数是一种方便的方法,可以在VBA中获得工作表公式的结果,而不必将公式放在工作表单元格中。然而,我发现,如果要评估的公式是跨多列工作的MATCH函数,它会慢得惊人——比在工作表单元格中计算相同的公式慢得多。例如:

MatchingRow = EVALUATE(MATCH(Sheet1!G6&Sheet1!H6&Sheet1!I6,Sheet2!B:B&Sheet2!C:C&Sheet2!D:D,0))

知道为什么在工作表单元格中会比这个慢得多吗?

=MATCH(Sheet1!G6&Sheet1!H6&Sheet1!I6,Sheet2!B:B&Sheet2!C:C&Sheet2!D:D,0)

我很确定我可以听到有人已经输入一个答案,说这都是因为从VBA环境中调用工作表函数的开销。但如果是这样的话,我的后续问题是:为什么其他函数的EVALUATE不慢?

几件事

作用域在使用Evaluate()时很重要。在工作表上调用该方法的速度大约是单独使用Evaluate()的两倍,后者是Application.Evaluate()的简写。

连接是出了名的慢,当通过VBA和Excel之间的屏障调用时,这种低效率会成倍增加。

使用布尔逻辑作为一种替代机制来获得相同的公式结果,执行速度更快,时间上更接近工作表中的公式:

 MatchingRow =  = Sheet1.[MATCH(1,(Sheet1!G6=Sheet2!B:B)*(Sheet1!H6=Sheet2!C:C)*(Sheet1!I6=Sheet2!D:D),0)]

为了完整性,您还应该强烈考虑限制查找范围的深度。这将大大加快公式的评估,无论是在工作表或从VBA。下面是与上面相同的公式,但查找范围仅限于100行。适当调整:

Sheet1.[MATCH(1,(Sheet1!G6=Sheet2!B1:B100)*(Sheet1!H6=Sheet2!C1:C100)*(Sheet1!I6=Sheet2!D1:D100),0)]

最新更新