如何制作一个已经很复杂的 Arrayformula 的 Arrayformula?
How Can I make an Arrayformula of an already complex Arrayformula?
这类问题已经在这里被问过很多次(我知道),我已经尝试将半打答案转化为我的特定公式但没有成功 ()。我想我不知道如何或在哪里将它实现到我已经非常复杂的公式中(它将多行的开放时间文本块解析为一周中每一天的单个 start/end 时间格式(和次要times if present)。我所有的尝试要么不起作用,要么第一行的计算结果在整列中重复。
我已经支持我的所有尝试,并将分享我希望最终在整个列(数千行)中“排列”的基本公式。
这是目前为止的基本公式:
=if(isblank($A3:$A),,iferror(
regexreplace(
concatenate(
arrayformula(
text(
split(
INDEX(
REGEXEXTRACT(
regexreplace($A3:$A,"–","-"),
"(\s?" & B & ":\s)((\d?\d:\d\d\s[AMP]*\s?\W\s\d?\d:\d\d\s[AMP]{2})|(Closed)|(Open\s24\shours))"
),1,2
),"-",true,true
),"HH:MM-"
)
)
),"(\d\d:\d\d\-\d\d:\d\d)\-",""
),
))
在此先感谢您的帮助。
编辑:我被要求澄清公式的作用。该公式正在将一段文本解析为机器可读格式(我将把它导入数据库),其中包含从周一到周日的企业营业时间。如果企业有时间段(比如一家餐馆午餐时间营业,休息一下,然后重新营业晚餐),相邻单元格中的公式也会考虑到这一点。
尝试:
=ARRAYFORMULA(IFERROR(HLOOKUP(B2:O2, QUERY(SPLIT(FLATTEN(IF(IFERROR(
SPLIT(INDEX(SPLIT(FLATTEN(SPLIT(TEXTJOIN(CHAR(10), 1, A3:A), CHAR(10))), ": ", ),,2), ",;"))<>"",
COUNTIFS(
INDEX(SPLIT(FLATTEN(SPLIT(TEXTJOIN(CHAR(10), 1, A3:A), CHAR(10))), ": ", ),,1),
INDEX(SPLIT(FLATTEN(SPLIT(TEXTJOIN(CHAR(10), 1, A3:A), CHAR(10))), ": ", ),,1),
ROW(INDIRECT("A1:A"&COUNTA(SPLIT(TEXTJOIN(CHAR(10), 1, A3:A), CHAR(10))))),
"<="&ROW(INDIRECT("A1:A"&COUNTA(SPLIT(TEXTJOIN(CHAR(10), 1, A3:A), CHAR(10))))))&"♣"&LOWER(
LEFT(INDEX(SPLIT(FLATTEN(SPLIT(TEXTJOIN(CHAR(10), 1, A3:A), CHAR(10))), ": ", ),,1), 3))&COLUMN(A:B)&"♣"&
SUBSTITUTE(SUBSTITUTE({TRANSPOSE(QUERY(TRANSPOSE(TEXT(SPLIT(INDEX(SPLIT(INDEX(
SPLIT(FLATTEN(SPLIT(TEXTJOIN(CHAR(10), 1, A3:A), CHAR(10))), ": ", ),,2), ",;"),,1), "–"), "hh:mm")),,9^9)),
TRANSPOSE(QUERY(TRANSPOSE(TEXT(IFERROR(SPLIT(INDEX(SPLIT(INDEX(
SPLIT(FLATTEN(SPLIT(TEXTJOIN(CHAR(10), 1, A3:A), CHAR(10))), ": ", ),,2), ",;"),,2), "–")), "hh:mm")),,9^9))},
"00:00 00:00", ), " ", "-"),
COUNTIFS(
INDEX(SPLIT(FLATTEN(SPLIT(TEXTJOIN(CHAR(10), 1, A3:A), CHAR(10))), ": ", ),,1),
INDEX(SPLIT(FLATTEN(SPLIT(TEXTJOIN(CHAR(10), 1, A3:A), CHAR(10))), ": ", ),,1),
ROW(INDIRECT("A1:A"&COUNTA(SPLIT(TEXTJOIN(CHAR(10), 1, A3:A), CHAR(10))))),
"<="&ROW(INDIRECT("A1:A"&COUNTA(SPLIT(TEXTJOIN(CHAR(10), 1, A3:A), CHAR(10))))))&"♣"&LOWER(
LEFT(INDEX(SPLIT(FLATTEN(SPLIT(TEXTJOIN(CHAR(10), 1, A3:A), CHAR(10))), ": ", ),,1), 3))&COLUMN(A:B))), "♣"),
"select max(Col3) group by Col1 pivot Col2"), ROW(INDIRECT("A2:A"&COUNTA(A3:A)+ROW(A3)-1)), 0)))
更新:
=ARRAYFORMULA(IFERROR(HLOOKUP(B2:O2, IFNA(VLOOKUP({""; ROW(A3:A)}, QUERY(SPLIT(FLATTEN(IF(IFERROR(
SPLIT(INDEX(SPLIT(FLATTEN(SPLIT(TEXTJOIN(CHAR(10), 1, A3:A), CHAR(10))), ": ", ),,2), ",;"))<>"",
LOWER(LEFT(INDEX(SPLIT(FLATTEN(SPLIT(TEXTJOIN(CHAR(10), 1, IF(A3:A="",,
REGEXREPLACE(A3:A, "^|(\n)", ""&ROW(A3:A)&"♣"))), CHAR(10))), ": ", ),,1), 5))&COLUMN(A:B)&"♣"&
SUBSTITUTE(SUBSTITUTE(SUBSTITUTE({TRANSPOSE(QUERY(TRANSPOSE(TEXT(SPLIT(INDEX(SPLIT(INDEX(
SPLIT(FLATTEN(SPLIT(TEXTJOIN(CHAR(10), 1, A3:A), CHAR(10))), ": ", ),,2), ",;"),,1), "–"), "hh:mm")),,9^9)),
TRANSPOSE(QUERY(TRANSPOSE(TEXT(IFERROR(SPLIT(INDEX(SPLIT(INDEX(
SPLIT(FLATTEN(SPLIT(TEXTJOIN(CHAR(10), 1, A3:A), CHAR(10))), ": ", ),,2), ",;"),,2), "–")), "hh:mm")),,9^9))},
"00:00 00:00", ), "Closed 00:00", "Closed"), " ", "-"),
LOWER(LEFT(INDEX(SPLIT(FLATTEN(SPLIT(TEXTJOIN(CHAR(10), 1, IF(A3:A="",,
REGEXREPLACE(A3:A, "^|(\n)", ""&ROW(A3:A)&"♣"))), CHAR(10))), ": ", ),,1), 5))&COLUMN(A:B))), "♣"),
"select Col1,max(Col3) group by Col1 pivot Col2"), COLUMN(B:O), 0)), ROW(INDIRECT("A2:A"&COUNTA(A3:A)+ROW(A3)-1)), 0)))
spreadsheet demo
修复:
=ARRAYFORMULA(IFERROR(HLOOKUP(B2:O2, IFNA(VLOOKUP({""; ROW(A3:A)}, QUERY(SPLIT(FLATTEN(IF(IFERROR(
SPLIT(INDEX(SPLIT(FLATTEN(SPLIT(TEXTJOIN(CHAR(10), 1, A3:A), CHAR(10))), ": ", ),,2), ",;"))<>"",
LOWER(REGEXEXTRACT(INDEX(SPLIT(FLATTEN(SPLIT(TEXTJOIN(CHAR(10), 1, IF(A3:A="",,
REGEXREPLACE(A3:A, "^|(\n)", ""&ROW(A3:A)&"♣"))), CHAR(10))), ": ", ),,1), "\d+♣..."))&COLUMN(A:B)&"♣"&
SUBSTITUTE(SUBSTITUTE(SUBSTITUTE({TRANSPOSE(QUERY(TRANSPOSE(TEXT(SPLIT(INDEX(SPLIT(INDEX(
SPLIT(FLATTEN(SPLIT(TEXTJOIN(CHAR(10), 1, A3:A), CHAR(10))), ": ", ),,2), ",;"),,1), "–"), "hh:mm")),,9^9)),
TRANSPOSE(QUERY(TRANSPOSE(TEXT(IFERROR(SPLIT(INDEX(SPLIT(INDEX(
SPLIT(FLATTEN(SPLIT(TEXTJOIN(CHAR(10), 1, A3:A), CHAR(10))), ": ", ),,2), ",;"),,2), "–")), "hh:mm")),,9^9))},
"00:00 00:00", ), "Closed 00:00", "Closed"), " ", "-"),
LOWER(REGEXEXTRACT(INDEX(SPLIT(FLATTEN(SPLIT(TEXTJOIN(CHAR(10), 1, IF(A3:A="",,
REGEXREPLACE(A3:A, "^|(\n)", ""&ROW(A3:A)&"♣"))), CHAR(10))), ": ", ),,1), "\d+♣..."))&COLUMN(A:B))), "♣"),
"select Col1,max(Col3) group by Col1 pivot Col2"), COLUMN(B:O), 0)), ROW(INDIRECT("A2:A"&MAX(IF(A:A="", ROW(A:A))))), 0)))
这是另一个建议,它更短但效果更好。
这是一个数组公式,将填充一个完整的行。然后你只需将它拖到 B 列下即可。我已将其放入单元格 B4 中名为“Erik Help”的新 sheet:
=ArrayFormula(IF(A4="","",IF(B:="","",IFERROR(TRIM(SUBSTITUTE(" "&VLOOKUP(LEFT(B:,3)&"*",{TRIM(QUERY(SPLIT(FLATTEN(SPLIT(A4,";")),": ",0),"Select Col1")),TEXT(TRIM(SPLIT(QUERY(SPLIT(FLATTEN(SPLIT(A4,";")),": ",0),"Select Col2"),"–,",1)),"hh:mm")},IF(VALUE(RIGHT(B:,1))=1,2,4),FALSE)&"-"&VLOOKUP(LEFT(B:,3)&"*",{TRIM(QUERY(SPLIT(FLATTEN(SPLIT(A4,";")),": ",0),"Select Col1")),TEXT(TRIM(SPLIT(QUERY(SPLIT(FLATTEN(SPLIT(A4,";")),": ",0),"Select Col2"),"–,",1)),"hh:mm")},IF(VALUE(RIGHT(B:,1))=1,3,5),FALSE)," -",""))))))
...然后我把它拖到B5和B6.
注意:FLATTEN 仍然是一个非官方的 Google 函数,因此请在理解的情况下使用它。
根据您添加的评论,我添加了另一个 sheet,名为“Erik Help 2”。您会发现新的数组公式位于单元格 B3(青色)中。它填充整个行和列网格,包括来自那个单元格的 sub-headers(例如,mon1、mon2 等):
=ArrayFormula({IF(B:O<>"",LOWER(LEFT(B:O,3))&"1",LOWER(LEFT(A:N,3))&2);IF(TRIM($A4:A)="","",IF(B:O<>"",
TEXT(TRIM(MID(TRIM($A4:A),FIND(":",TRIM($A4:A),FIND(B:O,TRIM($A4:A)))+1,9)),"hh:mm")&"-"&TEXT(TRIM(SUBSTITUTE(SUBSTITUTE(MID(TRIM($A4:A),FIND(":",TRIM($A4:A),FIND(B:O,TRIM($A4:A)))+12,9),",",""),";","")),"hh:mm"),
IF(FIND(";",TRIM($A4:A),FIND(A:N,TRIM($A4:A)))-FIND(":",TRIM($A4:A),FIND(A:N,TRIM($A4:A)))>25,
TEXT(TRIM(MID(TRIM($A4:A),FIND(",",TRIM($A4:$A),FIND(A:N,TRIM($A4:A)))+1,9)),"hh:mm")&"-"&TEXT(TRIM(SUBSTITUTE(MID(TRIM($A4:A),FIND(",",TRIM($A4:$A),FIND(A:N,TRIM($A4:A)))+12,9),";","")),"hh:mm"),"")))})
您需要仔细检查它以获得准确的结果,但我认为它是正确的。
请记住,这个复杂的公式 依赖于 您在 A 列中保留当前结构。即:
1.) 工作日拼写后跟一个冒号和 space.
2.) 同一天的两个时段用逗号分隔。
3.) 每个 工作日的条目以分号结尾。
如果更改此设置,公式将不起作用,因为它将无法找到所需的标记。
这类问题已经在这里被问过很多次(我知道),我已经尝试将半打答案转化为我的特定公式但没有成功 (
我已经支持我的所有尝试,并将分享我希望最终在整个列(数千行)中“排列”的基本公式。
这是目前为止的基本公式:
=if(isblank($A3:$A),,iferror(
regexreplace(
concatenate(
arrayformula(
text(
split(
INDEX(
REGEXEXTRACT(
regexreplace($A3:$A,"–","-"),
"(\s?" & B & ":\s)((\d?\d:\d\d\s[AMP]*\s?\W\s\d?\d:\d\d\s[AMP]{2})|(Closed)|(Open\s24\shours))"
),1,2
),"-",true,true
),"HH:MM-"
)
)
),"(\d\d:\d\d\-\d\d:\d\d)\-",""
),
))
在此先感谢您的帮助。
编辑:我被要求澄清公式的作用。该公式正在将一段文本解析为机器可读格式(我将把它导入数据库),其中包含从周一到周日的企业营业时间。如果企业有时间段(比如一家餐馆午餐时间营业,休息一下,然后重新营业晚餐),相邻单元格中的公式也会考虑到这一点。
尝试:
=ARRAYFORMULA(IFERROR(HLOOKUP(B2:O2, QUERY(SPLIT(FLATTEN(IF(IFERROR(
SPLIT(INDEX(SPLIT(FLATTEN(SPLIT(TEXTJOIN(CHAR(10), 1, A3:A), CHAR(10))), ": ", ),,2), ",;"))<>"",
COUNTIFS(
INDEX(SPLIT(FLATTEN(SPLIT(TEXTJOIN(CHAR(10), 1, A3:A), CHAR(10))), ": ", ),,1),
INDEX(SPLIT(FLATTEN(SPLIT(TEXTJOIN(CHAR(10), 1, A3:A), CHAR(10))), ": ", ),,1),
ROW(INDIRECT("A1:A"&COUNTA(SPLIT(TEXTJOIN(CHAR(10), 1, A3:A), CHAR(10))))),
"<="&ROW(INDIRECT("A1:A"&COUNTA(SPLIT(TEXTJOIN(CHAR(10), 1, A3:A), CHAR(10))))))&"♣"&LOWER(
LEFT(INDEX(SPLIT(FLATTEN(SPLIT(TEXTJOIN(CHAR(10), 1, A3:A), CHAR(10))), ": ", ),,1), 3))&COLUMN(A:B)&"♣"&
SUBSTITUTE(SUBSTITUTE({TRANSPOSE(QUERY(TRANSPOSE(TEXT(SPLIT(INDEX(SPLIT(INDEX(
SPLIT(FLATTEN(SPLIT(TEXTJOIN(CHAR(10), 1, A3:A), CHAR(10))), ": ", ),,2), ",;"),,1), "–"), "hh:mm")),,9^9)),
TRANSPOSE(QUERY(TRANSPOSE(TEXT(IFERROR(SPLIT(INDEX(SPLIT(INDEX(
SPLIT(FLATTEN(SPLIT(TEXTJOIN(CHAR(10), 1, A3:A), CHAR(10))), ": ", ),,2), ",;"),,2), "–")), "hh:mm")),,9^9))},
"00:00 00:00", ), " ", "-"),
COUNTIFS(
INDEX(SPLIT(FLATTEN(SPLIT(TEXTJOIN(CHAR(10), 1, A3:A), CHAR(10))), ": ", ),,1),
INDEX(SPLIT(FLATTEN(SPLIT(TEXTJOIN(CHAR(10), 1, A3:A), CHAR(10))), ": ", ),,1),
ROW(INDIRECT("A1:A"&COUNTA(SPLIT(TEXTJOIN(CHAR(10), 1, A3:A), CHAR(10))))),
"<="&ROW(INDIRECT("A1:A"&COUNTA(SPLIT(TEXTJOIN(CHAR(10), 1, A3:A), CHAR(10))))))&"♣"&LOWER(
LEFT(INDEX(SPLIT(FLATTEN(SPLIT(TEXTJOIN(CHAR(10), 1, A3:A), CHAR(10))), ": ", ),,1), 3))&COLUMN(A:B))), "♣"),
"select max(Col3) group by Col1 pivot Col2"), ROW(INDIRECT("A2:A"&COUNTA(A3:A)+ROW(A3)-1)), 0)))
更新:
=ARRAYFORMULA(IFERROR(HLOOKUP(B2:O2, IFNA(VLOOKUP({""; ROW(A3:A)}, QUERY(SPLIT(FLATTEN(IF(IFERROR(
SPLIT(INDEX(SPLIT(FLATTEN(SPLIT(TEXTJOIN(CHAR(10), 1, A3:A), CHAR(10))), ": ", ),,2), ",;"))<>"",
LOWER(LEFT(INDEX(SPLIT(FLATTEN(SPLIT(TEXTJOIN(CHAR(10), 1, IF(A3:A="",,
REGEXREPLACE(A3:A, "^|(\n)", ""&ROW(A3:A)&"♣"))), CHAR(10))), ": ", ),,1), 5))&COLUMN(A:B)&"♣"&
SUBSTITUTE(SUBSTITUTE(SUBSTITUTE({TRANSPOSE(QUERY(TRANSPOSE(TEXT(SPLIT(INDEX(SPLIT(INDEX(
SPLIT(FLATTEN(SPLIT(TEXTJOIN(CHAR(10), 1, A3:A), CHAR(10))), ": ", ),,2), ",;"),,1), "–"), "hh:mm")),,9^9)),
TRANSPOSE(QUERY(TRANSPOSE(TEXT(IFERROR(SPLIT(INDEX(SPLIT(INDEX(
SPLIT(FLATTEN(SPLIT(TEXTJOIN(CHAR(10), 1, A3:A), CHAR(10))), ": ", ),,2), ",;"),,2), "–")), "hh:mm")),,9^9))},
"00:00 00:00", ), "Closed 00:00", "Closed"), " ", "-"),
LOWER(LEFT(INDEX(SPLIT(FLATTEN(SPLIT(TEXTJOIN(CHAR(10), 1, IF(A3:A="",,
REGEXREPLACE(A3:A, "^|(\n)", ""&ROW(A3:A)&"♣"))), CHAR(10))), ": ", ),,1), 5))&COLUMN(A:B))), "♣"),
"select Col1,max(Col3) group by Col1 pivot Col2"), COLUMN(B:O), 0)), ROW(INDIRECT("A2:A"&COUNTA(A3:A)+ROW(A3)-1)), 0)))
spreadsheet demo
修复:
=ARRAYFORMULA(IFERROR(HLOOKUP(B2:O2, IFNA(VLOOKUP({""; ROW(A3:A)}, QUERY(SPLIT(FLATTEN(IF(IFERROR(
SPLIT(INDEX(SPLIT(FLATTEN(SPLIT(TEXTJOIN(CHAR(10), 1, A3:A), CHAR(10))), ": ", ),,2), ",;"))<>"",
LOWER(REGEXEXTRACT(INDEX(SPLIT(FLATTEN(SPLIT(TEXTJOIN(CHAR(10), 1, IF(A3:A="",,
REGEXREPLACE(A3:A, "^|(\n)", ""&ROW(A3:A)&"♣"))), CHAR(10))), ": ", ),,1), "\d+♣..."))&COLUMN(A:B)&"♣"&
SUBSTITUTE(SUBSTITUTE(SUBSTITUTE({TRANSPOSE(QUERY(TRANSPOSE(TEXT(SPLIT(INDEX(SPLIT(INDEX(
SPLIT(FLATTEN(SPLIT(TEXTJOIN(CHAR(10), 1, A3:A), CHAR(10))), ": ", ),,2), ",;"),,1), "–"), "hh:mm")),,9^9)),
TRANSPOSE(QUERY(TRANSPOSE(TEXT(IFERROR(SPLIT(INDEX(SPLIT(INDEX(
SPLIT(FLATTEN(SPLIT(TEXTJOIN(CHAR(10), 1, A3:A), CHAR(10))), ": ", ),,2), ",;"),,2), "–")), "hh:mm")),,9^9))},
"00:00 00:00", ), "Closed 00:00", "Closed"), " ", "-"),
LOWER(REGEXEXTRACT(INDEX(SPLIT(FLATTEN(SPLIT(TEXTJOIN(CHAR(10), 1, IF(A3:A="",,
REGEXREPLACE(A3:A, "^|(\n)", ""&ROW(A3:A)&"♣"))), CHAR(10))), ": ", ),,1), "\d+♣..."))&COLUMN(A:B))), "♣"),
"select Col1,max(Col3) group by Col1 pivot Col2"), COLUMN(B:O), 0)), ROW(INDIRECT("A2:A"&MAX(IF(A:A="", ROW(A:A))))), 0)))
这是另一个建议,它更短但效果更好。
这是一个数组公式,将填充一个完整的行。然后你只需将它拖到 B 列下即可。我已将其放入单元格 B4 中名为“Erik Help”的新 sheet:
=ArrayFormula(IF(A4="","",IF(B:="","",IFERROR(TRIM(SUBSTITUTE(" "&VLOOKUP(LEFT(B:,3)&"*",{TRIM(QUERY(SPLIT(FLATTEN(SPLIT(A4,";")),": ",0),"Select Col1")),TEXT(TRIM(SPLIT(QUERY(SPLIT(FLATTEN(SPLIT(A4,";")),": ",0),"Select Col2"),"–,",1)),"hh:mm")},IF(VALUE(RIGHT(B:,1))=1,2,4),FALSE)&"-"&VLOOKUP(LEFT(B:,3)&"*",{TRIM(QUERY(SPLIT(FLATTEN(SPLIT(A4,";")),": ",0),"Select Col1")),TEXT(TRIM(SPLIT(QUERY(SPLIT(FLATTEN(SPLIT(A4,";")),": ",0),"Select Col2"),"–,",1)),"hh:mm")},IF(VALUE(RIGHT(B:,1))=1,3,5),FALSE)," -",""))))))
...然后我把它拖到B5和B6.
注意:FLATTEN 仍然是一个非官方的 Google 函数,因此请在理解的情况下使用它。
根据您添加的评论,我添加了另一个 sheet,名为“Erik Help 2”。您会发现新的数组公式位于单元格 B3(青色)中。它填充整个行和列网格,包括来自那个单元格的 sub-headers(例如,mon1、mon2 等):
=ArrayFormula({IF(B:O<>"",LOWER(LEFT(B:O,3))&"1",LOWER(LEFT(A:N,3))&2);IF(TRIM($A4:A)="","",IF(B:O<>"",
TEXT(TRIM(MID(TRIM($A4:A),FIND(":",TRIM($A4:A),FIND(B:O,TRIM($A4:A)))+1,9)),"hh:mm")&"-"&TEXT(TRIM(SUBSTITUTE(SUBSTITUTE(MID(TRIM($A4:A),FIND(":",TRIM($A4:A),FIND(B:O,TRIM($A4:A)))+12,9),",",""),";","")),"hh:mm"),
IF(FIND(";",TRIM($A4:A),FIND(A:N,TRIM($A4:A)))-FIND(":",TRIM($A4:A),FIND(A:N,TRIM($A4:A)))>25,
TEXT(TRIM(MID(TRIM($A4:A),FIND(",",TRIM($A4:$A),FIND(A:N,TRIM($A4:A)))+1,9)),"hh:mm")&"-"&TEXT(TRIM(SUBSTITUTE(MID(TRIM($A4:A),FIND(",",TRIM($A4:$A),FIND(A:N,TRIM($A4:A)))+12,9),";","")),"hh:mm"),"")))})
您需要仔细检查它以获得准确的结果,但我认为它是正确的。
请记住,这个复杂的公式 依赖于 您在 A 列中保留当前结构。即:
1.) 工作日拼写后跟一个冒号和 space.
2.) 同一天的两个时段用逗号分隔。
3.) 每个 工作日的条目以分号结尾。
如果更改此设置,公式将不起作用,因为它将无法找到所需的标记。