如何使VLOOKUP返回* last *匹配?


12

我曾经使用过VLOOKUP,但这一次我遇到了挑战。我不希望第一个匹配的值,但最后一个。怎么样?(我正在使用LibreOffice Calc,但MS Excel解决方案应该同样有用。)

原因是我有两个带有数千行的文本列,假设一个是交易收款人的列表(亚马逊,Ebay,雇主,杂货店等),另一个是支出类别的列表(工资,税金,家庭,房租等)。有些交易并非每次都有相同的支出类别,我想获取最近使用的一种。请注意,该列表没有按任何列排序(实际上是按日期排序),我不想更改排序顺序。

我所拥有的(不包括错误处理)是通常的“首次匹配”公式:

=VLOOKUP( 
[payee field] , [payee+category range] , [index of category column] , 
0 )

我已经看到了这样的解决方案,但#DIV/0!出现错误:

=LOOKUP(2 , 1/( [payee range] = [search value] ) , [category range] )

解决方案可以是任何公式,不一定是VLOOKUP。我也可以交换收款人/类别列。请排序列保持不变。


奖励积分是一种选择最频繁而不是最后一个值的解决方案!

Answers:


3

您可以使用数组公式从最后匹配的记录中获取数据。

=INDEX(IF($A$1:$A$20="c",$B$1:$B$20),MAX(IF($A$1:$A$20="c",ROW($A$1:$A$20))))

使用Ctrl+ Shift+ 输入公式Enter

这类似于a的INDEX/ MATCH构造VLOOKUP,但使用条件MAX代替MATCH

请注意,这假设您的表从第1行开始。如果数据从另一行开始,则需要ROW(...)通过减去第一行和第1行之间的差来调整部分。


我对字面意义上的“ c”感到困惑-我认为评估始终是错误的,那么它到底能做什么?
2014年

我已经测试了您的建议(并检查了它是否被接受为数组公式)。我假设A上校是收款人,B上是类别,对吗?不幸的是,LibreOffice返回了“ ERR:502”,它转换为“无效的参数:函数参数无效。例如,SQRT()函数的负数,为此,请使用IMSQRT()”。我检查了LibreOffice中所有具有该名称的功能是否存在,但我想知道LibreOffice是否IF无法处理数组。
2014年

抱歉,文字“ c”只是您要匹配的收款人姓名。那是我玩的样本数据的遗物。我假设它将替换为工作表中的单元格引用。
Excellll

@ TorbenGundtofte-Bruun关心分享您使用的配方吗?如果可以看到它,则可以对它进行故障排除。另外,您始终可以尝试逐步浏览公式,Evaluate Formula以查看公式的哪一部分会产生错误。此功能存在于Excel中,如果LibreOffice Calc没有相同的功能,我会感到惊讶。
Excellll 2014年

我的原始公式很简单,这就是为什么它不够用的原因:-) =VLOOKUP(J1061;$J$2:$K$9999;2;0)其中col J包含收款人,而col K包含类别。它按预期返回第一个匹配项。
Torben Gundtofte-Bruun 2014年

2

(在这里回答,因为没有单独的问题来排序数据。)

如果数据进行排序,你可以使用VLOOKUPrange_lookup参数TRUE(或省略,因为它是默认值),这是正式用于Excel描述为“搜索近似匹配”。

换句话说,对于排序的数据:

  • 将最后一个参数设置为FALSE返回第一个值,并且
  • 将最后一个参数设置为TRUE返回最后一个值。

这在很大程度上没有记录和模糊不清,但是可以追溯到VisiCalc(1979),并且今天至少在Microsoft Excel,LibreOffice Calc和Google Sheets中占有。最终归因LOOKUP于VisiCalc 的最初实现(以及VLOOKUPand和HLOOKUP),当时没有第四个参数。该值是通过二进制搜索(使用包含左边界和专有右边界(常见且优雅的实现))找到的,从而导致此行为。

从技术上讲,这意味着从候选区间开始搜索[0, n),其中interval n是数组的长度,而循环不变条件是A[imin] <= key && key < A[imax](左边界<=目标,右边界在结束后开始一个,即>目标;进行验证,要么检查端点之前的值,要么检查之后的结果),然后相继平分并选择保留该不变性的任何一侧:通过排除一侧,直到到达带有1项的间隔[k, k+1),并且算法然后返回k。不一定是完全匹配(!):这只是下面最接近的匹配。如果存在重复的匹配项,则会导致返回最后一个匹配项,因为它要求下一个值更大而不是键(或数组的末尾)。在重复的情况下,您需要采取一些措施,这是合理且易于实现的。

在旧的Microsoft知识库文章(强调中已添加)中明确说明了此行为:“ XL:如何返回数组中的第一个或最后一个匹配项”(Q214069):

您可以使用LOOKUP()函数在已排序数据的数组中搜索值,然后返回另一个数组中该位置包含的对应值。如果在数组中重复查找值,它将返回遇到的最后一个匹配项。对于VLOOKUP(),HLOOKUP()和LOOKUP()函数,此行为是正确的。

以下是一些电子表格的官方文档;都没有说明“最后匹配”行为,但Google表格文档中暗示了这种行为:

  • 微软Excel

    TRUE假定表中的第一列以数字或字母顺序排序,然后搜索最接近的值

  • Google表格

    如果is_sortedTRUE或省略,则返回最接近的匹配项小于或等于搜索键)


最近的比赛的事情被我逼疯了!
davetapley18年

1

如果搜索数组中的值是连续的(即,您正在寻找最大值,例如最新日期),则甚至不需要使用INDIRECT函数。试试这个简单的代码:

=MAX(IF($A$1:$A$20="c",$B$1:$B$20,)

再次,使用CTRL + SHIFT + ENTER输入公式


0

我最常去的地方。不知道它是否可以在libreOffice中工作,但似乎可以在excel中工作

= INDEX($ B $ 2:$ B $ 9,MATCH(MAX(-($ A $ 2:$ A $ 9 = D2)* COUNTIFS($ B $ 2:$ B $ 9,$ B $ 2:$ B $ 9,$ A $ 2 :$ A $ 9,D2)),-($ A $ 2:$ A $ 9 = D2)* COUNTIFS($ B $ 2:$ B $ 9,$ B $ 2:$ B $ 9,$ A $ 2:$ A $ 9,D2 ),0))

列A为收款人,列B为类别,D2为您要过滤的收款人。我不确定为什么要在上面的函数中添加额外的换行符。

我找到最后一个单元格的功能如下:

= INDIRECT(“ B”&MAX(-($ A $ 2:$ A $ 9 = D2)* ROW($ A $ 2:$ A $ 9)))

间接让我指定要返回的列并直接查找行(因此,我不需要减去标题行的数量。

这两个功能都需要使用Ctrl + Shift + Enter输入


0
=LOOKUP([payee field] , [payee range] , [category range])

这将为您带来最后的价值

迟到3年是否可以获得奖励积分?


-1

您遇到了#DIV/0!错误,因为您应该这样写公式:

=LOOKUP(2;IF(([payee range] = [search value]);1;"");[category range])

这将起作用,并将找到最后一个匹配项。

([payee range] = [search value]) :布尔矩阵TRUE / FALSE

IF(([payee range] = [search value]);1;"") :伪布尔矩阵1 /“”

=LOOKUP(2; {pseudo-boolean matrix 1/""} );[category range]):总是返回最后一个1位置


LOOKUP仅适用于排序列表,比较结果将以1非排序方式生成s和空格列表,因此不会给出正确的结果。
朱塔什(MátéJuhász)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.