除了一列以外,查找公式效果很好
我有一个在这里上传的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,但用它你想要的结果似乎可以实现如下:
- 为了缩短公式并减less计算量,我在Report C5“Table”和D5
=VLOOKUP(B5,TblA,2,1)
。 - 我也在5.2.0到5.7.30列的ColumnH(“ColD”)的右侧立即插入了一列,并且在列H上应用了Text To Columns,以
-
作为分隔符。 -
然后我申请报告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向右移动的话,这种调整就没有必要了。 -
在E13中,我将比赛从精确的改为了更高的一个(最后
0
到-1
)。 - 对于数字,我骗了5.2.0的K23,把它从21-22改成了5.7.30到22,但是对于其他列,这样的绑定可以像对待ColD一样进行处理。