【问题标题】:Populate all months between two dates填充两个日期之间的所有月份
【发布时间】:2021-01-25 06:58:09
【问题描述】:

我一直在尝试在 Excel 中创建一个公式来填充两个日期之间的月份。

我得到的只是 DatedIF() 但它不满足要求。

这是我想要的 Excel 公式中的图片。如果我更新开始日期或结束日期公式中的任何日期,将自动计算日期之间的所有月份,并在附图中给出结果。

代码结果和我想要的结果。代码应该与日期相应地工作。

https://docs.google.com/spreadsheets/d/1AbLs8soPOgQvorwIzWLIJIooIQiVg9fvKaBdxY0tmgU/edit#gid=1340167497

=IF(ROW()=15,0,IFERROR(INDEX(MONTH(EDATE(Sheet1!B$4,ROW(A$15:INDEX(A:A,DATEDIF(Sheet1!B$4,Sheet1!G$1,"m"))))),COUNT(A$15:A15)),""))

【问题讨论】:

  • 您使用的是哪个版本的 Excel?
  • @Darren Bartrup-Cook Excel 2016,但是如果数组函数在 excel 2016 中不可用,我可以拖动公式。我将相应地拖动公式。
  • 不确定 '16 是否有 SEQUENCE 功能?如果是,您可以使用=SEQUENCE(B3-B2,,0,1),其中 B3 和 B2 是您的日期。
  • 不,它不工作,我们可以使用 VBA 吗?如果公式不起作用。
  • 刚刚注意到 SEQUENCE 公式会给你一年中的几天而不是几个月......无论如何都不适合你。是的,VBA 解决方案是很有可能的。

标签: excel excel-formula excel-2016


【解决方案1】:

你可以试试:

A4中的公式:

=IF(ROW()=4,0,IFERROR(INDEX(MONTH(EDATE(B$1,ROW(A$1:INDEX(A:A,DATEDIF(B$1,B$2,"m"))))),COUNT(A$3:A3)),""))

向下拖动。

注意:例如,结束日期为“30-12-2021”时,最多只能显示 11 个。如果您仍希望看到最多 12 个,则需要使用 EOMONTH() 作为里面有一个嵌套函数。

【讨论】:

  • 感谢您解决问题,我附上了一个表格链接,我将单元格引用替换为sheet1,但它不起作用,请检查一下。
  • @Learning,我没有看到你的公式...?
  • 在 Sheet2 单元格 C15 中
  • 在@Darren Bartrup-Cook 答案中错误地添加了工作表链接。合资公司
  • 是的 Excel 2016 我只是作为示例添加的
【解决方案2】:

这将从第 5 行开始填充。毫无疑问,该代码可以用作数组公式。

Sub Test()

    With ThisWorkbook.Worksheets("Sheet1")
        PopulateMonths .Range("B2"), .Range("B3")
    End With

End Sub

Sub PopulateMonths(FirstDate As Range, SecondDate As Range)

    Dim MonthCount As Long
    MonthCount = DateDiff("m", FirstDate, SecondDate)
    
    With ThisWorkbook.Worksheets("Sheet1")
    
        'This will clear from row 5, column 1 to the last piece of data in column 1.
        'If column 1 is already empty it will clear from A1:A5, so best to check if
        'there's any data to clear before this line runs (just see if A5<>"")
        .Range(.Cells(5, 1), .Cells(.Rows.Count, 1).End(xlUp)).ClearContents
    
        Dim x As Long
        For x = 0 To MonthCount
            .Cells(x + 5, 1) = x 'Start on row 5, column 1.
        Next x
    
    End With
    
End Sub

【讨论】:

  • 感谢您的帮助,请看看我更新了您的代码结果
  • 我一直在使用此代码,当我编辑下个月或下一年的结束日期时,它工作正常,它给出了准确的结果,但是当我重新编辑日期时,它不会删除给定的结果。 @Darren Bartrup-Cook
  • 已更新代码以在添加新数据之前清除 A 列。
  • 谢谢@Darren Bartrup-Cook 现在它工作得很好
【解决方案3】:

填充两个日期之间的月份

  • 以下是使用Worksheet Change event 的自动版本,即它仅在您手动或通过VBA 更改值(而不是通过公式)时运行。您无需运行任何东西,只需将代码复制到相应的模块并调整常量部分中的值即可。
  • 如果出于某种原因不想自动化,可以删除sheet模块中的代码,删除标准模块中Option Explicit下面的三个常量,取消populateMonths中三个常量的注释。现在它只适用于populateMonthsInit
  • 如果开始日期是该月的最后一天,则该月将不包括在内。同样,如果结束日期是该月的第一个日期,则该月将不包括在内。这很容易调整。

表格模块,例如Sheet1

Option Explicit

Private Sub Worksheet_Change(ByVal Target As Range)
    Dim rng As Range
    Set rng = Intersect(Union(Range(StartDateCell), Range(EndDateCell)), Target)
    If Not rng Is Nothing Then
        populateMonths
    End If
End Sub

标准模块,例如Module1

Option Explicit
 
Public Const StartDateCell As String = "B1"
Public Const EndDateCell As String = "B2"
Private Const FirstCell As String = "B4"

Sub populateMonthsInit()
    populateMonths
End Sub

Sub populateMonths(Optional ws As Worksheet)
    'Const StartDateCell As String = "B1"
    'Const EndDateCell As String = "B2"
    'Const FirstCell As String = "B4"
    If ws Is Nothing Then
        Set ws = ThisWorkbook.ActiveSheet
    End If
    With ws.Range(FirstCell)
        Dim Data As Variant
        Data = getMonthNumbers(.Worksheet.Range(StartDateCell).Value, _
            .Worksheet.Range(EndDateCell).Value)
        .Resize(.Worksheet.Rows.Count - .Row + 1).ClearContents
        .Value = 0 ' Not sure what that's all about.
        If Not IsEmpty(Data) then
            .Offset(1).Resize(UBound(Data, 1)).Value = Data
        End if
    End With
End Sub

Function getMonthNumbers( _
    ByVal StartDate As Date, _
    ByVal EndDate As Date) _
As Variant
    On Error GoTo clearError
    Dim Months As Long: Months = DateDiff("m", StartDate, EndDate)
    Dim StartMonth As Long
    If Month(StartDate + 1) = Month(StartDate) Then
        Months = Months + 1
        StartMonth = modMonth(Month(StartDate))
    Else
        StartMonth = modMonth(Month(StartDate) + 1)
    End If
    If Month(EndDate - 1) <> Month(EndDate) Then
        Months = Months - 1
    End If
    Dim Data() As Long: ReDim Data(1 To Months, 1 To 1)
    Data(1, 1) = StartMonth
    Dim i As Long
    For i = 2 To Months
        Data(i, 1) = modMonth(Data(i - 1, 1) + 1)
    Next i
    getMonthNumbers = Data
ProcExit:
    Exit Function
clearError:
    Resume ProcExit
End Function

Function modMonth( _
    m As Long) _
As Long
    modMonth = IIf(m Mod 12, m Mod 12, 12)
End Function

Sub TESTgetMonthNumbers()
    Dim Data As Variant: Data = getMonthNumbers(Range("B1"), Range("B2"))
    If Not IsEmpty(Data) Then
        Debug.Print Join(Application.Transpose(Data), vbLf)
    Else
        Debug.Print "Nope."
    End If
End Sub

【讨论】:

    猜你喜欢
    • 2015-05-20
    • 1970-01-01
    • 2019-03-28
    • 2015-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多