【问题标题】:Excel - Find the last day of a month in a range given a specific year and month valueExcel - 在给定特定年份和月份值的范围内查找一个月的最后一天
【发布时间】:2022-02-24 16:41:40
【问题描述】:

我想知道我可以使用哪些 Excel/VBA 函数在具有特定年份和月份输入值的范围内查找一个月的最后一天。 例如,对于 '1995' 和 '3',它应该返回 '3/31/1995'。 对于 '1995' 和 '4',它应该返回 '4/28/1995'。

请注意,“04/1995”的实际最后一天是“4/30/1995”。我正在寻找范围内的最后一天,“1995 年 4 月 28 日”,所以我不能盲目地使用 EOMONTH 函数。

【问题讨论】:

  • 到目前为止你有什么尝试?
  • 这些是实际的日期值吗?你研究了什么?您标记了VBA,但如果您愿意,这也可以通过函数轻松完成
  • 您可以使用数组公式,例如 =MAX((MONTH($A$1:$A$18)=4)*(A1:A18)) 我在 a1:a18 中有各种日期
  • @Nathan_Sav 感谢您的评论。 4 有什么用?
  • 试试=INDEX($A:$A,MATCH(EOMONTH(DATE(1995,4,1),0),$A:$A,1))。这会计算出该月的实际最后一天,然后找到小于或等于该日期的最大数字。

标签: excel vba


【解决方案1】:

下面是一个 VBA 解决方案,应该可以工作并且速度相对较快。

我将范围内与年份和月份匹配的所有项目添加到ArrayList。然后,我按升序对该列表进行排序并选择列表中的最后一项(该项应具有集合中的最大值)。

这是在不到一秒的时间内运行通过大约 800 个项目的列表。

功能:

Option Explicit

Public Function MaxDateInRange(SearchRange As Range, _
                               YearNumber As Long, _
                               MonthNumber As Long) As String
    Dim cell        As Range
    Dim ListIndex   As Long
    Dim List        As Object: Set List = CreateObject("System.Collections.ArrayList")
    
    'Go through all cells, and all items that match the month and year to a list
    For Each cell In SearchRange
        If IsDate(cell) Then
            If Month(cell) = MonthNumber And Year(cell) = YearNumber Then List.Add (cell)
        End If
    Next
    
    'Sort the list ascending, then select the last item in that list
    List.Sort
    ListIndex = List.Count - 1
    
    'Bounds check, to see if anything was found, otherwise return ""
    If ListIndex >= 0 Then
        MaxDateInRange = List(ListIndex)
    Else
        MaxDateInRange = vbNullString
    End If
    
End Function

用法:

Public Sub Example()
    Dim rng As Range: Set rng = Sheets(2).Range("D1:D795")
    Dim t   As Double
    t = Timer
    
    Debug.Print MaxDateInRange(rng, 2019, 3)
    Debug.Print MaxDateInRange(rng, 2019, 4)

    Debug.Print "Process took " & Timer - t
End Sub

基于示例数据的调试输出:

2019-03-28
2019-04-25
Process took 0.04296875

【讨论】:

    【解决方案2】:

    另一种方法可能如下,我没有完全测试过,但可能值得深思。

    Function get_latest_date(rngInput As Excel.Range, intMonth As Integer, lngYear As Long) As Date
    
    get_latest_date = 0
    
    On Error Resume Next
    
    get_latest_date = Application.Evaluate( _
                    "=MAX(IF((YEAR(" & _
                    rngInput.Address & _
                    ")=" & lngYear & _
                    ")*(MONTH(" & _
                    rngInput.Address & _
                    ")=" & intMonth & ")," & rngInput.Address & "))")
    
    End Function
    

    这使用了从传入的参数构建的数组公式的评估。

    我有 10,000 个虚拟日期,从 2015 年到 2030 年以上。我使用以下内容进行了快速测试

    Function test_get_last_date()
    
    Dim r As Excel.Range
    Dim lYear As Long
    Dim iMonth As Integer
    Dim dTimer As Double
    
    Set r = Range("a1:a10000")
    
    dTimer = Timer
    
    For lYear = 2015 To 2030
    
        For iMonth = 1 To 12
    
            Debug.Print get_latest_date(r, iMonth, lYear), "Took : "; Timer - dTimer
            dTimer = Timer
    
        Next iMonth
    
    Next lYear
    
    
    End Function
    

    这给出了这些结果

    31/05/2017    Took :  0.02734375 
    30/06/2017    Took :  0.015625 
    31/07/2017    Took :  0.015625 
    31/08/2017    Took :  0.015625 
    30/09/2017    Took :  0.01953125
    

    【讨论】:

      【解决方案3】:

      你有两个选择:

      1. 您的数据已排序,您可以将 match 与 1 或 -1 第三个选项一起使用。正如 Darren Bartrup-Cook 所说的那样

      2. 否则,您必须添加 2 列公式才能对解决方案进行排序:

      B列,公式=year(A:A)&MONTH(A:A);连接你的标准

      C列,单元格C2中的公式=IFERROR(MAX((B$1:B1=B2)*(C$1:C1)),A2);然后向下展开公式

      B 列中每个唯一月份的 C 列中的最后一个值将是您的答案。您可以使用单元格 D2 =MAX(IF(B:B=B2,C2)) 中的公式提取 D 列中的结果;然后向下展开公式

      【讨论】:

        【解决方案4】:

        我将日期分为日、月和年列,然后使用 MAXIFS。

        =MAXIFS(B:B,C:C,3,D:D,1995)
        

        【讨论】:

        • 谢谢达曼。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-05-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-11-21
        • 1970-01-01
        相关资源
        最近更新 更多