2017-06-19 92 views
2

所以我有一个日期的整个列表。我需要找出哪些日期落在与我每年所规定的“开始日期”和“结束日期”相同的范围内(日期和月份)。确定日期落在同一个月,跨越几年的日期

例如,开始日期:2004年12月2日,结束日期:31/1/2005,日期为2000年12月12日至31/1/2001,2/12/2001和31/1/2002,2/12/2001和31/1/2002等应标记为“有效”。

当前我使用上限/下限,然后测试日期是否在范围内。

Excel公式:

鞋面:= DATE(YEAR(日期),MONTH(测试),日(测试)+回头期)

下:= DATE(YEAR(日期),MONTH (试验),日(试验)-Look返回周期)

有效:= IF(AND(日期< =上,日期> =更低),1,0)

Test     1/1/2005 
Look Back Period (Days) 30 
Start Date    2/12/2004 (=Test + Look Back Period) 
End Date    31/1/2005 (=Test - Look Back Period) 


    Date  Upper  Lower  Valid 
    04/01/2000 31/1/2000 2/12/1999 1 
    05/01/2000 31/1/2000 2/12/1999 1 
    06/01/2000 31/1/2000 2/12/1999 1 
    07/01/2000 31/1/2000 2/12/1999 1 
    10/01/2000 31/1/2000 2/12/1999 1 
    11/01/2000 31/1/2000 2/12/1999 1 
    12/01/2000 31/1/2000 2/12/1999 1 
    13/01/2000 31/1/2000 2/12/1999 1 
    14/01/2000 31/1/2000 2/12/1999 1 
    17/01/2000 31/1/2000 2/12/1999 1 
    18/01/2000 31/1/2000 2/12/1999 1 
    19/01/2000 31/1/2000 2/12/1999 1 
    20/01/2000 31/1/2000 2/12/1999 1 
    21/01/2000 31/1/2000 2/12/1999 1 
    24/01/2000 31/1/2000 2/12/1999 1 
    25/01/2000 31/1/2000 2/12/1999 1 
    26/01/2000 31/1/2000 2/12/1999 1 
    27/01/2000 31/1/2000 2/12/1999 1 
    28/01/2000 31/1/2000 2/12/1999 1 
    31/01/2000 31/1/2000 2/12/1999 1 
    01/02/2000 31/1/2000 2/12/1999 0 
    02/02/2000 31/1/2000 2/12/1999 0 
    03/02/2000 31/1/2000 2/12/1999 0 
    04/02/2000 31/1/2000 2/12/1999 0 
    07/02/2000 31/1/2000 2/12/1999 0 
    . 
    . 
    . 
    30/11/2000 31/1/2000 2/12/1999 0 
    01/12/2000 31/1/2000 2/12/1999 0 
    04/12/2000 31/1/2000 2/12/1999 0 <-- :(
    05/12/2000 31/1/2000 2/12/1999 0 <-- :(
    06/12/2000 31/1/2000 2/12/1999 0 <-- :(
    07/12/2000 31/1/2000 2/12/1999 0 <-- :(
    08/12/2000 31/1/2000 2/12/1999 0 <-- :(
    11/12/2000 31/1/2000 2/12/1999 0 <-- :(
    12/12/2000 31/1/2000 2/12/1999 0 <-- :(
    13/12/2000 31/1/2000 2/12/1999 0 <-- :(
    14/12/2000 31/1/2000 2/12/1999 0 <-- :(
    15/12/2000 31/1/2000 2/12/1999 0 <-- :(
    18/12/2000 31/1/2000 2/12/1999 0 <-- :(
    19/12/2000 31/1/2000 2/12/1999 0 <-- :(
    20/12/2000 31/1/2000 2/12/1999 0 <-- :(
    21/12/2000 31/1/2000 2/12/1999 0 <-- :(
    22/12/2000 31/1/2000 2/12/1999 0 <-- :(
    25/12/2000 31/1/2000 2/12/1999 0 <-- :(
    26/12/2000 31/1/2000 2/12/1999 0 <-- :(
    27/12/2000 31/1/2000 2/12/1999 0 <-- :(
    28/12/2000 31/1/2000 2/12/1999 0 <-- :(
    29/12/2000 31/1/2000 2/12/1999 0 <-- :(
    01/01/2001 31/1/2001 2/12/2000 1 
    02/01/2001 31/1/2001 2/12/2000 1 
    03/01/2001 31/1/2001 2/12/2000 1 
    04/01/2001 31/1/2001 2/12/2000 1 
    05/01/2001 31/1/2001 2/12/2000 1 
    08/01/2001 31/1/2001 2/12/2000 1 
    09/01/2001 31/1/2001 2/12/2000 1 
    10/01/2001 31/1/2001 2/12/2000 1 
    11/01/2001 31/1/2001 2/12/2000 1 

公式工作正常只要这些时期不跨越几年。但是,如果上限和下限跨越两年,则有效公式将排除上一年的值。

有没有解决方法?

+1

这看起来像一个很好的例子,一个线段树。 https://en.wikipedia.org/wiki/Segment_tree你熟悉算法和VBA吗? – Vityata

+0

是的。我可以用vba编写解决方案。然而,为了这张表的传统缘故(这很可能不会传递给其他人),我更喜欢Excel的公式解决方案。 – adam

+0

你能给我们一个不起作用的例子吗? –

回答

3

使用公式为此,成立了两个帮手列

lower1: =DATE(YEAR(Date)-1,MONTH(StartDate),DAY(StartDate)) 
upper1: =C8+2*LookBack 
Lower2: =DATE(YEAR(Date),MONTH(StartDate),DAY(StartDate)) 
Upper2: =Lower2+2*LookBack 

valid: =IF(OR(AND(Date>=lower1,Date<=upper1),AND(Date>=Lower2,Date<=Upper2)),1,0) 

所有我们正在做的是建立两套界。相对于Date,一个从上一年开始;另一个从今年开始。然后检查Date以查看它是否属于任一组。

对于外观,不要求界限列可见,或者甚至不要求它们与Datevalid列连续。

enter image description here

+1

我正在研究一个不使用额外帮助列的公式(我常常将其用于挑战:P),但此解决方案的+1非常整洁,我喜欢它的可读性和可理解性:) –

+2

@ASH谢谢。我认为,他既想要Excel解决方案,又要将其传递给其他人,这一事实赞成可读性和紧凑性。 –

+1

使用助手列没有什么可耻的。事实上,在大多数项目中,我更喜欢人们使用帮助列,因为它使得以后更容易进行故障排除,解释,审计和调试。超级配方在所有这些方面都很糟糕。 – SandPiper