【问题标题】:Excel Formula OptimisationExcel公式优化
【发布时间】:2013-10-03 21:29:44
【问题描述】:

我不是 excel 专家,经过一些研究,我想出了这个公式来查看两组不同时间的相同数据。然后它会显示最新数据列表中但不在旧列表中的新条目。

这是我的公式:

  {=IF(ROWS(L$4:L8)<=(SUMPRODUCT(--ISNA(MATCH($E$1:$E$2500,List1!$E$1:$E$2500,0)))),
    INDEX(E$1:E$2500,
    SMALL(IF(ISNA(MATCH($E$1:$E$2500&$F$1:$F$2500,List1!$E$1:$E$2500&List1!$F$1:$F$2500,0)),
    ROW($F$1:$F$2500)-ROW($F$1)+1),ROWS(L$4:L8))),"")}

我可以采用任何优化技术来加快计算速度吗?

根据要求 一些示例数据(链接到电子表格): https://docs.google.com/file/d/0B186C84TADzrMlpmelJoRHN2TVU/edit?usp=sharing

在这个按比例缩小的版本上,它更有效,但在我的实际工作表中,它有更多数据,它会变慢。

【问题讨论】:

  • 你能发布一些示例数据吗?
  • 我添加了一些示例数据
  • @pnuts 您可以下载文件,然后在两个可用的工作表中播放。
  • @pnuts 哦,我什至没注意到 ^^;尽管 IMO 是一个了不起的公式,即使它可能是缓慢的一面。

标签: excel optimization excel-2007 formula


【解决方案1】:

好吧,我玩了一下,我认为这也是一样的,而且没有第一个 IF 语句:

=IFERROR(INDEX(A$1:A$2500,SMALL(IF(ISNA(MATCH($A$1:$A$2500&$B$1:$B$2500,List1!$A$1:$A$2500&List1!$B$1:$B$2500,0)),ROW($B$1:$B$2500)-ROW($B$1)+1),ROWS(F$2:F2))),"")

样本数据中的那部分:

ROWS(F$2:F2)<=(SUMPRODUCT(--ISNA(MATCH($A$1:$A$2500,List1!$A$1:$A$2500,0))))

据我了解,它只看到输入公式的行号低于“新”项目的数量,但它没有任何用途,因为当您拖动公式超过必需,您仍然会得到错误而不是预期的空白。所以我认为它可以完全删除(在尝试用COUNTA() 代替它之后)并在直接获取详细信息的部分上使用IFERROR()

编辑:把它刮掉了。有关这些部分的重要性,请参阅 barry houdini 的评论。

接下来,你有这个:

ROW($B$1:$B$2500)-ROW($B$1)+1

-ROW($B$1)+1 always 返回0,所以我没有发现它有什么用处并完全删除了它。

我猜它仍然很长并且需要一些时间,但我相信它应该比以前快一个档次:)

【讨论】:

  • 嘿杰瑞!使用 ROW($B$1:$B$2500)-ROW($B$1)+1 的理由是它更“健壮” - 例如,如果在工作表顶部添加两行将更改为 ROW($B$3:$B$2502)-ROW($B$3)+1 并因此返回相同的数组 - 这是行不通的如果您删除 ROW($B$1)+1。同样,如果第一个公式在 F2 中,最后的 ROW()-1ROWS(F$2:F2) 更健壮
  • @barryhoudini 这确实改变了这些部分的视角。您是否可能是说ROW()-less 健壮的? =P
【解决方案2】:

一个相对快速的解决方案是在列表 2 旁边的列中添加一个多单元格数组公式

{=MATCH($A$1:$A$16,List1!$A$1:$A$11,0)}

并过滤 #N/A 的结果输出。

(或查看 Compare.Lists vs VLOOKUP 了解我的商业解决方案)

【讨论】:

  • 否:它不是拖下来的单格数组公式,是多格数组公式:选择C1:C16 将公式输入到编辑栏中按Control-Shift-Enter跨度>
【解决方案3】:

数组公式很慢。当你有数千个数组公式时,它会使速度很慢。因此,关键是避免使用任何数组公式。

以下将是我实现它的方法,只使用简单的公式。如果您只有 2500 行,它应该足够快。

  • F 列和 H 列是“键”,通过连接 2 列(原始公式中的 E 和 F)创建
  • 假设第一行数据在第三行。

数据:

|   A   |      B      |    |  D |       E       |     F     |      |     H     |
| index | final value |    | ID | exist in Old? | Key (New) |      | Key (Old) |
--------------------------------------------------------------------------------
|   1   |    XXX-33   |    |  0 |      3        | OOD-06    |      | OOC-01    |
|   2   |    ZZZ-66   |    |  0 |      1        | OOC-01    |      | OOC-02    |
|   3   |    ZZZ-77   |    |  1 |     N/A       | XXX-33    |      | OOD-06    |
|   4   |             |    |  1 |      4        | OOE-01    |      | OOE-01    |
|   5   |             |    |  1 |      2        | OOC-02    |      | OOF-03    |
|   6   |             |    |  2 |     N/A       | ZZZ-66    |      |           |
|   7   |             |    |  3 |     N/A       | ZZZ-77    |      |           |

Column E "exist in Old?":测试新键(Column F)是否存在于旧列表(Column H)中

=MATCH(F3, $H$3:$H$2500, 0)

D 列“ID”:每当发现新项目时加一

=IF(ISNA(E3), 1, 0)+IF(ISNUMBER(D2), D2, 0)  

ISNUMBER 的第二部分仅针对第一行,仅使用 D2 会导致错误

A列“索引”:只是一个从1开始的普通系列(直到新列表F列的长度)

B 列“最终值”:通过将 A 列与 D 列匹配来找到新的键。

=IF(A3>MAX($D$3:$D$2500), "", INDEX($F$3:$F$2500, MATCH(A3, $D$3:$D$2500, 0))

此列 B 将是您想要的列表。

如果仍然太慢,则存在一些加速计算的肮脏技巧,例如通过使用带有MATCH( , , 1) 而不是MATCH( , , 0) 的排序列表。

【讨论】:

    猜你喜欢
    • 2023-01-18
    • 2014-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-07
    相关资源
    最近更新 更多