ExcelTip.Net留存知识帖 ---【注:附件之前被网盘供应商清空后,现已修复-现已修复-现已修复为本地下载!】
现在位置:首页 > 我的酷贴 > Excel VBA > 求指定时间前后N个月的日期(自定义函数)

求指定时间前后N个月的日期(自定义函数)

作者:绿色风 分类: 时间:2022-08-18 浏览:95
楼主
DJ_Soo
Q:edate函数可以返回某个日期之前或之后几个月的日期,但是遇到如4月30号往后推一个月,就不能判断30号是4月最后一天.结果为5月30,这个时候与我想要的5月31相差了一天.如何解决这样的问题呢?
A:用自定义函数解决此问题:
ALT+F11→插入模块→输入以下代码:
  1. Function mDate(Start_Date As Date, Months As Integer) As Date
  2.     Dim LstDay As Byte
  3.     LstDay = Day(DateSerial(Year(Start_Date), Month(Start_Date) + 1, 0))
  4.     If Day(Start_Date) = LstDay Then
  5.         mDate = DateSerial(Year(Start_Date), Month(Start_Date) + Months + 1, 0)
  6.     Else
  7.         mDate = DateSerial(Year(Start_Date), Month(Start_Date) + Months, Day(Start_Date))
  8.     End If
  9. End Function
测试:
  1. Sub Test()
  2.     Dim testDate As Date
  3.     testDate = Application.InputBox("请输入测试日期", "测试", "2012-2-29")
  4.     MsgBox mDate(testDate, 1)
  5. End Sub
默认测试结果为"2012-3-31"
当然,函数本身有edate也可以有"类似"效果,但是对于月末最后一天的判断还要根据需要自行选择是使用edate还是自定义.
测试中仅往后推一个月,测试日期可随意输入.
mdate.rar

修改了一次代码:
  1. Function mDate(Start_Date As Date, Months As Integer) As Date
  2.     Dim LstDay As Byte
  3.     LstDay = Day(DateSerial(Year(Start_Date), Month(Start_Date) + 1, 0))
  4.     If Day(Start_Date) = LstDay Then
  5.         mDate = DateSerial(Year(Start_Date), Month(Start_Date) + Months + 1, 0)
  6.     Else
  7.         mDate = DateSerial(Year(Start_Date), Month(Start_Date) + Months, Day(Start_Date))
  8.         If Month(mDate) <> (Month(Start_Date) + Months) Mod 12 Then'增加一次判断,弥补二楼所指出的缺陷.
  9.             mDate = DateSerial(Year(Start_Date), Month(Start_Date) + Months + 1, 0)
  10.         End If
  11.     End If
  12. End Function
再次修改..
  1. Function mDate(Start_Date As Date, Months As Integer) As Date
  2.     Dim LstDay As Byte
  3.     LstDay = Day(DateSerial(Year(Start_Date), Month(Start_Date) + 1, 0))
  4.     If Day(Start_Date) = LstDay Then
  5.         mDate = DateSerial(Year(Start_Date), Month(Start_Date) + Months + 1, 0)
  6.     Else
  7.         mDate = DateSerial(Year(Start_Date), Month(Start_Date) + Months, Day(Start_Date))
  8.         If (Month(mDate) - (Month(Start_Date) + Months) Mod 12) Mod 12 <> 0 Then '增加一次判断,弥补4楼所指出的缺陷.
  9.             mDate = DateSerial(Year(Start_Date), Month(Start_Date) + Months + 1, 0)
  10.         End If
  11.     End If
  12. End Function
更简单的,VBA内置函数:
  1. Function mDate(Start_Date As Date, Months As Integer) As Date
  2.     mDate=DateAdd("m",Months,Start_Date)
  3. End Function
2楼
gouweicao78
EDATE,如果是3月31日往后推1个月,会得到4月30日(从多往少),3月30日推一个月也是4月30日。
但4月30日往后推一个月要得到5月31日,确实需要再判断一次,毕竟这样的应用也不多。

另,此帖的自定义函数也存在一个问题:
mdate("2010-1-29",1)得到的是2010-3-1,又作如何处理?也就是说,这个“规则”并不完善。
3楼
gouweicao78
使用工作表内置函数,假设起始日期在A1,间隔月数在B1,公式:
  1. =IF(A1=EOMONTH(A1,0),EOMONTH(A1,B1),EDATE(A1,B1))
即,判断A1是否月末日期,如果是月末日期,则返回间隔B1个月后的月末日期,否则按EDATE返回间隔月数后的日期。
4楼
gouweicao78
新代码仍然有问题:
mdate("2010/1/29",-1)得到2009-12-31,实际应该是2009-12-29

免责声明

有感于原ExcelTip.Net留存知识的价值及部分知识具有的时间限定性因素, 经与ExcelTip.Net站长Apolloh商议并征得其同意, 现将原属ExcelTip.Net的知识帖采集资料于本站点进行展示, 供有需要的人士查询使用,也慰缅曾经的论坛时代。 所示各个帖子的原作者如对版权有异议, 可与本人沟通提出,或于本站点留言,我们会尽快处理。 在此,感谢ExcelTip.Net站长Apolloh的支持,感谢本站点所有人**绿色风(QQ:79664738)**的支持与奉献,特此鸣谢!
------本人网名**KevinChengCW(QQ:1210618015)**原ExcelTip.Net总版主之一

评论列表
sitemap