【问题标题】:How to identify two separate ranges of consecutively marked cells within a row如何识别一行中连续标记的两个不同范围的单元格
【发布时间】:2016-05-11 00:24:50
【问题描述】:

鉴于下面的全部示例表,如何识别:

  1. 上面的 H 列或日期作为第一组带有 x 的连续单元格的最后一个单元格。
  2. 上面的 M 列或日期作为第二组连续 x 的第一个单元格。

+---+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+
|   |    A     |    B     |    C     |    D     |    E     |    F     |    G     |    H     |    I     |    J     |    K     |    L     |    M     |    N     |    O     |    P     |
+---+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+
| 1 | 14/01/01 | 14/01/02 | 14/01/03 | 14/01/04 | 14/01/05 | 14/01/06 | 14/01/07 | 14/01/08 | 14/01/09 | 14/01/10 | 14/01/11 | 14/01/12 | 14/01/13 | 14/01/14 | 14/01/15 | 14/01/16 |
| 2 |          |          |          | x        | x        | x        | x        | x        |          |          |          |          | x        | x        | x        |          |
+---+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+----------+

block 之间的间隙最大大小为 356。由于拼写错误,cmets 中的 316 的数量是错误的。

使用的公式:

识别第一个整体 x:

=MATCH("x",$A2:$P2,0)

确定最后一个整体 x:

=MATCH("x",$A2:$P2,1)

限制:

没有 VBA,只有 Excel 公式。
没有辅助单元格。
无法将 x 更改为其他标识符。
第一个块结束的一个单元格公式。
第二个块开始的一个单元格公式。


当我为两组使用两个不同的标识符时,这很容易,但是使用相同的标识符我只能弄清楚如何识别第一个和最后一个 X。我不知道如何识别两者之间的差距。我个人认为这是不可能的,但我看到在这里回答问题的人做了一些了不起的事情。如果您认为不可能,请说出来。

【问题讨论】:

  • 总是两组还是可以变化?
  • 我打算从两个小组开始,看看我是否可以把这个概念理解下来并从那里开始。根据它的工作方式,我可以用它来忽略周末的间隙。但暂时我会将其保留为两组 1 未确定大小的差距....实际上这并不完全正确。差距必须小于一年。即少于360 列...我认为最大的差距可以是316 列。不确定这是否重要,但最好把它扔在那里以防万一它可以使用。
  • 我有一些想法。我明天会去。
  • 不着急,它来自这里的另一个问题,对于我来说,我只是无法弄清楚如何识别差距。我的解决方案是为第二个块使用不同的标识符。我也想过使用块开始和块结束标识符,但这也是不行的。我知道如何根据给定的日期生成块,但是要根据我无法弄清楚的块获取日期。
  • 顺便说一句,这个单细胞复活节公式花了你多长时间?我看到了这方面的一些背景,只是说这真是太痛苦了!

标签: excel excel-formula


【解决方案1】:

这些似乎经受住了我对它们的测试。

在 B4:B5 中作为 CSE 数组¹ 公式。

=INDEX(INDEX(1:1, 0, MATCH("X", 2:2, 0)):INDEX(1:1, 0, MATCH(1E+99, 1:1)), 0, MATCH(TRUE, NOT(LEN(INDEX(2:2, 0, MATCH("X", 2:2, 0)):INDEX(2:2, 0, MATCH(1E+99, 1:1)))), 0)-1)
=INDEX(INDEX(1:1, 0, MATCH(TRUE, NOT(LEN(INDEX(2:2, 0, MATCH("X", 2:2, 0)):INDEX(2:2, 0, MATCH(1E+99, 1:1)))), 0)+MATCH("X", 2:2, 0)-1):INDEX(2:2, 0, MATCH(1E+99, 1:1)), 0, MATCH("X", INDEX(2:2, 0, MATCH(TRUE, NOT(LEN(INDEX(2:2, 0, MATCH("X", 2:2, 0)):INDEX(2:2, 0, MATCH(1E+99, 1:1)))), 0)+MATCH("X", 2:2, 0)-1):INDEX(2:2, 0, MATCH(1E+99, 1:1)), 0))

这个想法是建立一个可用单元格的子范围。例如,从第一个 X 到最后一个日期,您需要找到比第一个空白少一个单元格。你会寻找第一个空白,

INDEX(2:2, 0, MATCH("X",2:2, 0)):INDEX(2:2, 0, MATCH(1E+99,1:1 ))

在第一组后的第一个空白中减去 1,调整起始位置,得到最后一个 X 的列。

