【问题标题】:Expand/explode a Google Sheets table with ticket open and close stats to show all tickets open each month展开/展开包含工单打开和关闭统计信息的 Google 表格表格,以显示每个月打开的所有工单
【发布时间】:2020-02-01 05:48:08
【问题描述】:

我的工作示例/示例 Google 表格:https://docs.google.com/spreadsheets/d/1AvAb_qnrrexYl5W5wAW6aA6P552T-prBxoONOis-XZM/edit?usp=sharing

我有一个包含有关门票信息的源表。对于这个问题,只有三列很重要:

  • 票证编号
  • 开票日期
  • 票务结束日期 -- 如果已关闭

根据这些信息,我需要生成显示特定月份的指标/报告:

  1. 当月开的票
  2. 当月关闭的门票
  3. 已打开的票证(之前已打开且未关闭)

而且,我需要原始数据,而不仅仅是每月摘要。意思是,我应该能够选择一个月份并显示所有符合上述三个条件的票证 ID。

使用此函数(示例表中的 E-G 列)很容易获得前两个:

{
    QUERY(A2:C, "SELECT B, 'Opened', A WHERE A IS NOT NULL LABEL 'Opened' '' FORMAT B 'YYYY-MM'");
    QUERY(A2:C, "SELECT C, 'Closed', A WHERE C IS NOT NULL LABEL 'Closed' '' FORMAT C 'YYYY-MM'")
}

我被困在第三个。我试图弄清楚如何在每个月打开一张票。每个月都有一张票打开,应该有一行:

  • 第一列是月份
  • 第二列是“打开”
  • 第三列是工单 ID

例如:

  • ID0010
    • 2018-11 开业
    • 2019-01关闭
    • 打开位置:
      • 2018-12
  • ID0019
    • 2018-08开业
    • 2019-03关闭
    • 打开位置:
      • 2018-09
      • 2018-10
      • 2018-11
      • 2018-12
      • 2019-01
      • 2019-02

会变成:

| Month   | Status | Ticket ID |
|---------|--------|-----------|
| 2018-11 | Opened | ID0010    |
| 2018-12 | Open   | ID0010    |
| 2019-01 | Closed | ID0010    |
| 2018-08 | Opened | ID0019    |
| 2018-09 | Open   | ID0019    |
| 2018-10 | Open   | ID0019    |
| 2018-11 | Open   | ID0019    |
| 2018-12 | Open   | ID0019    |
| 2019-01 | Open   | ID0019    |
| 2019-02 | Open   | ID0019    |
| 2019-03 | Closed | ID0019    |

注意:工单打开和关闭的月份也不会显示该工单的“打开”。换句话说,一张票应该只在月份有“Open”:

  • 之后且不包括打开
  • 之前且不包括关闭

而且,如果一张票还没有关闭,那么它会在今天之前每个月一排。

我认为我可以在Google Sheets Formula to calculate actual total duration of tasks with different start/end dates, overlaps, and gaps 的公认解决方案中使用这个概念,但由于数据的大小,我遇到了错误。公式在我的样本表的 I2 中。

CONCATENATE 的文本结果超过了 50000 个字符的限制。

所以我想知道是否有其他方法可以获得我需要的数据。我知道如何使用自定义函数来做到这一点,但我希望尽可能避免使用自定义函数。

更新解决方案

我能够获取player0 答案的关键部分,并在我的原始解决方案中使用它。简而言之,不是使用CONCATENATE 组合列/行,而是使用QUERY999^99 作为标题计数(第三个参数),因为QUERY 将组合所有行(使用空格分隔符) )。

最终公式为:

