如何开发VBA宏以确定给定年份的10月的最后一个星期六? (4)
答案 0 :(得分:2)
答案 1 :(得分:1)
尝试以下公式
=EOMONTH(A1,0)-WEEKDAY(EOMONTH(A1,0),2)-1
答案 2 :(得分:1)
Function LSat10(Year As Long) As Date
Dim i As Long
Dim vntDate As Date
vntDate = DateSerial(Year, 10, 31)
For i = 0 To 6
If Weekday(vntDate - i) = 7 Then Exit For
Next
LSat10 = vntDate - i
End Function
正如T.M.在评论中指出的那样,使用Weekday
函数有一个更好的解决方案:
Function LSat10(Year As Long) As Date
Dim vntDate As Date
vntDate = DateSerial(Year, 10, 31)
LSat10 = vntDate - (Weekday(vntDate) Mod 7)
End Function
尽管这可能是最好的解决方案,但通过设置为{{1}的默认将{'1'}绑定到firstdayofweek
函数的Weekday
参数{1}}),第7天是“偶然”星期六。
要进一步开发其他日子和月份的功能,solution的user11040196中的方法要好得多(关于下个月1号的使用):一个月可以是 28-31 ,但是第一天只能是 1 。
我在开发以下函数时使用了这种方法,该函数计算任何一年中任何月份的任何(星期)天的最后日期(Excel支持4位数字的年份1900-9999。不包括。)。它具有三个参数:(周)日,月和年均以数字形式输入。在开发它的过程中,我对用户可以输入的内容产生了过多的负担,因此它更多地是对Variant,IsMissing和其他“错误处理”方法的研究。
1
美国
要计算2019年10月的最后一个星期六:
vbSunday
要计算1999年4月的最后一个星期三,
'*******************************************************************************
' Purpose: Returns the date of a last weekday of a month of a year.
' Inputs
' dmlWeekDay: Depending on the FirstDayOfWeek constant, it is the numeric
' presentation of a weekday e.g. if FirstDayOfWeek is 1 (for
' US, CA, JP), 1 is Sunday, 2 is Monday , 3 is Tuesday etc.
' dmlMonth: The numeric presentation of a month.
' dmlYear: A specified year.
' FirstDayOfWeek as Constant: This argument has been left as a constant
' on purpose, so it has to be changed directly in the code.
' For US or wherever the FDoW is Sunday, use 1. For EU or
' wherever the FDoW is Monday, use 2. For ME or wherever the
' FDoW is Saturday, use 7 etc.
' Returns: A Date when dmlWeekday and dmlMonth are literally any number
' or omitted and dmlYear is any positive or negative number from
' 1900-9999 or omitted. An empty string ("") otherwise.
'*******************************************************************************
Function DAYMONL(Optional ByVal dmlWeekDay, Optional ByVal dmlMonth, _
Optional ByVal dmlYear)
' First Day of Week
Const FirstDayOfWeek As Long = 1 ' 1 (Sunday), 2 (Monday), 7 (Saturday)
Dim vntDay As Variant ' Weekday "firstdayofweek" Parameter Array
Dim dt As Date ' 1st of Next Month
DAYMONL = "" ' To return after Exit Function.
' Choose Weekday "firstdayofweek" Parameter Array.
Select Case FirstDayOfWeek
Case 1: vntDay = Array(7, 1, 2, 3, 4, 5, 6) ' Sunday: US, CA, JP
Case 2: vntDay = Array(6, 7, 1, 2, 3, 4, 5) ' Monday: EU
Case 7: vntDay = Array(1, 2, 3, 4, 5, 6, 7) ' Saturday: ME
'Case 3: vntDay = Array(5, 6, 7, 1, 2, 3, 4) ' Tuesday:
'Case 4: vntDay = Array(4, 5, 6, 7, 1, 2, 3) ' Wednesday:
'Case 5: vntDay = Array(3, 4, 5, 6, 7, 1, 2) ' Thursday:
'Case 6: vntDay = Array(2, 3, 4, 5, 6, 7, 1) ' Friday:
Case Else: MsgBox "Wrong FirstDayOfWeek parameter.": Exit Function
End Select
' Weekday
If IsMissing(dmlWeekDay) Then
dmlWeekDay = WeekDay(Date) ' Today('s (Week)Day)
Else
' Ensure that dmlWeekDay is a number.
If Not IsNumeric(dmlWeekDay) Then Exit Function
' Int ensures whole number.
' Abs ensures positive number.
' Mod ensures number from 1 to 7.
dmlWeekDay = Abs(Int(dmlWeekDay)) Mod 7
' 0 is useless, 7 is needed.
If dmlWeekDay = 0 Then dmlWeekDay = 7
'dmlWeekDay = Int(dmlWeekDay)
'If dmlWeekDay < 1 Or dmlWeekDay > 7 Then Exit Function
End If
' Month
If IsMissing(dmlMonth) Then
dmlMonth = Month(Date) ' Today's Month
Else
' Ensure that dmlMonth is a number.
If Not IsNumeric(dmlMonth) Then Exit Function
' Int ensures whole number.
' Abs ensures positive number.
' Mod ensures number from 1 to 12.
dmlMonth = Abs(Int(dmlMonth)) Mod 12
' 0 is useless, 12 is needed.
If dmlMonth = 0 Then dmlMonth = 12
'dmlMonth = Int(dmlMonth)
'If dmlMonth < 1 Or dmlMonth > 12 Then Exit Function
End If
' Year
If IsMissing(dmlYear) Then
dmlYear = Year(Date) ' Today's dmlYear
Else
' Ensure that dmlYear is a number.
If Not IsNumeric(dmlYear) Then Exit Function
' Int ensures whole number.
' Abs ensures positive number.
dmlYear = Abs(Int(dmlYear))
' Ensure dmlYear is a number from 1900 to 9999.
If dmlYear < 1900 Or dmlYear > 9999 Then Exit Function
If dmlYear = 9999 And dmlMonth = 12 Then
' Excel doesn't support dates greater than 12/31/9999.
' The following "dmlMonth + 1" would produce an error.
DAYMONL = DateSerial(9999, 12, 24 _
+ Application.Match(dmlWeekDay, vntDay, 0))
Exit Function
End If
End If
' Write the date of the 1st of next month to a variable.
dt = DateSerial(dmlYear, dmlMonth + 1, 1)
' Subtract the match (position) of dmlWeekday in Weekday "firstdayofweek"
' Parameter Array from dt.
DAYMONL = dt - WeekDay(dt, Application.Match(dmlWeekDay, vntDay, 0))
End Function
欧盟
要在每周的第一天为星期一的情况下使用该功能,必须将=DAYMONL(7,10,2019)
常量“手动”更改为=DAYMONL(4,4,1999)
。然后,您可以对前两个示例使用以下公式:
FirstDayOfWeek