除了一列以外,查找公式效果很好

我有一个在这里上传的excel文件

http://www58.zippyshare.com/v/99974349/file.html 

该公式工程很好,除了一个值降序的列。

 =INDEX( INDIRECT("'"&LOOKUP(B5,TblA)&"'!A6:A36"), LOOKUP(9.99999999999999E+307, SEARCH("-"&C8&"-","-"&INDIRECT("'"&LOOKUP(B5,TblA)&"'!C6:C36")&"-"), ROW(C6:C36)-ROW(C6)+1)) 

让我解释一下excel文件。

我有一个主要的工作表“报告” ,其他4张表对应4个年龄组。 – 4.2.0至4.7.30,4.8.0至5.1.30,5.2.0至5.7.30和5.8.0至6.1.30。 根据“报告”表中的年龄(B5),我select其中一张从中选取值。 我使用包含所有工作表名称的表格名称TblAselect正确的工作表,并且在工作表“报告”中从A24到B27定义。

在上传的示例表中,B5包含值5.7,这意味着我们必须select表单5.2.0到5.7.30。

现在从表格5.2.0到5.7.30,我必须在“报告”中input每个原始分数的相应标准分数(第一列)。

这里是步骤:

A.在工作表“报告”C7至C15中input原始分数

B.search根据年龄(B5细胞)的不同,在5.2.0至5.7.30的情况下,年龄为5.7岁

C.通过挑选4张相应的栏目,从原始分数中填入标准分数。 例如,如果Col1的原始分数是25(C7),则从5.2.0到5.7.30中selectCol1的标准分数,然后input到D7中,依此类推。

D.这样所有的标准分数都填入D7到D15。

因为如果您在5.2.0到5.7.30中观察到ColD,那么除了工作表“报告”中的D13以外,该公式工作得很好,因此按降序排列。

如何更改公式以适应这个独特的列?

那么,这不是真的是导致错误的顺序,这是因为你没有任何结果! 你使用的公式试图find-159-在年龄表中根本找不到的。 你真的需要一些东西来看看范围,所以如果你有159,当你尝试与139-160匹配时,它会返回一个积极的结果。

我已经做了一个从较小的公式build立它的公式,但是当组装时,重复单位使其令人畏惧…此外,这是一个数组公式,所以你需要使用Ctrl + Shift + Enter来按预期工作。 您仍然可以拖动公式。

 =INDEX( INDIRECT("'"&LOOKUP($B$5,TblA)&"'!A6:A36"), IFERROR( MATCH( C7, INDEX( INDIRECT("'"&LOOKUP($B$5,TblA)&"'!B6:J36"), 0, MATCH(B7,INDIRECT("'"&LOOKUP($B$5,TblA)&"'!B5:J5"),0) )*1, 0 ), MATCH( 1, IF( 1*LEFT( INDEX( INDIRECT("'"&LOOKUP($B$5,TblA)&"'!B6:J36"), 0, MATCH(B7,INDIRECT("'"&LOOKUP($B$5,TblA)&"'!B5:J5"),0) ), FIND( "-", INDEX( INDIRECT("'"&LOOKUP($B$5,TblA)&"'!B6:J36"), 0, MATCH(B7,INDIRECT("'"&LOOKUP($B$5,TblA)&"'!B5:J5"),0) ) )-1 )<=C7, 1, 0 )* IF( 1*MID( INDEX( INDIRECT("'"&LOOKUP($B$5,TblA)&"'!B6:J36"), 0, MATCH(B7,INDIRECT("'"&LOOKUP($B$5,TblA)&"'!B5:J5"),0) ), FIND( "-", INDEX( INDIRECT("'"&LOOKUP($B$5,TblA)&"'!B6:J36"), 0, MATCH(B7,INDIRECT("'"&LOOKUP($B$5,TblA)&"'!B5:J5"),0) ) )+1, 100 )>=C7, 1, 0 ) ,0 ) ) ) 

单行版本…

 =INDEX(INDIRECT("'"&LOOKUP($B$5,TblA)&"'!A6:A36"),IFERROR(MATCH(C7,INDEX(INDIRECT("'"&LOOKUP($B$5,TblA)&"'!B6:J36"),0,MATCH(B7,INDIRECT("'"&LOOKUP($B$5,TblA)&"'!B5:J5"),0))*1,0),MATCH(1,IF(1*LEFT(INDEX(INDIRECT("'"&LOOKUP($B$5,TblA)&"'!B6:J36"),0,MATCH(B7,INDIRECT("'"&LOOKUP($B$5,TblA)&"'!B5:J5"),0)),FIND("-",INDEX(INDIRECT("'"&LOOKUP($B$5,TblA)&"'!B6:J36"),0,MATCH(B7,INDIRECT("'"&LOOKUP($B$5,TblA)&"'!B5:J5"),0)))-1)<=C7,1,0)*IF(1*MID(INDEX(INDIRECT("'"&LOOKUP($B$5,TblA)&"'!B6:J36"),0,MATCH(B7,INDIRECT("'"&LOOKUP($B$5,TblA)&"'!B5:J5"),0)),FIND("-",INDEX(INDIRECT("'"&LOOKUP($B$5,TblA)&"'!B6:J36"),0,MATCH(B7,INDIRECT("'"&LOOKUP($B$5,TblA)&"'!B5:J5"),0)))+1,100)>=C7,1,0),0))) 