我开始使用另一种方法,当第一个 X 在 A2 中时似乎有困难,但这些方法没有出现相同的错误。


¹ 数组公式需要使用 Ctrl+Shift+Enter↵ 完成。如果输入正确,Excel 会将公式用大括号括起来(例如 {})。你不用自己输入大括号。一旦正确输入第一个单元格,它们就可以像任何其他公式一样被填充或向下或向右复制。尝试将全列引用减少到更接近代表实际数据范围的范围。数组公式以对数方式消耗计算周期,因此最好将引用范围缩小到最小值。更多信息请参见Guidelines and examples of array formulas

【讨论】:

  • 感谢 Jeeped,我需要一些时间才能弄清楚这一点。我理解的 CSE,不确定我是否理解 MATCH(巨大的数字,在第一行)......我也不熟悉在两个索引函数之间使用 :。我只知道:作为 A1:B34 中的范围指示器。近 0100 听到了,所以我最好遛狗并睡在上面,然后再尝试吸收。
  • match(HUGE_NUMBER, 1:1) 产生第 1 行中最后一个数字(日期为数字)的列号。A1:A9 也可以写成INDEX(A:A, 1):INDEX(A:A, 9)
  • 我还在纠结这个,我要去查看索引公式。试图弄清楚为什么索引中的 row 参数为 0。
  • 对于单行,它也可以是一个或只是空白,用逗号表示 row_number 参数被跳过。因为复杂匹配提供的是 column_number 而不是 row_number,所以至少有一个逗号。零表示 所有行,当您只处理单行时,它与 1 相同或只是空白。
  • 好的,算出 0,表示您希望将整行作为数组。因此,如果我理解正确,第二个公式会找到第一个 X 的列和最后一列的日期。仍然对两个索引函数之间的 : 感到困惑。
【解决方案2】:

这是我的:

要查找任何组的结束日期:

=INDEX($A$1:$P$1,AGGREGATE(15,6,(COLUMN($A$1:$P$1))/(($A$2:$P$2="x")*($B$2:$Q$2 = "")),COLUMN(A:A)))

其中 Column(A:A) 是一个计数器,这将解析为 1 或第一个。当它拖过时,它将增加获得第二个结束日期,然后是第三个等等。

然后获取第二个开始日期:

=INDEX($A$1:$P$1,AGGREGATE(15,6,(COLUMN($A$1:$P$1)+1)/(($A$2:$P$2="")*($B$2:$Q$2 = "x")),COLUMN(B:B)))

这个计数器和上面那个一样。

这将搜索模式"","x""x","" 分别作为开始和结束日期。

然后让它变得动态:

=INDEX($A$1:INDEX(1:1,MATCH(1e99,1:1)),AGGREGATE(15,6,(COLUMN($A$1:INDEX(1:1,MATCH(1e99,1:1))))/(($A$2:INDEX(2:2,MATCH(1e99,1:1))="x")*($B$2:INDEX(2:2,MATCH(1e99,1:1)+1) = "")),COLUMN(A:A)))

=INDEX($A$1:INDEX(1:1,MATCH(1E+99,1:1)),AGGREGATE(15,6,(COLUMN($A$1:INDEX(1:1,MATCH(1E+99,1:1)))+1)/(($A$2:INDEX(2:2,MATCH(1E+99,1:1))="")*($B$2:INDEX(2:2,MATCH(1E+99,1:1)+1) = "x")),COLUMN(B:B)))

看了@Jeeped 的回答,这大概就是他开始的方法了。因为他是正确的,所以 A 中需要有一个空白列,否则它会失败。

【讨论】:

  • 好的,我刚刚和他一起学习了 Jeeped 的方法,至少可以说学习了一些新技巧。有趣的是我有时可以看到发生了什么,但只是不知道它是如何工作的。当那个灯泡打开时非常酷。假设我在发布示例数据时发出了嘘声。日期不是从 A 列开始,而是让我们任意将其颠倒以从 D 列开始。Goody,您在范围左侧有额外的列可以使用!不幸的是,A 到 C 列中有数字或文本。它们不是空白、“”或字母 X。这有区别吗?
  • 唯一需要注意的是,第一个系列中的第一个 x 需要在前面有一个空格,否则它将选择第二个系列作为第一个而不是第二个开始。否则,无论起始位置如何,第二组公式都将起作用。
  • 好吧,我想我会检查一下。
  • 斯科特,有一个chat room on this question。无论如何有一个问题要问你。
猜你喜欢
  • 2020-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多