在excel中找到一系列值

时间:2015-11-04 10:19:25

标签: excel excel-formula excel-2007

我在Excel中有两张不同的纸张,包含300,000个数据。    第一张包含:

    S2_Symbol   Start_Pos   End Position
    STE        254857     267891
    PRI        748578     758962
    ILA        852741     963369
    VIS        789456     796325

第二

   S1_Location
   789460
   852898
   748678

我的输出应该是这样的:

S1_Location   Symbol 
789460         VIS
852898        ILA
748678        PRI

我必须发现S1_location落在S2_location及其相应的符号中。我在Excel中使用了INDEX公式但是对于每个单元格,我必须手动更改参考单元格。我无法做到300,000个数据。

如何在Excel中使用或者我应该使用脚本?

4 个答案:

答案 0 :(得分:2)

此解决方案假设如下:

  • 每个S2 Symbol的开始和结束位置都是唯一的(即分配给每个符号的范围之间没有交集)

  • 第一张表格中的数据位于A1:D17 (根据需要调整公式中的范围)

  • 第二张表格中的数据位于A1:B300010 (根据需要调整公式中的范围)

解决方案要求:

  • 在工作表一中添加工作列。在D2中输入此公式并复制到最后一条记录。

    =ROWS($A$1:$A2)
    

    enter image description here

图。 1

  • 然后在第二个工作表中输入此公式B2并复制到最后一个记录。

    =INDEX( Sheet1!$A$1:$A$17,
    SUMIFS( Sheet1!$D$1:$D$17,
    Sheet1!$B$1:$B$17, "<=" & $A2, Sheet1!$C$1:$C$17, ">=" & $A2 ) )
    

    enter image description here

图。 2

它采取了aprox。向下复制并计算表2中的公式不到14秒。 如图1和图2所示,不需要对表格进行排序。

答案 1 :(得分:1)

假设两张纸都在A1中开始,而第一张纸ColumnB按升序排序,请在第二张B2中尝试:

=INDEX(First!A:A,MATCH(A2,First!B:B))  

复制到西装。它依赖于不精确的匹配。

答案 2 :(得分:1)

假设我们有Sheet1这样:

enter image description here

请注意,Sheet1Start_PosEnd_Pos按升序排序。

Sheet2这样:

enter image description here

然后Sheet2!B2向下的公式可能是:

=INDEX(Sheet1!A:A,IF(MATCH(A2,Sheet1!B:B)>IFERROR(MATCH(A2-(10^-10),Sheet1!C:C),0),MATCH(A2,Sheet1!B:B),NA()))

请参阅MATCHhttps://support.office.com/en-us/article/MATCH-function-e8dffd45-c762-47d6-bf89-533f4a37673a

这个想法是:MATCH没有完全匹配(没有参数match_type)获取最大值的行,该值小于或等于搜索值。因此,在Start_Pos列中,它将获得我们可以从中获取S2_Symbol的行。但是,如果值不在给定范围之外,则应从End_Pos列预先获得一行。

只有一个例外。如果该值与End_Pos列中的值完全相同,则它将返回与Start_Pos列中相同的行。考虑到此异常,我们可以在End_Pos列中搜索稍微小一点的值。感谢Tom Sharpe的评论。

Sheet2!D2向下的公式是:

{=INDEX(Sheet1!A:A,MIN(IF($A2>=Sheet1!$B$2:$B$300000,IF($A2<=Sheet1!$C$2:$C$300000,ROW(Sheet1!$A$2:$A$300000),2^20+1))))}

这是一个根据要求精确制定的数组公式。但是在很多细胞中使用这种性能非常糟糕。但是使用它,Sheet1不需要排序。

基准测试:

拥有以下Sheet1

enter image description here

公式:

A2:A300002="S"&(ROW(A1)-1)*10&"-"&(ROW(A1)-1)*10+7

B2:B300002=(ROW(A1)-1)*10

C2:C300002=B2+7

以及以下Sheet2

enter image description here

公式:

A2:A300002=RANDBETWEEN(0,3000007)

B2:B300002=INDEX(Sheet1!A:A,IF(MATCH(A2,Sheet1!B:B)>IFERROR(MATCH(A2-10^-9,Sheet1!C:C),0),MATCH(A2,Sheet1!B:B),NA()))

请注意先前版本中的-10^-9而不是-10^-10。这是因为我们只有16位精度。在以前的版本中,这是最多6位整数部分,然后是10位小数部分。现在它是最大7位整数部分,然后是9位小数部分。

F9中按Sheet2后计算需要大约2秒(Excel 2007,Windows 7,4核处理器)。

答案 3 :(得分:0)

我会选择这样的东西,如果有的话,会给你第一场比赛: -

=INDEX(First!A:A,MATCH(1,(First!B:B<=A2)*(First!C:C>=A2),0))

假设键和起始值和结束值位于名为First的表单中,查找值从A2开始。

必须使用 Ctrl Shift 输入

输入的数组公式

在回答@pnuts关于需要多长时间的问题时,我已经建立了一个类似的基准,每张表有300,000行,90分钟后已经达到1%,所以它需要大约150个小时才能到达100%或大约一周。这是预期的,因为所需的计算次数是(表1中的行)X(表2中的行)

300,000 X 300,000

但实际上因为乘法适用于完整列,我相信它更正确

300,000 X 1,048,576

即。 &GT; 3000亿。

对较小范围给出良好响应的实用版本如下: -

我定义了三个命名范围Range1,Range2和Range3

=First!$A$1:INDEX(First!$A:$A,MATCH("ZZZ",First!$A:$A))

=First!$B$1:INDEX(First!$B:$B,MATCH(9.9E+307,First!$B:$B))

=First!$C$1:INDEX(First!$C:$C,MATCH(9.9E+307,First!$C:$C))

,修改后的公式为

=INDEX(Range1,MATCH(1,(Range2<=A2)*(Range3>=A2),0))

我正在考虑删除这个答案,但我宁愿把它作为一个反例。