【问题标题】:How do we aggregate time series in Excel?我们如何在 Excel 中聚合时间序列?
【发布时间】:2019-10-07 18:32:53
【问题描述】:

鉴于以下现金流时间序列,我如何将它们聚合成 Excel 中的累积现金流时间序列,理想情况下仅使用数组公式而不使用 VBA 宏?

具体来说,我得到了每笔交易的现金流时间序列:

鉴于每个时期的交易数量的输入(在 F 列中),我希望能够计算总现金流的聚合时间序列(在 G 列中,以黄色突出显示),理想情况下使用数组公式只有和没有 VBA 宏?

注意:H 到 J 列仅用于说明如何计算 G 列,我不希望它们出现在我的最终电子表格中。

非常感谢您的帮助!

【问题讨论】:

    标签: excel excel-formula


    【解决方案1】:

    我相信您可以通过公式来做到这一点 - 最简单的方法是反转现金流并乘以当前和之前的 5 笔交易:

    =SUMPRODUCT(INDEX(F:F,MAX(ROW()-5,3)):F16*INDEX(C:C,MAX(11-ROW(),3)):$C$8)
    

    在 G3 中。

    这是一个普通的非数组公式。

    【讨论】:

    • 感谢您提供简洁优雅的解决方案。是否有一个简单的 Excel 公式可以帮助扭转 C 列中的现金流?谢谢。
    • 好问题!在这种特殊情况下,它只是 =INDEX(B:B,11-ROW()) 。下一个问题是您是否可以将其直接放入主要公式中-必须考虑那个。简短的回答(我认为)是你最终会使用 offset 或相当古怪的 index(B:B,n(if({1}... 构造哪种失去原始公式的简单性。
    【解决方案2】:

    这也可以在 Power Query 中完成。

    请参阅此article,了解如何在您的 Excel 版本上使用 Power Query。它在 Excel 2010 Professional Plus 及更高版本中可用。我的演示使用的是 Excel 2016

    步骤是:

    1. time series of cash-flow2-column output table 这两个表加载到电源查询编辑器,那么您应该:

    1. 对于第一个表,将Period列与Cashflow列合并,以分号;作为分隔符;
    2. 转置列/表,然后用逗号,作为分隔符合并列;
    3. 使用此公式="Connector" 添加自定义列,该列将使用单词Connector 填充列,那么您应该:

    1. 对于第二个表格,还添加一个自定义列,使用相同的公式="Connector" 将用单词Connector 填充列;
    2. 使用Custom 列作为连接将第二个表与第一个表合并,然后展开新列以显示第一个表中的Merged 列,那么您应该有:

    1. 删除Custom 列,然后用分隔符逗号, 拆分Merged 列并将结果放入Rows
    2. 用分隔符分号; 再次拆分Merged 列,将PeriodCashflow 与第一个表分开;
    3. 添加一个自定义列来计算New Period=[Period]+[Merged.1]
    4. 添加另一个自定义列来计算Cashflow=[#"# Tran"]*[Merged.2],那么您应该有如下内容:

    1. New PeriodCashflow 列进行分组/求和。

    完成后,您可以关闭并加载结果到新工作表(默认情况下)。如果要在最终输出中显示# Trans 列,可以在进行任何更改之前复制第二个表,然后通过Period 列将其与最终输出表合并以显示相应的数量交易。

    这是第一个表的电源查询M代码:

    let
        Source = Excel.CurrentWorkbook(){[Name="Tbl_CFS"]}[Content],
        #"Changed Type" = Table.TransformColumnTypes(Source,{{"Period", Int64.Type}, {"Cashflow", Int64.Type}}),
        #"Merged Columns1" = Table.CombineColumns(Table.TransformColumnTypes(#"Changed Type", {{"Period", type text}, {"Cashflow", type text}}, "en-AU"),{"Period", "Cashflow"},Combiner.CombineTextByDelimiter(";", QuoteStyle.None),"Merged"),
        #"Transposed Table" = Table.Transpose(#"Merged Columns1"),
        #"Merged Columns" = Table.CombineColumns(Table.TransformColumnTypes(#"Transposed Table", {{"Column1", type text}, {"Column2", type text}, {"Column3", type text}, {"Column4", type text}, {"Column5", type text}, {"Column6", type text}}, "en-AU"),{"Column1", "Column2", "Column3", "Column4", "Column5", "Column6"},Combiner.CombineTextByDelimiter(",", QuoteStyle.None),"Merged"),
        #"Added Custom" = Table.AddColumn(#"Merged Columns", "Custom", each "Connector")
    in
        #"Added Custom"
    

    下面是第二张表的代码:

    let
        Source = Excel.CurrentWorkbook(){[Name="Tbl_Total"]}[Content],
        #"Changed Type" = Table.TransformColumnTypes(Source,{{"Period", Int64.Type}, {"# Tran", Int64.Type}}),
        #"Added Custom" = Table.AddColumn(#"Changed Type", "Custom", each "Connector"),
        #"Merged Queries" = Table.NestedJoin(#"Added Custom", {"Custom"}, Tbl_CFS, {"Custom"}, "Tbl_CFS", JoinKind.LeftOuter),
        #"Expanded Tbl_CFS" = Table.ExpandTableColumn(#"Merged Queries", "Tbl_CFS", {"Merged"}, {"Merged"}),
        #"Removed Columns" = Table.RemoveColumns(#"Expanded Tbl_CFS",{"Custom"}),
        #"Split Column by Delimiter" = Table.ExpandListColumn(Table.TransformColumns(#"Removed Columns", {{"Merged", Splitter.SplitTextByDelimiter(",", QuoteStyle.Csv), let itemType = (type nullable text) meta [Serialized.Text = true] in type {itemType}}}), "Merged"),
        #"Changed Type1" = Table.TransformColumnTypes(#"Split Column by Delimiter",{{"Merged", type text}}),
        #"Split Column by Delimiter1" = Table.SplitColumn(#"Changed Type1", "Merged", Splitter.SplitTextByDelimiter(";", QuoteStyle.Csv), {"Merged.1", "Merged.2"}),
        #"Changed Type2" = Table.TransformColumnTypes(#"Split Column by Delimiter1",{{"Merged.1", Int64.Type}, {"Merged.2", Int64.Type}}),
        #"Added Custom1" = Table.AddColumn(#"Changed Type2", "New Period", each [Period]+[Merged.1]),
        #"Added Custom2" = Table.AddColumn(#"Added Custom1", "Cashflow", each [#"# Tran"]*[Merged.2]),
        #"Grouped Rows" = Table.Group(#"Added Custom2", {"New Period"}, {{"Sum", each List.Sum([Cashflow]), type number}})
    in
        #"Grouped Rows"
    

    所有步骤都使用内置函数,因此应该简单明了且易于执行。让我知道是否有任何问题。干杯:)

    【讨论】:

      【解决方案3】:

      OK 把这个数组公式放到 G3 中:

      =IFERROR(SUMPRODUCT(INDEX($B$2:$B$7,N(IF({1},MODE.MULT(IF(INDEX(F:F,MAX(ROW()-5,3)):F3>0,(ROW()-ROW(INDEX(F:F,MAX(ROW()-5,3)):F3)+1)*{1,1}))))),INDEX(INDEX(F:F,MAX(ROW()-5,3)):F3,N(IF({1},MODE.MULT(IF(INDEX(F:F,MAX(ROW()-5,3)):F3>0,(ROW(INDEX(F:F,MAX(ROW()-5,3)):F3)-MIN(ROW(INDEX(F:F,MAX(ROW()-5,3)):F3))+1)*{1,1})))))),0)
      

      作为数组公式,退出编辑模式时必须使用 Ctrl-Shift-Enter 确认,而不是 Enter。然后抄下来。


      一旦微软发布了FILTERSEQUENCE,它就可以被缩短:

      =IFERROR(SUMPRODUCT(INDEX($B$2:$B$7,FILTER(SEQUENCE(ROW()-MAX(ROW()-5,3)+1,,ROW()-MAX(ROW()-5,3)+1,-1),INDEX(F:F,MAX(ROW()-5,3)):F3>0)),FILTER(INDEX(F:F,MAX(ROW()-5,3)):F3,INDEX(F:F,MAX(ROW()-5,3)):F3>0)),0)
      

      【讨论】:

      • 谢谢!你能解释一下这两个公式是如何工作的吗?
      • @vkc 这需要对所有部分有很多了解。只需说它使用 N() 将行号数组返回到索引,该索引根据 F 中的值相对于公式所在的位置大于 0 的位置来提取正确的值。必须处理标准范围中的单元格少于事务中的单元格的事实。这就是为什么 vba 更适合这样的事情。更易于维护。
      猜你喜欢
      • 2011-04-28
      • 2018-05-18
      • 2015-05-28
      • 1970-01-01
      • 2018-04-16
      • 1970-01-01
      • 2015-10-11
      • 2023-03-07
      • 1970-01-01
      相关资源
      最近更新 更多