编辑以澄清:返回的日期必须小于当前日期的 24 个月,因为这是到期日期,除非续订,否则物品必须在正确的时间到期。换句话说,日期需要尽可能接近 2 年的续订周期,但不能超过 2 年。
原帖:早上好!我一直在谷歌上搜索,但一无所获,所以我希望我能帮上忙创建一个公式。我需要创建一个不引用其他单元格的公式,因为我希望限制其他用户的错误数量 :)
我需要的是:找到距离今天大于 18 个月但小于 24 个月的 03/31 或 09/30 的下一个实例。
根据我上面的措辞,我觉得 TODAY、OR、<、> 和月/日标识符的某种组合可以给出我想要的结果,但我对操作顺序感到困惑。目前我的同事正在使用表格(见下文)手动计算这些日期,这很繁琐。
- 四月至九月奇数 = 三月下一个奇数
- 四月 - 九月偶数 = 下个三月偶数
- 十月双数 - 三月单数 = 九月下一个双数
- 10 月单数 - 3 月双数 = 9 月下一个单数
提前感谢任何意见,如果我下班后想出一个粗略的公式,我会对其进行编辑!
答案1
这是一个易于理解、基于公式、非数组的解决方案,适用于 Excel 2010(及更早版本)。它使用辅助列(可以隐藏)。
由于 <24 个月和 >18 个月的要求并不总是能够满足,而硬性要求是 <24 个月,因此我放宽了另一端的要求至 >=18 个月。
对于任何给定的日期,只有三个可能的目标日期:该日期后 18 个月的 3 月 31 日或 9 月 30 日,或次年的 3 月 31 日。您只需选择符合条件的第一个日期即可。
问题指定了基于 TODAY 的结果。我还想展示这在其他“今天”上的表现。单元格 A2 包含=TODAY()
。A 列中的其他单元格只是一些其他日期,用于说明;尤其是与 3/31 和 9/30 相关的“边界日期”上的日期。公式引用日期单元格,但 TODAY() 可以改为硬编码。
I:J 列仅用于说明。它们显示距离 A 列日期 18 个月和 24 个月的日期,以帮助理解为何选择结果值。
辅助列是 C:E。这些列包含 A 列中日期的三个候选目标日期。C2 中的目标 1 包含:
=DATE(YEAR(EDATE(A2,18)),3,31)
这将创建从 A 列日期开始 18 个月后的日期 3/31。D2 中的目标 2 包含:
=DATE(YEAR(EDATE(A2,18)),9,30)
这将创建从 A 列日期开始 18 个月后的日期 9/30。E2 中的目标 3 包含:
=DATE(YEAR(EDATE(A2,18))+1,3,31)
这将创建 A 列日期后 18 个月的年份的日期 3/31。
结果在G列。G2中的公式:
=SUMPRODUCT((C2:E2<EDATE(A2,24))*(C2:E2>=EDATE(A2,18))*C2:E2)
由于要求,只有一个目标日期符合条件。SUMPRODUCT 使用普通(非数组)公式处理数组比较。
C2:E2<EDATE(A2,24)
根据每个目标日期是否距离 A 列日期小于 24 个月,返回 TRUE/FALSE(1/0)。
C2:E2>=EDATE(A2,18)
类似地,根据日期是否距离 A 列日期 >= 18 个月,为每个目标日期返回 1/0。
只有一个目标日期会同时满足两个条件,因此这些 1/0 值的乘积将1
针对该日期和0
其他两个日期。该乘积将乘以每个目标日期单元格中的值。由于日期以数字形式存储,因此结果就是代表合格目标日期的数字。只需将其格式化为日期即可。
答案2
以下用户定义函数首先创建一个从今天起 18 到 24 个月的日历范围。然后它循环遍历该范围,直到找到符合条件的日期:
Public Function ProjDate() As Date
Dim d1 As Date, d2 As Date, y As Long
Dim dd As Date, d As Long, m As Long
d = Day(Date)
m = Month(Date)
y = Year(Date)
d1 = DateSerial(y, m + 18, d + 1)
d2 = DateSerial(y, m + 24, d - 1)
For dd = d1 To d2
d = Day(dd)
m = Month(dd)
If (m = 3 And d = 31) Or (m = 9 And d = 30) Then
ProjDate = dd
Exit Function
End If
Next dd
End Function
用户定义函数 (UDF) 非常容易安装并使用:
- ALT-F11 打开 VBE 窗口
- ALT-I ALT-M 打开新模块
- 粘贴内容并关闭 VBE 窗口
如果您保存工作簿,UDF 将随之保存。如果您使用的是 2003 之后的 Excel 版本,则必须将文件保存为 .xlsm 而不是 .xlsx
到消除UDF:
- 调出如上所示的 VBE 窗口
- 清除代码
- 关闭 VBE 窗口
到使用Excel 中的 UDF:
=我的函数(A1)
要了解有关宏的更多信息,请参阅:
http://www.mvps.org/dmcritchie/excel/getstarted.htm
和
http://msdn.microsoft.com/en-us/library/ee814735(v=office.14).aspx
有关 UDF 的详细信息,请参阅:
http://www.cpearson.com/excel/WritingFunctionsInVBA.aspx
必须启用宏才能使其工作!
答案3
这是一个公式。正如所写,为了进行测试,它引用了。但是,如果您发现它返回预期结果,则A1
可以将其替换A1
为:TODAY()
=MAX((MONTH(EDATE(A1-DAY(A1)+1,{18;19;20;21;22;23;24}))={4,10})*EDATE(A1-DAY(A1)+1,{18;19;20;21;22;23;24}))-1
以上是大批公式。
由于这是一个数组公式,因此您需要按住ctrl+shift并点击 来“确认” enter。如果您正确执行此操作,Excel 将{...}
在公式栏中看到括号
如果您想避免CSE
进入程序,您可以尝试稍长一点的:
=AGGREGATE( 14,4,(MONTH(EDATE(A1-DAY(A1)+1,{18;19;20;21;22;23;24}))={4,10})*EDATE(A1-DAY(A1)+1,{18;19;20;21;22;23;24}),1)-1