繁体   English   中英

使用EOMONTH系列展开开始日期到结束日期

[英]Expand Start Date to End Date with Series of EOMONTHs

我有一个包含ID的数据表,其中包含与两者相关的开始日期和结束日期。

RowNo   AcNo     StartDate     EndDate
  1     R125     01/10/2017    30/09/2020
  2     R126     01/10/2017    30/09/2018
  3     R127     01/10/2017    30/09/2019
  4     R128     01/10/2017    30/09/2020

我需要扩展(即,取消忽略)此表,以便为每个AcNo的开始和结束日期(包括)之间的每个eomonth允许一行。 行号不重要。

AcNo    EOMONTHs
R125    Oct 17
R125    Nov 17
R125    Dec 17
R125    Jan 18
R125    Feb 18
R125    Mar 18
    ...
R128    Apr 20
R128    May 20
R128    Jun 20
R128    Jul 20
R128    Aug 20
R128    Sep 20

我可以用这样的公式做每一行,

'in F2
=IF(ROW(1:1)-1<DATEDIF(C$2, D$2, "m"), B$2, TEXT(,))
'in G2
=IF(ROW(1:1)-1<DATEDIF(C$2, D$2, "m"), EOMONTH(C$2, ROW(1:1)-1), TEXT(,))
'F2:G2 filled down

但是我有数千行AcNos,这对于单个行执行是不实用的。

我还使用VBA的DateDiff为各行形成一个循环。

    Dim m As Long, ms As Long
    With Worksheets("Sheet2")
        .Range("F1:G1") = Array("AcNo", "EOMONTHs")
        ms = DateDiff("m", .Cells(2, "C").Value2, .Cells(2, "D").Value2)
        For m = 1 To ms + 1
            .Cells(m, "M") = .Cells(2, "B").Value2
            .Cells(m, "N").Formula = "=EOMONTH(C$2, " & m - 1 & ")"
        Next m
    End With

同样,这一次只扩展一行。

我如何遍历将每个系列堆叠成一列的行? 我欢迎任何调整我的公式或代码的建议。

尝试使用DateDiff作为嵌套For ... Next循环来确定月数。 收集数组中的渐进值将加速执行,然后将它们转储回工作表。

Option Explicit

Sub eoms()
    Dim a As Long, m As Long, ms As Long, vals As Variant
    With Worksheets("Sheet2")
        .Range("F1:G1") = Array("AcNo", "EOMONTHs")
        For a = 2 To .Cells(.Rows.Count, "B").End(xlUp).Row
            ms = DateDiff("m", .Cells(a, "C").Value2, .Cells(a, "D").Value2)
            ReDim vals(1 To ms + 1, 1 To 2)
            For m = 1 To ms + 1
                vals(m, 1) = .Cells(a, "B").Value2
                vals(m, 2) = DateSerial(Year(.Cells(a, "C").Value2), _
                                        Month(.Cells(a, "C").Value2) + m, _
                                        0)
            Next m
            .Cells(.Rows.Count, "F").End(xlUp).Offset(1, 0).Resize(UBound(vals, 1), UBound(vals, 2)) = vals
        Next a
        .Range(.Cells(2, "G"), .Cells(.Rows.Count, "G").End(xlUp)).NumberFormat = "mmm yy"
    End With
End Sub

通过将下一个月的日期设置为零,可以将VBA的DateSerial用作EOMONTH生成器。

请注意,在下图中,生成的月份是系列中每个月的EOMONTH,其中包含mmm yy单元格编号格式。

在此输入图像描述

只是因为你似乎在寻求多个选项,这里有一个没有VBA:

  • 使用公式将表扩展到右侧(使用结构化引用):

=IF(EOMONTH(Table1[@[StartDate]:[StartDate]],COLUMNS($A:A))<Table1[@[EndDate]:[EndDate]],EOMONTH(Table1[@[StartDate]:[StartDate]],COLUMNS($A:A)),"")

在此输入图像描述

  • 使用Power QueryData Get & Transform来取消所有除前两列之外的所有内容:( 在GUI中轻松完成,但我粘贴以下代码以获取兴趣)

let
    Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
    #"Changed Type" = Table.TransformColumnTypes(Source,{{"RowNo", Int64.Type}, {"AcNo", type text}, {"StartDate", type datetime}, {"EndDate", type datetime}, {"Column1", type datetime}, {"Column2", type datetime}, {"Column3", type datetime}, {"Column4", type datetime}, {"Column5", type datetime}, {"Column6", type datetime}, {"Column7", type datetime}, {"Column8", type datetime}, {"Column9", type datetime}, {"Column10", type datetime}, {"Column11", type datetime}, {"Column12", type datetime}, {"Column13", type datetime}, {"Column14", type datetime}, {"Column15", type datetime}, {"Column16", type datetime}, {"Column17", type datetime}, {"Column18", type datetime}, {"Column19", type datetime}, {"Column20", type datetime}, {"Column21", type datetime}, {"Column22", type datetime}, {"Column23", type datetime}, {"Column24", type datetime}, {"Column25", type datetime}, {"Column26", type datetime}, {"Column27", type datetime}, {"Column28", type datetime}, {"Column29", type datetime}, {"Column30", type datetime}, {"Column31", type datetime}, {"Column32", type datetime}, {"Column33", type datetime}, {"Column34", type datetime}}),
    #"Unpivoted Other Columns" = Table.UnpivotOtherColumns(#"Changed Type", {"RowNo", "AcNo"}, "Attribute", "Value"),
    #"Removed Columns" = Table.RemoveColumns(#"Unpivoted Other Columns",{"Attribute"}),
    #"Renamed Columns" = Table.RenameColumns(#"Removed Columns",{{"Value", "EOM Date"}}),
    #"Changed Type1" = Table.TransformColumnTypes(#"Renamed Columns",{{"EOM Date", type date}})
in
    #"Changed Type1"
  • 按AcNo排序结果,然后按日期排序:

在此输入图像描述

请注意,以这种方式完成时,第一个日期实际上是一个BOM日期,但如果您按照结果格式化它们,mmm yy,它看起来会一样。 如果这是一个问题,事情很容易改变。

如果不希望第一个月作为BOM日期:

  • 将公式更改为:

=IF(EOMONTH(Table1[@[StartDate]:[StartDate]],COLUMNS($A:A)-1)<=Table1[@[EndDate]:[EndDate]],EOMONTH(Table1[@[StartDate]:[StartDate]],COLUMNS($A:A)-1),"")

  • 执行Data Get & Transform ,删除Query GUI编辑器中的StartDate列,因为这不会影响当时的其他列。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM