如题,如果一个Excel表格中有很多列,每列有几百上千行数据,每列的行数都不同,有没有一种快速的方法将每一列中最后一行数据提取出来呢?答案是肯定的,网上也有一堆方法,当然用得最多的还是有“函数引用王”之称的LOOKUP函数。比如,提取A列最后一行数据,网上给出的函数为 =LOOKUP(1,0/(A:A<>0),A:A)其实这个函数并不完美,如果当A列最后一行数据为0时,这个函数会查找出它上一行的数据,如果上一行的数据还是0,继续向上查找,直到不为0为止。鉴于此,我对这个函数进行了优化,优化后的函数为 =LOOKUP(2,1/(LEN(A:A)>0),A:A)。
其实这个函数也有问题,如果当A列最后一行数据为1时,这个函数会查找出它上一行的数据,如果上一行的数据还是1,继续向上查找,直到不为1为止。
因此,在实际工作中,如果数据量很大,为保险起见,建议用两个函数互查一下。
对函数不想深入了解的朋友,记住上述函数,就可实现提取一列中最后一行数据的功能,毕竟函数的运行是函数和电脑的事,我们只需要使用即可,没必要深究函数的运算过程。对这个函数感兴趣,想深入了解一下的朋友,不妨我们一起深入剖析一下这个函数,看它到底是如何实现功能的,篇幅有点长,耐心看完,肯定会有收获。
要想了解这个函数,我们先得了解一下LOOKUP函数的基础知识。
一、LOOKUP函数的基础知识
1、LOOKUP函数的基本功能:是在一列数据中查找并引用满足条件的数据;
2、LOOKUP函数的基本语法:LOOKUP(lookup_value, lookup_vector, [result_vector]),即
LOOKUP(找什么,在哪里找,需要哪里的结果)
3、LOOKUP函数的基本原理: “二分法”查找原理;
何为“二分法”查找:

上表中有12个序号,中间值是第6个,即A7单元格的数值16。要查找的序号是15,需要查找出15号对应的姓名及各科成绩。
第1次查找:显然中间值16大于查找值15,LOOKUP函数向上(不包含16)查找,即在A2-A6单元格中查找。(提示:如果数据源个数为单数,那么中间值为数据源个数+1再除以2)。
第2次查找:在A2-A6中,中间值为A4单元格的数值13,中间值13小于查找值15,LOOKUP函数向下查找,即在A5-A6单元格中查找。
第3次查找:在A5-A6中,中间值为A5单元格的数值14,中间值14小于查找值15,LOOKUP函数向下查找,此时就只剩A6单元格了,且与查找值一致,所以就返回A6单元格对应的姓名及各科成绩,函数结束运行。
以上就是LOOKUP函数通过二分法查找的基本逻辑。
4、 LOOKUP函数的基本条件:通过上述分析可以看出,中间值大于查找值,函数就向上查找,忽略下部分;当中间值小于查找值,函数就向下查找,忽略上部分,
因此:LOOKUP函数查找数据的前提条件:数据要升序排列。数字按1、2、3升序排列,字母按A、B、C升序排列,汉字按汉语拼音字母顺序升序排列。

上表中序号列未按升序的方式排序,查出的14号对应的姓名和各科成绩是不正确的。
第一次查找时,14与中间值A7中的19比较,中间值大于查找值,函数向上查找;
第二次查找时,14与中间值A4中的22比较,中间值大于查找值,函数向上查找;
第三次查找时,14与中间值A2中的13比较,中间时小于查找值,函数向下查找;
第四次查找时。14与中间值A3中的15比较,中间值大于查找值,函数向上查找;
查找4次后结束查找,只有13时小于查找值,是最接近查找值的序号,所以结果返回13所对应的姓名和各科成绩。
因此,LOOKUP直接查找时,“lookup_vector”中的数据一定要升序排列。
5、LOOKUP函数的基本特点:(1)LOOKUP函数在查找过程中会忽略错误值;(2)当查不到与查找值完全相同的数据时,LOOKUP函数会查找出最后一个小于查找值的数。
了解了LOOKUP函数的基本知识后,现在可以分析一下前面提到的两个函数了。
二、函数=LOOKUP(1,0/(A:A<>0),A:A)
上面这个函数翻译成大白话就是:在0/(A:A<>0)中,查找1,然后返回A:A列中与查找值1对应的数据。那么上面这个0/(A:A<>0)是什么意思呢?其实我们可以理解为给A:A列的数据编号。
A:A<>0的意思就是将A列从A1单元格开始,逐一判断单元格中的内容是否不为0(大于小于0就是不为0,EXCEL将没有内容的空单元格判断为单元格内容为0),也就是检查单元格是否空单元格,如果不是空单元格,条件成立就返回TRUE,如果是空单元格,条件不成立就返回FALSE,在EXCEL中,TRUE和FALSE是当做数字1和0,可以参与计算。
0/ (A:A<>0)的意思就是0÷1或0÷0,在数学中0÷1=0,0÷0不符合计算要求,EXCEL会显示为错误值#DIV/0! 这样通过0/ (A:A<>0)就将空单元格标记为#DIV/0!,非空单元格标记为0。
前面讲了,LOOKUP函数在查找时会忽略掉错误值。那么0/(A:A<>0)实质上就是一组全部为0的数据。那么上面的函数其实就是在一组0里面找1,因为全部都是0,就无所谓升序还是降序了,中间值0始终小于查找值1,LOOKUP函数一直向下二分法查找,最终只能找到最后一个0,最后一个0在A列所对应的值就是函数的最终结果。
从上表可以看出,如果A列中的数字正好是0,LOOKUP函数会返回为错误值而忽略掉,如果A列最后一行的数据是0,LOOKUP会返回上一行的数据,如果上一行还是0,再往上一行,直到不为0为止,上表I2单元格中,返回的并不是A13中的数据,而是A12中的数据。因此这个函数有缺陷:当一列最后一行的数据正好是0,LOOKUP函数会给出错误答案。
三、函数=LOOKUP(2,1/(LEN(A:A)>0),A:A)
读懂了上面的函数,这个函数就很好理解了。
LEN(A:A)>0,的意思是在A列中从A1开始,逐一判断单元格中的字节数,字节数大于0,条件成立,返回TRUE,单元格字节数等于0,条件不成立,返回FALSE;再用1除以1或0,最终将有字节的单元格标记为1,没字节的单元格标记为错误值并将其忽略,然后LOOKUP函数在一组1里面查找数字2,最终返回最后一行。
同样,如果一列最后一行数据是数字1,LOOKUP函数同样会给出错误的结果。
因此,在实际工作中,如果数据量很大,为保险起见,建议用两个函数互查一下。