我不清楚 LET() 语句中语句的执行顺序。
我的用例是一个返回数据库表中行数的函数:有一种快速的方法来获得估计值,或者有一种慢得多的方法来获得准确的数字。如果快速方法生成的行数低于 50,我想运行慢速方法来获取确切的行数,否则估计就可以了。
考虑一个例子:
单元格 A1 =QUICK()
其中 QUICK() 在快速函数中返回一个非零整数。
单元格 B1 = IF(A1<50,SLOW(),A1)
其中 SLOW() 是一个非常慢的函数
这正如我所期望的那样,只有当 A1 < 50 时才会调用 SLOW()。
但是,如果我尝试在一个函数中完成这一切:
单元格 A1 =LET(nr,QUICK(),IF(nr<50,SLOW(),nr))
看来SLOW()
始终执行,无论 nr
的值如何,即使我添加一个虚拟参数,使得 SLOW()
依赖nr
.
有人见过类似的吗?
最佳答案
此行为是由 QUICK() 函数(来自 xll)返回单值 1x1 数组而不是标量引起的。
使用@BigBen的例子:
=IF(TRUE,0,MMULT(SEQUENCE(1000,1000),SEQUENCE(1000,1000,2)))
立即返回0
而 =IF({TRUE},0,MMULT(SEQUENCE(1000,1000),SEQUENCE(1000,1000,2)))
返回 0
的 1000x1000 数组。
这本身很奇怪,因为这也不是 =MMULT(SEQUENCE(1000,1000),SEQUENCE(1000,1000,2))
的结果。
我使用的是 Excel 版本 2302 内部版本16130.20306
进一步说明:
如果我有一个范围 A1:A2,每个单元格中都包含 TRUE
并调用 =IF(A1:A2,0,1)
我得到一个 0
的 1x2 数组。这正是我所期望的。
如果我调用 =IF(A1:A2,0,SEQUENCE(2,2))
我会得到一个 0
的 2x2 数组,这肯定不是我想要的会期望。
怀疑:
Excel 函数只能返回标量或 r x c 数组。我猜测数组函数首先尝试确定结果数组的维度,然后用函数结果填充该数组。
以更简化的形式:
=IF({TRUE;TRUE},1,{0,0})
您可能期望得到 1
的 2x1 数组,但实际上得到的是 1
的 2x2 数组。 Excel(可能)执行了 fnTrue 和 fnFalse 选项,无论测试参数的值(TRUE/FALSE)如何,然后采用最小的 r x c 数组两者都适合。然后,它用 fnTrue 或 fnFalse 的结果填充该数组。在此示例中,对于测试的每一行,Excel 都会预留一个 1x2 数组,然后用答案填充它。
如果函数为 =IF({TRUE,FALSE},1,{0,0})
并且 Excel 天真地逐行应用测试,则第一行 (TRUE)将返回 1
,但返回第二个 {0,0}
。然后,Excel 必须重新分配返回数组,并返回并填充第一行结果中的空单元格。所以我猜测公式被解析以计算出结果的可能维度,这似乎需要执行这两个函数。
冒着过于沉迷于此的真正风险...您可以通过创建两个 VBA UDF(ifTrue() 和 ifFalse)来测试此断言,并使用Debug.Print
记录每次调用的时间。如果您调用函数=IF({TRUE},ifTrue(),ifFalse())
,您将在立即窗口中看到两个函数都被调用。
关于excel - 带有 IF 子句的 LET 语句中的执行顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77151788/