本帖最后由 看见星光 于 2014-8-20 12:41 编辑
第二节:VLOOKUP查询符合条件的多个结果。
通过第一节的内容,我们初步认识了VLOOKUP(ROW(A1),……)的技巧。 这一节,我们需要利用这个技巧,回答开篇所提到的第一个问题。 VLOOKUP能否查询符合条件的多个数值?就像经典数组套路INDEX+SMALL+IF那样?
如上图,我们需要提取C列符合F1班级的姓名,放入E4:E15。
通常我们会使用INDEX+SMALL+IF的数组套路: E4=INDEX(C:C,SMALL(IF($B$1:$B$15=F$1,ROW($1:$15),4^8),ROW(A1)))&""
如果使用VLOOKUP,我们应该怎么做? 其实也简单。 我们还是如第一节那般,先采用辅助列的方式。 A2=COUNTIF(B$2:B2,F$1) 向下填充。 E4=IFERROR(VLOOKUP(ROW(A1),A:C,3,0),"") 向下填充。
结果……如下:
这里,咱们依然利用了VLOOKUP(ROW(A1)……)的技巧。 第一个公式:=COUNTIF(B$2:B2,F$1) 我们使用COUNTIF函数,配合相对引用的原理,统计班级的累计重复次数。 第二个公式:=IFERROR(VLOOKUP(ROW(A1),A:C,3,0),"") 我们通过VLOOKUP查询ROW(a1)(1,2,3,4,5,上山打老……),来返回与之相对应的C列姓名结果,最后外套IFERROR函数,屏蔽VLOOKUP查询不到结果而返回的错误值,使之返回空白。
在数据量大时,我们使用INDEX+SMALL数组查询数据,难免卡机,此时不妨使用VLOOKUP+辅助列的方式,当然,辅助列我们不能再使用低效函数COUNTIF了,我们可以使用这样的公式: =(B2=$F$1)+A1
==========我是往事如烟的分割线==========
理解了辅助列的意义,加深了VLOOKUP(ROW(A1),……)技巧的理解,我们下面要做的,依然是丢掉辅助列,把辅助列的内容,放到公式中,直接使用一个公式得出结果。
我们依然可以使用OFFSET对COUNTIF的统计范围进行多维引用,比如: =COUNTIF(OFFSET(B$2,,,ROW($1:$14)),F$1) 这个公式的意思,是使用COUNTIF对B2:B2,B2:B3,B2:B4……直至B2:B15的范围内,分别统计F1数值的重复次数,得出来的结果,自然是和辅助列是一致的。
我们将这一段公式,放入VLOOKUP函数公式中: =IFERROR(VLOOKUP(ROW(A1),IF({1,0},COUNTIF(OFFSET($B$2,,,ROW($1:$14)),$F$1),$C$2:$C$15),2,0),"") 如此,这个公式也便正式写完了。
==========我是如烟往事的分割线==========
当然,如果您确实了解透彻了VLOOKUP的心,关于VLOOKUP查询符合条件的多个数值,我们其实也可以写成这样:
=IFERROR(VLOOKUP($F$1,OFFSET($B$1:$C$1,SMALL(IF($B$1:$B$15=$F$1,ROW($1:$15)-1),ROW(1:1)),,15),2,0),"") 或者这样: =IFERROR(VLOOKUP($F$1,INDIRECT("b"&SMALL(IF($B$1:$B$15=$F$1,ROW($1:$15)),ROW(1:1))&":c15"),2,0),"")
我们结合第二个函数套路来稍微解释下此中过程。
SMALL(IF($B$1:$B$15=$F$1,ROW($1:$15)),ROW(1:1)) IF函数判断B1:B15的值,是否等于F1,并返回相对应的行数序号ROW(1:15),或者FALSE。(为什么将IF的假值留白,而不是像许多学友那样习惯性的输入4^8之类?因为这里没有必要撒,逻辑值天生就比数值大不是……) SMALL函数,按IF函数的结果,在公式下拉的过程中,依次从小到大取数,即ROW(1:1),ROW(2:2),取得最小值,第二小值……。
INDIRECT函数,搭配SMALL所取得的结果,完成对VLOOKUP查找范围从大到小的限定。 比如此例中的INDIRECT(“B”&13&”:C15”),INDIRECT(“B”&14&”:C15”)……。 由于VLOOKUP天生只取首个匹配结果,所以咱们通过查找范围的精确限定,便可以使它依次取得所有符合条件的结果……
最后外套IFERROR函数,屏蔽错误值,使之返回空白。 ... .. .
好啦,现在,咱们可以很清楚的知道,关于VLOOKUP无法提取符合条件多个数值的说法,是不正确的。呵呵。(我每次发呵呵,都会想起胡剑么么哒,唉)
|