=ARRAYFORMULA(
    QUERY(
        SPLIT(
            TRANSPOSE(
                SPLIT(
                    QUERY(
                        TRANSPOSE(
                            TRIM(
                                QUERY(
                                    IF(
                                        A2:A <> "",
                                        A2:A & "," & EDATE(
                                            IFERROR(
                                                SPLIT(
                                                    REPT(
                                                        EOMONTH(B2:B, -1) + 1 & ",",
                                                        DATEDIF(
                                                            EOMONTH(B2:B, 0) + 1,
                                                            EOMONTH(
                                                                IF(
                                                                    C2:C <> "",
                                                                    C2:C,
                                                                    EDATE(TODAY(), 1)
                                                                ),
                                                                0
                                                            ),
                                                            "M"
                                                        )
                                                    ),
                                                    ","
                                                ),
                                                0
                                            ),
                                            TRANSPOSE(
                                                ROW(
                                                    INDIRECT(
                                                        "A1:A" & MAX(
                                                            IF(
                                                                B2:B <> "",
                                                                IFERROR(
                                                                    DATEDIF(
                                                                        EOMONTH(B2:B, 0) + 1,
                                                                        EOMONTH(
                                                                            IF(
                                                                                C2:C <> "",
                                                                                C2:C,
                                                                                EDATE(TODAY(), 1)
                                                                            ),
                                                                            0
                                                                        ),
                                                                        "M"
                                                                    ),
                                                                    0
                                                                ),
                                                            )
                                                        )
                                                    )
                                                )
                                            )
                                        ) & ";",
                                    ),
                                    ,
                                    999^99
                                )
                            )
                        ),
                        ,
                        999^99
                    ) & " ",
                    "; "
                )
            ),
            ","
        ),
        "SELECT Col2, 'Open', Col1 WHERE Col2 > 4000 LABEL 'Open' '' FORMAT Col2 'YYYY-MM'",
        0
    )
)

更新为使用 SEQUENCE

=ARRAYFORMULA(
    QUERY(
        SPLIT(
            TRANSPOSE(
                SPLIT(
                    QUERY(
                        TRANSPOSE(
                            TRIM(
                                QUERY(
                                    IF(
                                        A2:A <> "",
                                        A2:A & "," & EDATE(
                                            IFERROR(
                                                SPLIT(
                                                    REPT(
                                                        EOMONTH(B2:B, -1) + 1 & ",",
                                                        DATEDIF(
                                                            EOMONTH(B2:B, 0) + 1,
                                                            EOMONTH(
                                                                IF(
                                                                    C2:C <> "",
                                                                    C2:C,
                                                                    EDATE(TODAY(), 1)
                                                                ),
                                                                0
                                                            ),
                                                            "M"
                                                        )
                                                    ),
                                                    ","
                                                ),
                                                0
                                            ),
                                            SEQUENCE(
                                                1,
                                                MAX(
                                                    IF(
                                                        B2:B <> "",
                                                        IFERROR(
                                                            DATEDIF(
                                                                EOMONTH(B2:B, 0) + 1,
                                                                EOMONTH(
                                                                    IF(
                                                                        C2:C <> "",
                                                                        C2:C,
                                                                        EDATE(TODAY(), 1)
                                                                    ),
                                                                    0
                                                                ),
                                                                "M"
                                                            ),
                                                            0
                                                        ),
                                                    )
                                                )
                                            )
                                        ) & ";",
                                    ),
                                    ,
                                    999^99
                                )
                            )
                        ),
                        ,
                        999^99
                    ) & " ",
                    "; "
                )
            ),
            ","
        ),
        "SELECT Col2, 'Open', Col1 WHERE Col2 > 4000 LABEL 'Open' '' FORMAT Col2 'YYYY-MM'",
        0
    )
)

