用EOMONTHs系列展开开始date到结束date

我有一个数据表,其中包含与两个相关的开始date和结束date的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 

我需要展开(即unpivot)这个表,以允许每个emonth在每个AcNo的开始date和结束date之间(含)。 行号是不重要的。

 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 

这又一次只扩展一行。

我将如何循环遍历将每个系列堆叠到一个列中的行? 任何对我的公式或代码进行调整的build议都会受到欢迎。

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

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

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

在这里输入图像描述

  • 使用Power QueryData Get & Transform除了前两列unpivot:( 很容易在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然后按datesorting结果:

在这里输入图像说明

请注意,以这种方式完成时,第一个date实际上是一个BOMdate,但是如果将它们格式化为结果,那么它看起来是一样的。 如果这是一个问题,事情很容易改变。

如果将第一个月作为BOMdate不需要:

  • 将公式更改为:

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

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

尝试使用DateDiff作为嵌套的… 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可以通过将下一个月的date设置为零来用作EOMONTH生成器。

请注意,在下图中,生成的月份是MMM yy单元格格式的系列中每月的EOMONTH。

在这里输入图像说明