|
年纪大了,思维比较慢,打字也比较慢,当我写好下面东西准备发帖的时候,发现21楼已经把公式解析了。我写的的思路稍有不同,我想还是发了出来,提供大家从另一角度来学习21楼的公式的精髓,说得不对请指正:
1.首先要指出的是,这是一个真正意义上的数组公式:在指定的区域里输入同一个公式(而不是通过右拖下拉把公式扩充到区域里),根据规律在不同的单元格产生不同的数据。本题要求对19行的数据进行处理,故在连续19个单元格里同时输入数组公式。
2.其次公式的关键在于LARGE(IF(MATCH(Data,Data,0)=ROW($A$1:$A$19),COUNTIF(Data,Data)*1000000-IF(MATCH(Data,Data,0)=ROW($A$1:$A$19),ROW($A$1:$A$19))*10000+ROW($A$1:$A$19)),ROW($A$1:$A$19)),
3.而关键中的关键即核心式子是COUNTIF(Data,Data)*1000000-IF(MATCH(Data,Data,0)=ROW($A$1:$A$19),ROW($A$1:$A$19))*10000+ROW($A$1:$A$19)),它把同一数字出现次数(COUNTIF(Data,Data))加了个大权数——放大1000000倍(我称之“大权”),把各数第一次出现的位置次序(IF(MATCH(Data,Data,0)=ROW($A$1:$A$19),ROW($A$1:$A$19)))也加了权,但只放大10000倍((我称之“小权”。注意:某数再次出现没有加此权!),两个加权后的数据对应相减,实际上已经把19个数据根据次数和次序的要求规律进行了预处理,最后加上原始数据在原区域顺序号——ROW($A$1:$A$19),以本例A2:A20的数据,核心式子得到的是{2990001;1980002;2970003;960004;3000005;1940006;3000007;3000008;910009;3000010;2890011;880012;2000013;1860014;850015;3000016;2000017;2000018;3000019},(注意:这里可见第5个数3000005、第7个数3000007……并没有加上放大10000倍的那个权数,因为它们是6和2……等的再次出现)
4.不要紧,公式马上通过关键公式中第一个括弧里if()判断——IF(MATCH(Data,Data,0)=ROW($A$1:$A$19),COUNTIF(Data,Data)……ROW($A$1:$A$19))把这些只加大权没加小权的数据“屏蔽”掉,得到{2990001;1980002;2970003;960004;FALSE;1940006;FALSE;FALSE;910009;FALSE;2890011;880012;FALSE;1860014;850015;FALSE;FALSE;FALSE;FALSE}
5.接着,整个关键部分LARGE(IF(……),ROW($A$1:$A$19))对上面的数组进行了排序,得到{2990001;2970003;2890011;1980002;1940006;1860014;960004;910009;880012;850015;#NUM!;#NUM!;#NUM!;#NUM!;#NUM!;#NUM!;#NUM!;#NUM!;#NUM!}。
6.最后,通过mod()函数求出余数,也即各数在原始区域的位置次序号,并由index()函数返回相应位置的原始数据,这就不用多说。值得提一下的是,这里得到的余数(即位置次序号)也是一数组,它将按照顺序依次在输出区域各自的单元格里输出最后结果。
7.公式的开头部分IF(ROW($A$1:$A$19)>SUM(IF(MATCH(Data,Data,0)=ROW($A$1:$A$19),1)),"",……),应该比较容易理解:若输出结果的单元格行号大于原始数据区域里不同数据的个数便以空白显示,否则……,换一句说,如果19个原始数据全不相同,那么输出区域将填满19的数,并且次序与原始数据区域完全相同;如果19个原始数据全部相同,那么输出区域将只在第一个单元格里输出这一个数,其余空白。
8.自定义名称:MaxRow=MAX(IF(LEN($A3:$A997)>0,ROW(Sheet3!$A3:$A997)))得出最后一个数据的行号(空白单元格字符数为0);Data=INDIRECT("a"&MaxRow-18&":a"&MaxRow),用INDIRECT得到动态的数据区域。
总之,这是一个非常好的数组公式,比起我站在6楼肩膀上修改而来的公式优点很多,它不会因为要统计的原始数据区域里少了某个数而出现12楼的问题,数值的大小也不局限在0~9十个数字,只是如果要改变统计区域大小的话,除了修改自定义名称的参数外,还要修改公式和调整输出区域(还好,并不算很麻烦)。
看官注意,我上面的是分析,电脑的实际运行步骤并不是按我上面分析的走!
(顺便提一句,13楼的公式也是非常好的公式,他不用自定义名称,也很直观,只是统计区域动态“动”的不够到位,下限动起来了,上限始终老地方踏步——后续单元格输入数据的话,统计范围不断在扩大。修改难度也不大,只要把INDIRECT("A2:A"&COUNT(A:A)+1)改成INDIRECT("A"&COUNT(A:A)-17&":A"&COUNT(A:A)+1)就完全动起来啦。)
[ 本帖最后由 wangjguo44 于 2010-7-15 14:20 编辑 ] |
|