【问题讨论】:

    标签: google-sheets google-sheets-formula transpose array-formulas google-sheets-query


    【解决方案1】:

    同样的逻辑:

    =ARRAYFORMULA(UNIQUE(QUERY(SPLIT(TRANSPOSE(SPLIT(QUERY(TRANSPOSE(QUERY(TRANSPOSE(
     "♦"&FILTER(A2:A, B2:B<>"", C2:C<>"")&"♠"&SPLIT(REPT(FILTER(B2:B, B2:B<>"", C2:C<>"")+1&"♣",
     NETWORKDAYS(FILTER(B2:B, B2:B<>"", C2:C<>"")+1, FILTER(C2:C, B2:B<>"", C2:C<>""))), "♣")+
     TRANSPOSE(ROW(INDIRECT("A1:A"&MAX(
     NETWORKDAYS(FILTER(B2:B, B2:B<>"", C2:C<>"")+1, FILTER(C2:C, B2:B<>"", C2:C<>"")))))-1)&"♠")
     ,,999^99)),,999^99), "♦")), "♠"),
     "select Col2,'Open',Col1 where Col2>4000 label 'Open''' format Col2 'YYYY-MM'", 0)))
    


    更新:

    =ARRAYFORMULA(UNIQUE(QUERY(SPLIT(TRANSPOSE(SPLIT(QUERY(TRANSPOSE(QUERY(TRANSPOSE("♦"&
     FILTER(A2:A, B2:B<>"", C2:C<>"", MONTH(B2:B)<>MONTH(C2:C), YEAR(B2:B)<>YEAR(C2:C))&"♠"&EOMONTH(SPLIT(REPT(
     FILTER(B2:B, B2:B<>"", C2:C<>"", MONTH(B2:B)<>MONTH(C2:C), YEAR(B2:B)<>YEAR(C2:C))+1&"♣", DATEDIF(
     FILTER(B2:B, B2:B<>"", C2:C<>"", MONTH(B2:B)<>MONTH(C2:C), YEAR(B2:B)<>YEAR(C2:C))+1, 
     FILTER(C2:C, B2:B<>"", C2:C<>"", MONTH(B2:B)<>MONTH(C2:C), YEAR(B2:B)<>YEAR(C2:C)), "M")-1), "♣"),
     TRANSPOSE(ROW(INDIRECT("A1:A"&MAX(NETWORKDAYS(
     FILTER(B2:B, B2:B<>"", C2:C<>"", MONTH(B2:B)<>MONTH(C2:C), YEAR(B2:B)<>YEAR(C2:C))+1, 
     FILTER(C2:C, B2:B<>"", C2:C<>"", MONTH(B2:B)<>MONTH(C2:C), YEAR(B2:B)<>YEAR(C2:C))))))))&"♠")
     ,,999^99)),,999^99), "♦")), "♠"), 
     "select Col2,'Open',Col1 where Col2>4000 label 'Open''' format Col2 'YYYY-MM'", 0)))
    

    【讨论】:

    • 这不显示不同的月份。例如,ID0003 不会出现在列表中,因为它是在同一个月打开和关闭的。 ID0010 将有一行 2018-12
    • 看起来您使用的是NETWORKDAYS,但我需要知道之间有多少个月...
    • 我明白了。因此,关键在于,您不是使用CONCATENATE,而是添加一个字段分隔符并使用QUERY 标题连接方面进行连接。这很棒。我忘了提到它需要使用今天的日期来考虑开放票,但我想我可以接受你提供的东西并让它发挥作用。让我看看。谢谢!
    • 我能够使用您将列与QUERY 合并的数据并将其添加到我的函数中以获得所需的最终结果。我将用有效的最终答案更新我的问题。谢谢!
    • 我刚刚意识到我也可以使用SEQUENCE 函数来生成数字 1 到 x 的范围。哦!
    【解决方案2】:

    更新:

    我已经更新了我的解决方案以使用一种我喜欢将二维数组转换为 2 列数据集的重制表方法。下面这个公式在这个sample sheet.的C1中 您将在 F1 中看到一个类似的公式,该公式跳过了爆炸,如果这是图表的目标,则按月计算票数。 A1 中还有一个小公式,它只计算开放票的最大长度(以月为单位)。这在公式中多次使用,因此在视觉上为它设置一个辅助单元格很有帮助。如果您想避免使用任何辅助单元格,则可以轻松地将其替换为大型公式来代替 A1 参考。

    =ARRAYFORMULA(QUERY(VLOOKUP(SEQUENCE(COUNTA(Sheet1!A2:A)*A1,1,0)/A1+2,{ROW(Sheet1!A2:A),Sheet1!A2:A,IF(EDATE(EOMONTH(Sheet1!B2:B,-1)+1,SEQUENCE(1,A1,0))>EOMONTH(IFERROR(1/(1/Sheet1!C2:C),TODAY()),-1)+1,,EDATE(EOMONTH(Sheet1!B2:B,-1)+1,SEQUENCE(1,A1,0)))},MOD(SEQUENCE(COUNTA(Sheet1!A2:A)*A1,1,0),A1)*{0,1}+{2,3}),"where Col2 is not null label Col1'Ticket',Col2'Month'"))
    

    【讨论】:

    • 我实际上需要将原始数据分解出来,以便将其放入图表中以按月显示统计数据。
    • 啊,我明白了。我实际上有一个很好的,有点整洁的方法。现在要睡觉了,但可以在早上发布。
    • @IMTheNachoMan 我更新了我的解决方案。我知道你已经得到了你想要的东西,但你可能会发现这种方法在未来很有用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多