希望将 ARRAYFORMULA 用于 increment-count 包含 TRUE 或 FALSE 的相邻行
Looking to use ARRAYFORMULA to increment-count adjacent rows containing either TRUE or FALSE
我在 Google 工作表中有一个动态 table,除了其他不相关的列外,B 列已经进行了各种计算,结果 [=26] 中每一行的结果为 TRUE 或 FALSE =](前三行是headers和摘要)。
我想要的是能够在另一列中计算(C 会很好!)到目前为止(自上而下)在当前 streak 并且,当 B 更改为 FALSE 时,执行相同的操作,在 B 的值每次更改时重置回 1。
这是我的数据示例 link(抱歉,rep<10 所以不能只 post 图片):
sample data
由于实际数据远远超过 ~20 行,并且在可预见的未来每天至少更新一次,我更愿意使用 ARRAYFORMULA 来计算 C,而不必将公式向下拖动。此外,除非脚本特别简化,否则我非常喜欢公式而不是脚本。
如果我想要所有 TRUE 或所有 FALSE(甚至都在 pre-determined 范围内),我已经可以做到;困扰我的是问题的动态性质。
advTHANKSance
清除 C4:C500,然后将以下内容放入单元格 C4:
=ArrayFormula(IF(B4:B500="",, ROW(B4:B500) - VLOOKUP(ROW(B4:B500), FILTER(ROW(B4:B500), B4:B500<>"", B4:B500<>B3:B499), 1, TRUE) + 1))
FILTER
创建一个列表,其中包含与 B4:B 中的非空单元格对应的所有行号,其中当前单元格与前一个单元格的值不同。此列表将仅包含“重新启动”新值的行。
VLOOKUP
最终参数为 TRUE
将在上面的 FILTER
ed 短列表中查找与 B4:B500 对应的每个行号,然后“回退”到最接近的值。因此,如果 FILTER
ed 列表从 4, 8, 9...
开始,那么第 5 行将 return 4
,第 6 行将 return 4
,等等。减去最来自每个实际行号的最近回退行号将产生上次更改的计数。
我们添加 +1
因为每个变化点的计数从 1 而不是 0 开始。例如,对于第 4 行,我们将得到 4(当前行)- 4(回退值)= 0;但我们希望第 4 行从 1 开始计数,因此每个值的 +1
。
有 2 列...(未指定列的结尾)
在 C2
=arrayformula(B4:B&(SUMIF(ROW(B4:B),"<="&ROW(B4:B),C4:C)))
D2
=arrayformula((row(B4:B)<=transpose(row(B4:B)))*((B4:B&(SUMIF(ROW(B4:B),"<="&ROW(B4:B),C4:C)))=TRANSPOSE((B4:B&(SUMIF(ROW(B4:B),"<="&ROW(B4:B),C4:C))))))
编辑:使用类似逻辑的更简洁的公式:
=index(if(B4:B="",,len(RegexReplace(left(join(,left(B4:B)),row(B4:B)-3),".*"&if(B4:B,"F","T"),))))
这是使用 Regex 的另一种方法。
=ArrayFormula(IFNA(len(RegexExtract(RegexReplace(RegexReplace(join(,B4:B500),"RUE|ALSE",),"^(.{"&sequence(counta(B4:B500))&"})","~"),"(.*)~"))-len(RegexExtract(RegexReplace(RegexReplace(join(,B4:B500),"RUE|ALSE",),"^(.{"&sequence(counta(B4:B500))&"})","~"),"(.*"&if(RegexExtract(RegexReplace(RegexReplace(join(,B4:B500),"RUE|ALSE",),"^(.{"&sequence(counta(B4:B500))&"})","~"),"(.)~")="T","F","T")&").+~")),sequence(999)))
就长度和多功能性而言,它都不是最佳解决方案,因为它仅设计用于此特定输入 (TRUE/FALSE),但这是一个有趣的问题,所以我想试一试。
另一个尝试:
=ArrayFormula(if(B2:B="",,row(B2:B)-
if(B2:B,
iferror(vlookup(row(B2:B),if(not(B2:B),row(B2:B)),1),1),
iferror(vlookup(row(B2:B),if(B2:B,row(B2:B)),1),1))))
iferror 值的更通用表达式,如果您想从第 4 行等开始:
=ArrayFormula(if(B4:B="",,row(B4:B)-
if(B4:B,
iferror(vlookup(row(B4:B),if(not(B4:B),row(B4:B)),1),min(row(B4:B))-1),
iferror(vlookup(row(B4:B),if(B4:B,row(B4:B)),1),min(row(B4:B))-1))))
或您的具体要求:
=ArrayFormula(if(B4:B="",,row(B4:B)-
if(B4:B,
iferror(vlookup(row(B4:B),if(not(B4:B),row(B4:B)),1),3),
iferror(vlookup(row(B4:B),if(B4:B,row(B4:B)),1),3))))
我在 Google 工作表中有一个动态 table,除了其他不相关的列外,B 列已经进行了各种计算,结果 [=26] 中每一行的结果为 TRUE 或 FALSE =](前三行是headers和摘要)。
我想要的是能够在另一列中计算(C 会很好!)到目前为止(自上而下)在当前 streak 并且,当 B 更改为 FALSE 时,执行相同的操作,在 B 的值每次更改时重置回 1。
这是我的数据示例 link(抱歉,rep<10 所以不能只 post 图片): sample data
由于实际数据远远超过 ~20 行,并且在可预见的未来每天至少更新一次,我更愿意使用 ARRAYFORMULA 来计算 C,而不必将公式向下拖动。此外,除非脚本特别简化,否则我非常喜欢公式而不是脚本。
如果我想要所有 TRUE 或所有 FALSE(甚至都在 pre-determined 范围内),我已经可以做到;困扰我的是问题的动态性质。
advTHANKSance
清除 C4:C500,然后将以下内容放入单元格 C4:
=ArrayFormula(IF(B4:B500="",, ROW(B4:B500) - VLOOKUP(ROW(B4:B500), FILTER(ROW(B4:B500), B4:B500<>"", B4:B500<>B3:B499), 1, TRUE) + 1))
FILTER
创建一个列表,其中包含与 B4:B 中的非空单元格对应的所有行号,其中当前单元格与前一个单元格的值不同。此列表将仅包含“重新启动”新值的行。
VLOOKUP
最终参数为 TRUE
将在上面的 FILTER
ed 短列表中查找与 B4:B500 对应的每个行号,然后“回退”到最接近的值。因此,如果 FILTER
ed 列表从 4, 8, 9...
开始,那么第 5 行将 return 4
,第 6 行将 return 4
,等等。减去最来自每个实际行号的最近回退行号将产生上次更改的计数。
我们添加 +1
因为每个变化点的计数从 1 而不是 0 开始。例如,对于第 4 行,我们将得到 4(当前行)- 4(回退值)= 0;但我们希望第 4 行从 1 开始计数,因此每个值的 +1
。
有 2 列...(未指定列的结尾)
在 C2
=arrayformula(B4:B&(SUMIF(ROW(B4:B),"<="&ROW(B4:B),C4:C)))
D2
=arrayformula((row(B4:B)<=transpose(row(B4:B)))*((B4:B&(SUMIF(ROW(B4:B),"<="&ROW(B4:B),C4:C)))=TRANSPOSE((B4:B&(SUMIF(ROW(B4:B),"<="&ROW(B4:B),C4:C))))))
编辑:使用类似逻辑的更简洁的公式:
=index(if(B4:B="",,len(RegexReplace(left(join(,left(B4:B)),row(B4:B)-3),".*"&if(B4:B,"F","T"),))))
这是使用 Regex 的另一种方法。
=ArrayFormula(IFNA(len(RegexExtract(RegexReplace(RegexReplace(join(,B4:B500),"RUE|ALSE",),"^(.{"&sequence(counta(B4:B500))&"})","~"),"(.*)~"))-len(RegexExtract(RegexReplace(RegexReplace(join(,B4:B500),"RUE|ALSE",),"^(.{"&sequence(counta(B4:B500))&"})","~"),"(.*"&if(RegexExtract(RegexReplace(RegexReplace(join(,B4:B500),"RUE|ALSE",),"^(.{"&sequence(counta(B4:B500))&"})","~"),"(.)~")="T","F","T")&").+~")),sequence(999)))
就长度和多功能性而言,它都不是最佳解决方案,因为它仅设计用于此特定输入 (TRUE/FALSE),但这是一个有趣的问题,所以我想试一试。
另一个尝试:
=ArrayFormula(if(B2:B="",,row(B2:B)-
if(B2:B,
iferror(vlookup(row(B2:B),if(not(B2:B),row(B2:B)),1),1),
iferror(vlookup(row(B2:B),if(B2:B,row(B2:B)),1),1))))
iferror 值的更通用表达式,如果您想从第 4 行等开始:
=ArrayFormula(if(B4:B="",,row(B4:B)-
if(B4:B,
iferror(vlookup(row(B4:B),if(not(B4:B),row(B4:B)),1),min(row(B4:B))-1),
iferror(vlookup(row(B4:B),if(B4:B,row(B4:B)),1),min(row(B4:B))-1))))
或您的具体要求:
=ArrayFormula(if(B4:B="",,row(B4:B)-
if(B4:B,
iferror(vlookup(row(B4:B),if(not(B4:B),row(B4:B)),1),3),
iferror(vlookup(row(B4:B),if(B4:B,row(B4:B)),1),3))))