2017-05-09 144 views
2

下面是一个可以帮助我预防偏头痛的方法吗? :-)计算多个日期范围中的独特日期

我有一张表中的一列包含开始日期和另一个结束日期。我有第三列来计算开始日期和结束日期之间有多少天(添加1以获得正确的计数,因为开始日期等于结束日期需要计为一天,而不是零)。

然而,不同的行的时间段可以重叠,所以可具有介于(警告:英国日期格式DD/MM/YY):

Start  End   Days 
22/01/17 26/01/17 5 
24/01/17 24/01/17 1 

因为第24是在第一行中已经计数,我当我得到所有日子的总数时,不想再次数它。我怎样才能做到这一点?

在此先感谢!

Lucien。

回答

1

长话短说 - 我想不出一个好的和明确的方式来做到这一点,只需用Excel。 然而,VBA有一个好办法:

Option Explicit 

Public Sub TestMe() 

    Dim lngCounter   As Long 
    Dim dtStartDate   As Date 
    Dim dtEndDate   As Date 
    Dim collDates   As New Collection 

    dtStartDate = CDate("22.01.2015") 
    dtEndDate = CDate("25.01.2015") 

    For lngCounter = dtStartDate To dtEndDate 
     If Not Contains(collDates, lngCounter) Then 
      collDates.Add lngCounter 
     End If 
    Next lngCounter 

    dtStartDate = CDate("23.01.2015") 
    dtEndDate = CDate("28.01.2015") 

    For lngCounter = dtStartDate To dtEndDate 
     If Not Contains(collDates, lngCounter) Then 
      collDates.Add lngCounter 
     End If 
    Next lngCounter 

    For lngCounter = 1 To collDates.Count 
     Debug.Print CDate(collDates(lngCounter)) 
    Next lngCounter 

End Sub 

Public Function Contains(ByRef col As Collection, ByRef key As Variant) As Boolean 

    Dim lngCounter As Long 

    Contains = True 

    For lngCounter = 1 To col.Count 
     If col(lngCounter) = key Then Exit Function 
    Next lngCounter 

    Contains = False 

End Function 

你给两次dtStartDatedtEndDate和你之间的数字保存日期的集合collDates中,如果它们已经不存在。

+0

感谢。这是类似的解决方案的人在其他地方建议,我开始使用: '显式的选项 功能UniqueDayCount(RSTART量程,雷德作为范围)只要 昏暗的山坳作为收藏 昏暗的vStart为Variant,鬻为Variant 暗淡我作为龙,J只要 的vStart = RSTART 鬻=雷德 上的错误继续下一步 集山坳=新集合 对于i = 1到UBound函数(的vStart) 对于J =的vStart(I,1)为贩卖(I, 1) col.Add Item:= J,Key:= CStr(J) Next J Next I On Error转至0 UniqueDayCount = col.Count End Function ' –

+0

您可以将代码放入pastebin.com吗?并给一个链接? :) – Vityata

0

如果在列A中有开始日期,列B中的结束日期和列C中的结果日期差异,则可以在列D和E中使用以下两个数组公式计算双精度值(此解决方案不需要升序)。

请注意,这这些都是数组公式,您有按Ctrl +确认他们 + 输入,而不是仅按输入 - 键。

列d:

=COUNT(IF(ISNUMBER(SEARCH(A2-1+(ROW(INDIRECT("A1:A"&C2))),E1)),"",A2-1+(ROW(INDIRECT("A1:A"&C2))))) 

E列:

=TEXTJOIN(",",TRUE,IF(ISNUMBER(SEARCH(A2-1+(ROW(INDIRECT("A1:A"&C2))),E1)),"",A2-1+(ROW(INDIRECT("A1:A"&C2)))),E1) 

您需要的Excel 2016,所以你可以达到预期的效果,因为textjoin() - 函数是一个新的。

count distinct textjoin

它是如何工作的: 数组公式分裂所有起始日期和结束日期之间的日期为行和搜索它们作为连接字符串的一个整数,如果有比赛,该日期将被“空白”,其他不同的结果将与先前保存在不断增长的字符串中的不同结果连接起来。

+0

非常聪明。我一直在思考相同的问题,但无法完成它的工作。这可以'隐形'完成吗?考虑到它的累积性,性能不会比UDF /宏慢吗? –

1

如果要求每行和每列都总天数,那么你可以总是有一个单独的列中添加独特的天(假定起始日期是按日期顺序排列) enter image description here

+0

不幸的是,订单不能保证,并且日期间有重叠和间隔。 –

0

另一种方法来使所使用的日期的列表是通过产生过日期的整个范围内(到最近的结束日期从最早的开始日期)的阵列,以使用一个“筛子”的方法则在所使用的那些填充

=SUMPRODUCT(SIGN(COUNTIFS(A2:A10,"<="&ROW(INDIRECT(MIN(A2:A10)&":"&MAX(B2:B10))),B2:B10,">="&ROW(INDIRECT(MIN(A2:A10)&":"&MAX(B2:B10)))))) 

enter image description here

(D列中的数字刚刚作为支票手动输入,并未在计算中使用)。

这显示了数组的样子

enter image description here

+0

Tom在哪里存储数组? –

+0

该阵列只是暂时的,它不存储在任何地方。如果您取公式= SIGN(COUNTIFS(A2:A10,“<=”&ROW(INDIRECT(MIN(A2:A10)&“:”&MAX(B2:B10))), B2:B10“ > =“&ROW(INDIRECT(MIN(A2:A10)&”:“&MAX(B2:B10)))))并将其作为数组公式输入到一个单元格区域中,您会看到该数组映射为一系列0(不使用日期)和1(使用日期)。 –