【问题标题】:How Can I make an Arrayformula of an already complex Arrayformula?如何制作已经很复杂的 Arrayformula 的 Arrayformula?
【发布时间】:2020-08-14 00:56:13
【问题描述】:

这种类型的问题已经在这里被问过很多次(我知道),我尝试将六个答案转换成我的特定公式但没有成功(like the query smush header trick)。我想我不知道如何或在哪里将它实现到我已经非常复杂的公式中(它将多行营业时间文本块解析为一周中每一天的单个开始/结束时间格式(如果是次要时间)存在)。我的所有尝试要么不起作用,要么第一行的计算结果在整个列中重复。

我已支持我的所有尝试,并将分享我希望最终在整个列(数千行)中“数组公式化”的基本公式。

Here's the Google Sheet

这是迄今为止的基本公式:

=if(isblank($A3:$A),,iferror(
  regexreplace(
    concatenate(
      arrayformula(
        text(
          split(
            INDEX(
              REGEXEXTRACT(
                regexreplace($A3:$A,"–","-"),
                "(\s?" & B$1 & ":\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)\-","$1"
  ),
))

提前感谢您的帮助。

编辑:有人要求我澄清公式的作用。该公式将包含周一至周日营业时间的文本块解析为机器可读格式(我将导入数据库)。如果企业有时间段(例如一家餐厅在午餐时间营业,休息一下,然后在晚餐时间重新营业),则相邻单元格中的公式也可以解释这一点)。

【问题讨论】:

  • 我正在度假,但我会添加一个澄清问题,以帮助其他人帮助您。你的结果是什么意思?我快速看了你的单子,“17:00 - 21:00”没有明显的意思。我建议您在帖子中明确说明这些结果(例如 mon1、mon2 等)的含义。
  • 它们是时间(24 小时格式)。 17:00 到 21:00 = 星期一下午 5 点到晚上 9 点(它所在的列)。 14 列(mon1 到 sun2)中的每一列都是最左侧列的解析结果(这是整周所有时间的块)

标签: google-sheets google-sheets-formula array-formulas google-sheets-query gs-vlookup


【解决方案1】:

尝试:

=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)", "$1"&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)", "$1"&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)", "$1"&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)", "$1"&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)))

【讨论】:

  • 哇。我没想到会得到一个填充列和行的公式。疯了吧。我什至不会开始尝试理解这个...但是谢谢。
  • 我刚刚意识到我在创建示例电子表格时搞砸了。从 JSON 文件导入的源数据没有尾随“;”在最后一行(星期一)。我需要更改哪一行才能使公式在没有尾随分号的情况下工作? docs.google.com/spreadsheets/d/… 编辑:实际上,我不认为缺少尾随分号是问题所在。我只是无法让公式在不同的工作表上工作。
  • 对您的帮助我感激不尽。但是...如果有多个空白行,则公式开始分解。不幸的是,我的源数据有许多空白时间行(并非所有营业时间都是已知的)。 Here's a sheet with real source data to show you what I mean
【解决方案2】:

这是另一个建议,它更短,完成更多。

这是一个将填充整行的数组公式。然后,您只需将其拖到 B 列即可。我已将其放入单元格 B4 中名为“Erik Help”的新工作表中:

=ArrayFormula(IF(A4="","",IF(B$3:$3="","",IFERROR(TRIM(SUBSTITUTE(" "&VLOOKUP(LEFT(B$3:$3,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$3:$3,1))=1,2,4),FALSE)&"-"&VLOOKUP(LEFT(B$3:$3,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$3:$3,1))=1,3,5),FALSE)," -",""))))))

...然后我把它拖到B5和B6。

注意:FLATTEN 仍然是非官方的 Google 功能,因此请在理解后使用它。

【讨论】:

  • 谢谢,但我需要一个能自动填充一列的公式。我不介意稍微改变顶行中的每个公式(一周中的每一天)。我希望能够锁定第一行(我所有的数组公式所在的位置)。数据输入人员不知道如何拖动公式和/或在添加新行时忘记这样做。我正在尝试创建一个无用户错误的解决方案。
【解决方案3】:

根据您添加的评论,我添加了另一个名为“Erik Help 2”的工作表。您将在那里找到的新数组公式位于单元格 B3(青色)中。它填充整个行和列网格,包括来自该单元格的子标题(例如,mon1、mon2 等):

=ArrayFormula({IF(B$2:O$2<>"",LOWER(LEFT(B$2:O$2,3))&"1",LOWER(LEFT(A$2:N$2,3))&2);IF(TRIM($A4:A)="","",IF(B$2:O$2<>"",
TEXT(TRIM(MID(TRIM($A4:A),FIND(":",TRIM($A4:A),FIND(B$2:O$2,TRIM($A4:A)))+1,9)),"hh:mm")&"-"&TEXT(TRIM(SUBSTITUTE(SUBSTITUTE(MID(TRIM($A4:A),FIND(":",TRIM($A4:A),FIND(B$2:O$2,TRIM($A4:A)))+12,9),",",""),";","")),"hh:mm"),
IF(FIND(";",TRIM($A4:A),FIND(A$2:N$2,TRIM($A4:A)))-FIND(":",TRIM($A4:A),FIND(A$2:N$2,TRIM($A4:A)))>25,
TEXT(TRIM(MID(TRIM($A4:A),FIND(",",TRIM($A4:$A),FIND(A$2:N$2,TRIM($A4:A)))+1,9)),"hh:mm")&"-"&TEXT(TRIM(SUBSTITUTE(MID(TRIM($A4:A),FIND(",",TRIM($A4:$A),FIND(A$2:N$2,TRIM($A4:A)))+12,9),";","")),"hh:mm"),"")))})

你会想要仔细检查它以获得准确的结果,但我觉得它是正确的。

请记住,这个复杂的公式依赖您将当前结构保留在 A 列中。即:

1.) 工作日是拼写出来的,后面是冒号和空格。

2.) 同一天的两个句点用逗号分隔。

3.) 每个工作日的条目都以分号结尾。

如果您更改此设置,公式将不起作用,因为它将无法找到所需的标记。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-09-12
    • 2022-09-27
    • 1970-01-01
    • 1970-01-01
    • 2020-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多