你可以注意到有一些重复块,即:

 INDIRECT("'"&LOOKUP($B$5,TblA)&"'!B6:J36") 

对于表名;

 INDEX( INDIRECT("'"&LOOKUP($B$5,TblA)&"'!B6:J36"), 0, MATCH(B7,INDIRECT("'"&LOOKUP($B$5,TblA)&"'!B5:J5"),0) ) 

这是一个更大的块,使公式更灵活一点(它会自动select正确的列,例如,如果您将B8 Exclusion更改为Col1 ,公式将自动调整自己)

如果我打电话给第一Sheet和第二张Column ,它会变得更短,也许更容易理解:

 =INDEX( Sheet, IFERROR( MATCH( C7, Column*1, 0 ), MATCH( 1, IF( 1*LEFT( Column, FIND( "-", Column )-1 )<=C7, 1, 0 )* IF( 1*MID( Column, FIND( "-", Column )+1, 100 )>=C7, 1, 0 ) ,0 ) ) ) 

要么

 =INDEX(Sheet,IFERROR(MATCH(C7,Column*1,0),MATCH(1,IF(1*LEFT(Column,FIND("-",Column)-1)<=C7,1,0)*IF(1*MID(Column,FIND("-",Column)+1,100)>=C7,1,0),0))) 

免责声明:我不确定是否有任何方法可以使这个更短,但我想,只要它正在工作^^

你可以在这里下载你的更新表。


说明:

正如我之前提到的,这个公式是以几个较小的公式为基础的,而且还有很多重复的公式。

 INDIRECT("'"&LOOKUP($B$5,TblA)&"'!B6:J36") 

