神秘使用LOOKUP

时间:2015-09-21 19:31:23

标签: excel excel-formula

我多年来一直在使用这个Excel公式。它工作正常,但我想了解它的工作原理!该公式用于在列表中查找 last 关联值。例如:

Macro usage example.

C14中的公式:=LOOKUP(2,1/(B1:B12="meat"),C1:C12)

此处,C14中的公式在B列中查找最新的"meat"标记的单元格,并返回C列中的关联值。它在"meat"处找到B9,并相应地返回C9处的值。

公式中最令人费解的部分是"1/(....)"。这个师是什么?这种语法来自哪里?可以在其他地方使用吗?为什么查找值为2

2 个答案:

答案 0 :(得分:8)

这里发生了什么:这个

=LOOKUP(2,1/(B1:B12="meat"),C1:C12)

变成这个

=LOOKUP(2,1/{TRUE;FALSE;FALSE;FALSE;FALSE;FALSE;FALSE;FALSE;TRUE;FALSE;FALSE;FALSE},C1:C12)

成为这个

=LOOKUP(2,{1;#DIV/0!;#DIV/0!;#DIV/0!;#DIV/0!;#DIV/0!;#DIV/0!;#DIV/0!;1;#DIV/0!;#DIV/0!;#DIV/0!},C1:C12)

B1:B12="meat"部分被评估为TRUE和FALSE值的数组。当您在TRUE或FALSE上进行数学运算时,它会变为1或0.将1乘1或0除以1表示所有结果,div / 0表示所有结果。

既然你知道你将拥有一个完全由两件事组成的阵列(1或者div / 0),你可以查看大于1的任何数字,它会返回列表中的最后一个。您可以=LOOKUP(800,...),它仍会返回小于或等于查找值"的最大值,或者在您的情况下为1。

所以这两者有点武断 - 它只是一个大于1的数字。它的关键是创建只包含1和错误的查找数组参数--LOOKUP忽略错误。

二进制搜索

我没有关于此的官方文档,所以这里是非官方版本。 LOOKUP,HLOOKUP和VLOOKUP有一个参数,告诉函数数据是否已排序。如果该参数为False,则该函数将一直查看每个条目,直到结束。如果该参数为True或省略,则该函数使用二进制搜索。这样做 - 论证只存在 - 因为二元搜索比ol'更快。一次一个搜索。

二元搜索的工作原理是找到中间值并根据搜索值对其进行评估。如果中间值较大,则右侧的所有内容都将被丢弃 - 所寻求的值必须在左侧。它需要左半部分并找到它的中间值。如果它更大,它会丢弃右边并保持左边。继续迭代,直到找到值。

那么为什么LOOKUP(2,{1,1,#DIV/0!,1,1,#DIV/0!,1,1},...)会找到最后一个1而不是某个1?我不确切知道MS如何实现他们的二分搜索,所以我必须做出一些假设。我的假设是错误值被抛出数组,并且当存在偶数个条目(没有中间值)时,使用中间左侧的值。这些假设可能是错误的,但它们对结果没有任何影响。

首先,抛弃错误。现在您有这些条目及其原始位置

1  1  1  1  1  1
1  2  4  5  7  8

"中间"数字是1(4)。它小于2(寻求值),所以我们抛弃左边的所有东西并重新处理右边。现在我们有了

1  1  1
5  7  8

中间值为1(7)。它小于2,所以我们抛弃左边的所有内容并重新处理右边的内容。现在我们有了

1
8

我们归结为一个条目,这就是答案。如果搜索到的值高于所有其他值,则二进制搜索将始终返回最后一个值。

答案 1 :(得分:4)

逻辑是这样的:

  • B1:B12="meat"返回一个布尔数组,TRUE表示“meat”,否则返回FALSE
  • 1 / TRUE返回1,而1 / FALSE = 1/0返回#DIV / 0 !,所以你得到一个填充了1和#DIV / 0!的数组,如下图所示。 (此步骤用于将FALSE转换为错误值,以供下一步使用。)

enter image description here

  • 对该数组中的值2执行LOOKUP失败,因为那里没有2,并且因为值未排序。因此,LOOKUP会查找最后一次出现的小于2的数值,忽略任何#DIV / 0!错误值。为什么?谁知道。这是一个未记录的功能,documentation for the LOOKUP function
  • 中未提及

基本上,这个shenanigan依赖于未记录的行为来返回所需的结果。