神秘的使用LOOKUP

我一直在使用这个Excel公式多年。 它工作正常,但我想明白为什么它的作品! 该公式用于查找列表中最后一个关联的值。 例如:

宏用法示例。

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

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

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

这是发生了什么:这个

 =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进行math运算时,它将变成1或0.将1除以1或0将返回1,对于所有的结果返回1,对于所有的假设返回div / 0。

现在你知道你将有一个正好两个东西(一个1或一个div / 0)的数组,你可以查找任何大于1的数字,它将返回列表中的最后一个数字。 你可以=LOOKUP(800,...) ,它仍然会返回“小于或等于查找值的最大值”,或者在你的情况1。

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

二进制search

我没有这方面的官方文档,所以这里是非官方的版本。 如果数据被sorting,LOOKUP,HLOOKUP和VLOOKUP就有一个参数来告诉函数。 如果该参数是False,则该函数一直查看每个条目直到结束。 如果该参数为True或省略,则该函数使用二进制search。 它是这样做的 – 这个论点只存在 – 因为二进制search比ol一次一个search要快。

二分search通过find中间值并根据所寻求的值对其进行评估而起作用。 如果中间值较大,则放弃右侧的所有内容 – search值必须在左侧。 它取左边的一半,find它的中间值。 如果它更大,则丢弃右边并保持左边。 继续迭代,直到find值。

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

首先,抛出错误。 现在你有这些条目和他们原来的位置

 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 

我们只有一个入口,所以这就是答案。 如果查找的值高于所有其他值,则二分查找将始终返回最后一个值。

逻辑是这样的:

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

在这里输入图像描述

  • 对该数组中的值2进行查找失败,因为在那里没有2,并且因为这些值是未分类的。 相反,LOOKUP会查找小于2的数值的最后一次出现,忽略任何#DIV / 0! 错误值。 为什么? 谁知道。 这是一个未logging的function, LOOKUPfunction的文档中没有提到

所以基本上,这个shenanigan依靠无证行为来返回所需的结果。