正如你已经知道的那样(这是你自己公式的一部分的变化),这给了包含所有不同年龄段的区域。 使用它和下面,我们得到这个:

 INDEX( INDIRECT('"&LOOKUP($B$5,TblA)&"'!B6:J36"), 0, MATCH(B7,INDIRECT("'"&LOOKUP($B$5,TblA)&"'!B5:J5"),0) ) 

成:

 INDEX( 'Sheet'!B6:J36, 0, MATCH(B7,'Sheet'!B5:J5,0) ) 

'Sheet'!B6:J36任意一列, MATCH(B7,'Sheet'!B5:J5,0)返回第n列,取值为B7 (在电子表格Col1的情况下),并将其Col1 'Sheet'!B5:J5 ,给出1 。 以上将返回范围'Sheet'!B6:B36 。 让我们把它放在公式中:

 =INDEX( 'Sheet'!A6:A36, IFERROR( MATCH( C7, 'Sheet'!B6:B36*1, 0 ), MATCH( 1, IF( 1*LEFT( 'Sheet'!B6:B36, FIND( "-", 'Sheet'!B6:B36 )-1 )<=C7, 1, 0 )* IF( 1*MID( 'Sheet'!B6:B36, FIND( "-", 'Sheet'!B6:B36 )+1, 100 )>=C7, 1, 0 ) ,0 ) ) ) 

这个公式本身就是一个巨大的INDEX公式,范围是'Sheet'!A6:A36 ,行号是IFERROR大集团。 IFERROR()的第一部分首先被评估:

 MATCH( C7, 'Sheet'!B6:B36*1, 0 ) 

这应该很容易理解。 它查找原始分数(从C7 )到我们之前获得的范围内,时间1将所有内容都转换为数字(您不能查找数字和文本并期望匹配)。 因此,如果数字完全匹配,它将返回find的原始分数的行号,并将其提供给INDEX() 。 例如,如果第一行被返回,我们得到:

 =INDEX('Sheet'!A6:A36,1) 

这是'Sheet'!B6 。 如果没有匹配(即未find原始分数), MATCH将返回一个错误。 这就是IFERROR的第二部分:

 MATCH( 1, IF( 1*LEFT( 'Sheet'!B6:B36, FIND( "-", 'Sheet'!B6:B36 )-1 )<=C7, 1, 0 )* IF( 1*MID( 'Sheet'!B6:B36, FIND( "-", 'Sheet'!B6:B36 )+1, 100 )>=C7, 1, 0 ) ,0 ) 

这个MATCH试图在似乎是两个IF的情况下find1 ; 第一个是:

 IF( 1*LEFT('Sheet'!B6:B36,FIND("-",'Sheet'!B6:B36)-1)<=C7 , 1 , 0) 

FIND("-",'Sheet'!B6:B36)-1'Sheet'!B6:B36列中获取最后一个字符的位置'Sheet'!B6:B36

有了这些值,这个FIND将返回:

 12-13 -> 2 145-155 -> 3 1567-1865 -> 4 

IF因此变成:

 IF( 1*LEFT('Sheet'!B6:B36,{2,3,4})<=C7 , 1 , 0) 

注意这里的大括号。 他们表示一个数组,这就是为什么这是一个数组公式。 然后LEFT提取所有的字符- (记住你的另一个问题,我回答了一个非常相似的技术):

 12-13 -> 2 -> 12 145-155 -> 3 -> 145 1567-1865 -> 4 -> 1567 

这是…

 IF( 1*{12,145,1567}<=C7 , 1 , 0) 

再次, 1*将其转换为实际的数字,因为LEFT是默认返回文本字符。 这样做很重要,因为我们要使用比较器<= ,所以如果C7左边的值(原始分数),那么IF应该返回1 ,否则返回0 。 假设原始分数为154 。 结果将是:

 IF( {12,145,1567}<=154 , 1 , 0) IF( {TRUE,TRUE,FALSE} , 1 , 0) {1,1,0} 

我刚刚意识到,公式可以做得更短xD无论如何,我们稍后会看到。 下一个IF以类似的方式运行,但检查- :右侧的值。

 IF( 1*MID('Sheet'!B6:B36,FIND("-",'Sheet'!B6:B36)+1,100)>=C7 , 1 , 0) 

用… FIND MID('Sheet'!B6:B36,X,100)12-13→4→13 145-155→5→155 1567-1865→6→1865

你可以注意到,如果你有超过100个字符的东西,这个公式将停止工作。 无论如何, IF因此变成:

 IF( {13,155,1865}>=154 , 1 , 0) IF( {FALSE,TRUE,TRUE} , 1 , 0) {0,1,1} 

现在我们有了这些,以前的MATCH变成了:

 MATCH( 1 , {1,1,0}*{0,1,1} , 0) 

一些简单的math把它变成:

 MATCH( 1 , {0,1,0} , 0) 

那里1的位置是什么? 没错,位置2!

我们原来的公式变成:

 =INDEX( 'Sheet'!A6:A36 , IFERROR( #Error! , 2 ) ) 

所以,如果一开始没有find,它将返回一个错误(在这种情况下#N/A ),而是返回2=INDEX( 'Sheet'!A6:A36 , 2 )给出'Sheet'!A7


稍短的版本是:

 =INDEX(INDIRECT("'"&LOOKUP($B$5,TblA)&"'!A6:A36"),IFERROR(MATCH(C7,INDEX(INDIRECT("'"&LOOKUP($B$5,TblA)&"'!B6:J36"),0,MATCH(B7,INDIRECT("'"&LOOKUP($B$5,TblA)&"'!B5:J5"),0))*1,0),MATCH(1,(1*LEFT(INDEX(INDIRECT("'"&LOOKUP($B$5,TblA)&"'!B6:J36"),0,MATCH(B7,INDIRECT("'"&LOOKUP($B$5,TblA)&"'!B5:J5"),0)),FIND("-",INDEX(INDIRECT("'"&LOOKUP($B$5,TblA)&"'!B6:J36"),0,MATCH(B7,INDIRECT("'"&LOOKUP($B$5,TblA)&"'!B5:J5"),0)))-1)<=C7)*(1*MID(INDEX(INDIRECT("'"&LOOKUP($B$5,TblA)&"'!B6:J36"),0,MATCH(B7,INDIRECT("'"&LOOKUP($B$5,TblA)&"'!B5:J5"),0)),FIND("-",INDEX(INDIRECT("'"&LOOKUP($B$5,TblA)&"'!B6:J36"),0,MATCH(B7,INDIRECT("'"&LOOKUP($B$5,TblA)&"'!B5:J5"),0)))+1,100)>=C7),0))) 

因为(a>b)*(c>b)已经返回0和1,因为TRUE乘以TRUE在excel中给出1 ,所以我实际上删除了内部IF

在Excel 2007中,公式正在返回大量的循环引用警告,因此可能值得为Excel版本添加标签。 我是Excel 2007,但用它你想要的结果似乎可以实现如下:

  1. 为了缩短公式并减less计算量,我在Report C5“Table”和D5 =VLOOKUP(B5,TblA,2,1)
  2. 我也在5.2.0到5.7.30列的ColumnH(“ColD”)的右侧立即插入了一列,并且在列H上应用了Text To Columns,以-作为分隔符。
  3. 然后我申请报告E7并复制到E15:

    =INDEX(INDIRECT("'"&D$5&"'!A6:A36"),MATCH(C7,INDIRECT("'"&D$5&"'!"&CHAR(ROW()+59)&"6:"&CHAR(ROW()+59)&"36"),0))

    并将最后三排中的59秒调整为60秒。 如果ColumnI向右移动的话,这种调整就没有必要了。

  4. 在E13中,我将比赛从精确的改为了更高的一个(最后0-1 )。

  5. 对于数字,我骗了5.2.0的K23,把它从21-22改成了5.7.30到22,但是对于其他列,这样的绑定可以像对待ColD一样进行处理。