在VBA中查找一个月或一年的第一天和最后一天的最简单方法

在VBA中查找一个月或一年的第一天和最后一天的最简单方法,vba,excel,Vba,Excel,我有两个选择年份和月份的下拉列表。在月下拉列表中有1月、2月、3月、12月和所有选项。201620170201820192020年 我需要一个函数,返回第一天的选择。如果选择了2017和All,则应返回2017年1月1日。如果是2017年和7月,则返回值应为2017年7月1日 另一个功能正好相反。如果用户给出2018年和所有,则应返回2018年12月31日。如果用户提供2018年2月和2018年2月,则应返回2018年2月28日 那么对于这种情况,哪一个是最好的解决方案 第一天我做了如下尝试 F

我有两个选择年份和月份的下拉列表。在月下拉列表中有1月、2月、3月、12月和所有选项。201620170201820192020年

我需要一个函数,返回第一天的选择。如果选择了2017和All,则应返回2017年1月1日。如果是2017年和7月,则返回值应为2017年7月1日

另一个功能正好相反。如果用户给出2018年和所有,则应返回2018年12月31日。如果用户提供2018年2月和2018年2月,则应返回2018年2月28日

那么对于这种情况,哪一个是最好的解决方案

第一天我做了如下尝试

Function firstDay(year As String, month As String) As Date
    Dim fd As Date
    If LCase(month) = "all" Then month = "JAN"
    fd = DateValue("01 " & month & Space(1) & year)
    firstDay = fd
End Function

但最后一天我不知道怎么做,或者我尝试的解决方案不是很好。因此,如果有更好的选择,也希望在第一天的cource中有更好的解决方案,我将共享我创建的用于此目的的函数。所以对于那些有类似要求的人可以使用

Function lastDay(year As String, month As String) As Date
    Dim ld As Date
    If LCase(month) = "all" Then month = "DEC"
    ld = DateValue("01 " & month & Space(1) & year)
    Dim d As Double
    d = WorksheetFunction.EoMonth(ld, 0)
    ld = CDate(d)
    lastDay = ld
End Function

这应该适用于所有月份,无论它们有多长:

Function lastDay(year As String, month As String) As Date
    Dim fd As Date
    If LCase(month) = "all" Then month = "DEC"
    fd = DateValue("01 " & month & Space(1) & year) + 32
    fd = fd - Day(fd)
    lastDay = fd
End Function

这是我对你函数的理解

Function endofdates(yr As Integer, _
                    mth As Integer, _
                    Optional firstday As Boolean = True) As Date
    If firstday Then
        endofdates = DateSerial(yr, mth, 0) + 1
    Else
        endofdates = DateSerial(yr, mth + 1, 0)
    End If
End Function
编辑1:重新阅读你的问题,发现你不能使用上面的内容,所以我写了它来满足你的需要

Function endofdates(yr As Integer, _
                    mth_name As String, _
                    Optional firstday As Boolean = True) As Date
    Dim mth As Integer, idx As Integer
    Const mlist As String = "JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC"
    idx = InStr(1, mlist, mth_name, vbTextCompare)
    mth = Int(idx / 3) + (idx Mod 3)
    If firstday Then
        If mth = 0 Then mth = 1
        endofdates = DateSerial(yr, mth, 0) + 1
    Else
        If mth = 0 Then yr = yr + 1
        endofdates = DateSerial(yr, mth + 1, 0)
    End If
End Function
Edit2:我想您使用DateValue的逻辑更简单:

Function endofdates(yr As Integer, _
                    mth_name As String, _
                    Optional firstday As Boolean = True) As Date
    Dim dt As Date
    If firstday Then
        If LCase$(mth_name) = "all" Then mth_name = "jan"
        dt = DateValue("1 " & mth_name & " " & yr)
    Else
        If LCase$(mth_name) = "all" Then mth_name = "dec"
        dt = DateValue("1 " & mth_name & " " & yr)
        dt = DateSerial(Year(dt), Month(dt) + 1, 0)
    End If
    endofdates = dt
End Function