在列中搜索连续值并将三个不同的值返回到其他单元格

Searching column for consecutive values and returning three different values to other cells

我有一系列专栏。一个包含数据点的时间戳,下一个是数据点,接下来是该数据点从十进制到二进制的转换,其余列是二进制字符串拆分成每个位。每列都有一个标题:"No Engine Speed"、"Engine Derate",依此类推。

这是我想做的,但不具备 VBA/Excel 的技能。我正在尝试获取所有这些信息并将其放入对 reader 更友好的内容中。

因此,例如:

会让我得到这个:

描述来自列标题,时间范围start/end来自第一列。我将根据描述列的内容使用 Excel IF 函数或某种 VLOOKUP 函数获得错误代码。我需要的是一个 VBA 代码或一组 Excel 函数,它们将根据那些位列的内容为我填充那些描述和时间戳列。

我设想它的工作方式如下:搜索每个位列,如果找到 1 并且它下面的四个单元格也被发现是 1s 第一个 1 和最后一个 1 的日期戳在我正在创建的更具可读性的报告中填充 Start/End 次。除此之外,列 header 被复制到描述字段。

我只想在连续出现五个或更多个 1 时获取时间戳的原因是我希望在状态被认为是 'event' 之前经过一些时间。我想满足的第二个条件是时间戳相当接近(例如,彼此相隔 2 分钟以内)。这就是为什么即使我为“16-May-15 21:52:47”链接的图片中有一个“1”事件,我也将其排除在我链接的第二张图片之外。

时间戳旁边的数字(以及时间戳本身)将根据用户打开工作簿的时间而变化。这些列是查询数据库的结果,并根据上一个班次的开始和结束时间进行更改。作为旁注,在复制时间戳时,我知道您需要粘贴单元格值,而不仅仅是常规粘贴,否则您最终会将查询数组复制到数据库中。我不知道这是否对编码解决方案有任何影响,但我认为值得一提。

我考虑尝试使用某种类型的 VLOOKUP 函数,但我发现并不能完全满足我的要求,因为它不检查是否有五个或更多连续事件。非常感谢你们能提供的任何指导或方向。我觉得我知道如何做到这一点,但我是 VBA 的新手,我的 Excel 能力还不能胜任这项任务,我的谷歌搜索也没有找到我想要的需要。

我希望我在解释我想做的事情时很清楚,如果我不清楚,请随时提问。

谢谢,

编辑 1:

正如 Grade 'Eh' Bacon 所建议的,我问了一个与此相关的附加问题,该问题导致了一个更适合我需要的解决方案。可以找到

由于您使用辅助列似乎没有问题,如果您的数据已经按日期排序,这可以以相当简单的方式完成。

原始数据表

添加一个新列(我们称之为 X 列),它会检查您的单元格是否是第一个开始一串 5 个日期戳的单元格,如您所说,所有这些日期戳都相隔 2 分钟[从 X2 开始,以假设的 X100 结束,假设日期戳为 A 列,十进制参考代码为 B 列]:

=COUNTIFS(A2:A0,">=" & A2 - TIMEVALUE("00:02:00"),B2:B0,B2)

这会计算当前单元格下方有多少个单元格在不超过 2 分钟后,包括它自己,并且在 B 列中也有相同的代码。我们将使用它来检查该单元格是否开始一个新的 5 串+ 相同,near-in-time,代码。

在 Y 列中,从 Y2 开始,输入:

=IF(AND(OR(B2<>B1,A2 - TIMEVALUE("00:02:00")>A1),X2 >= 5), TRUE)

这将首先检查是否 (1) 当前单元格中的代码与前一个单元格中的代码不匹配; OR (2) 当前行的时间比上一行至少晚 2 分钟(无论哪种方式,这都是一个新的循环)。然后我们检查 AND 条件,即 X 列中的当前行是否在同一时间周期内显示下面至少 5 个具有相同代码的单元格的匹配项。如果为 TRUE,则它将 return 为 TRUE。否则,它将 return FALSE。

然后 Z 列中的代码 return 是我们在该行上的第 n 个 "hit code" 的编号。即:这是否是第 1 次、第 2 次、第 n 次命中一串 5 个代码 [从 Z2 开始;将 Z1 硬编码为“0”,或者做一些其他特殊情况,这样第一个就不会添加上面单元格的标题,从而导致 #VALUE!错误]:

=IF(Y2,Z1+1,Z1)

这会将 Z 变成位置的升序列表,每当无法创建新代码时重复值。现在我们需要获取此行所代表的代码的描述。

假设您有一个包含所有代码的有序列表,其中第 1 列相当于“1000000...”,第 2 列相当于“01000000..”等等。命名 single-row列(或单列行)作为范围,我将其称为 Code_Index.

在 AA 列中,从 AA2 开始,输入以下内容:

=INDEX(Code_Index,SEARCH("1",C2))

这会检查在该行的 C 列中出现了哪个字符“1”,这将成为我们要从中提取描述的位置(我们已将其放置在命名范围 Code_Index 中)。

最后,我们需要添加一行来检查特定的 5+ 代码块何时结束。说,AB:AB(我最初忘记了这一点,因此最初有点乱)。在 AB2 中向下复制,您将检查在 2 分钟块内的同一行中是否至少有 5 行,以及在新的 2 分钟块内的下一行是否是相同的东西。

=IF(AND(COUNTIFS(B:B2,B2,A:A2,">"A2 - TIMEVALUE("00:02:00")>=5,OR(B3<>B2, A3 + TIMEVALUE("00:02:00")>= A2)),MAX(Z:Z1),"")

结果页

现在假设 Sheet1 上的所有内容,您希望 Sheet2 上的 'clean' 结果。

在 sheet 2 中,将 A 列作为索引,它只是从 A2 上的 1 开始,然后每行加 1。 B 列将是另一个 'helper' 列,C 列将拉描述,D 列将拉开始时间,E 列将拉结束时间。

在 B 列中,输入以下公式,它将检查我们在哪个 'new' 索引上(来自最后一个选项卡上的 Z 列)。从 B2 开始,

=MATCH(A2,Sheet1!Z:Z,0)

这将从原始数据选项卡中找到与 A1 上的当前索引号匹配的第一行。然后只需在接下来 3 列的每一列中的索引公式中使用它,即可提取描述、开始时间和结束时间。

在 C2 中(从最后一个选项卡上的 AA 中提取描述):

=INDEX(Sheet1!AA:AA,B2)

在 D2 中(从最后一个选项卡上的 A 中拉出开始时间)

=INDEX(Sheet1!A:A,B2)

在 E2 中(从最后一个选项卡上的 A 中拉出结束时间,*基于 AB 列索引中的行号)

=INDEX(Sheet1!A:A,MATCH(A2,Sheet1!AB:AB,0))

如果我误解了您希望如何设置“2 分钟时间块”,请告诉我;做一些严格的测试以确保它按照您期望的方式运行。