【发布时间】:2016-05-10 03:06:15
【问题描述】:
我正在尝试计算多个事件之间重叠的总持续时间。每个事件可以以任何安排与多个其他事件重叠。我需要计算任何单个事件与任何其他事件重叠的总时间。我的数据是这样的。
event timeStart timeEnd
1 15:00 22:00
2 12:00 18:00
3 20:00 23:00
4 16:00 17:00
5 10:00 14:00
Output:
event timeOverlap
1 05:00 '03:00 (1,2) + 02:00 (1,3)
2 04:00 '03:00 (1,2) + 01:00 (2,4)
3 02:00 '02:00 (1,3)
4 01:00 '01:00 (2,4)
5 02:00 '02:00 (2,5)
我正在尝试在 Excel VBA 中执行此操作。我现在的主要问题是找到一种方法来总结不连续的重叠,例如事件 1 或事件 2。任何帮助将不胜感激。
编辑:澄清一下,我想避免重复计算,这就是为什么我没有在事件 1 的计算中包括 (1,4) 之间的重叠。输出应该显示重叠的总和导致最大的重叠持续时间。
这是我正在使用的部分代码。现在它计算多个事件之间最长的连续重叠。它不会总结不连续的重叠。
'DECLARE VARIABLES
Dim timeStart() As Date 'start times of cases
Dim timeEnd() As Date 'end times of cases
Dim ovlpStart() As Double 'start times of overlap regions for cases
Dim ovlpEnd() As Double 'end times of overlap regions for cases
Dim totalRows As Long 'total number of cases`
'RETRIEVE NUMBER OF ROWS
totalRows = WorksheetFunction.CountA(Columns(1))
'STORE COLUMN DATA FROM EXCEL SHEET INTO ARRAYS
ReDim timeStart(1 To totalRows)
ReDim timeEnd(1 To totalRows)
ReDim ovlpStart(1 To totalRows)
ReDim ovlpEnd(1 To totalRows)
'FILL IN ARRAYS WITH DATA FROM SPREADSHEET
For i = 2 To totalRows
timeStart(i) = Cells(i, 3).Value
timeEnd(i) = Cells(i, 4).Value
'Initialize ovlpStart and ovlpEnd
ovlpStart(i) = 1
ovlpEnd(i) = 0
Next
'FILL IN CONCURRENCE COLUMN WITH ALL ZEROS TO START
For i = 2 To totalRows
Cells(i, 6).Value = "0"
Next
'SEARCH FOR CONCURRENT TIME INTERVALS
For i = 2 To totalRows
For j = (i + 1) To totalRows
'Check if the times overlap b/w cases i and j
Dim diff1 As Double
Dim diff2 As Double
diff1 = timeEnd(j) - timeStart(i)
diff2 = timeEnd(i) - timeStart(j)
If diff1 > 0 And diff2 > 0 Then
'Mark cases i and j as concurrent in spreadsheet
Cells(i, 6).Value = "1"
Cells(j, 6).Value = "1"
'Determine overlap start and end b/w cases i and j, store as x and y
Dim x As Double
Dim y As Double
If timeStart(i) > timeStart(j) Then
x = timeStart(i)
Else
x = timeStart(j)
End If
If timeEnd(i) < timeEnd(j) Then
y = timeEnd(i)
Else
y = timeEnd(j)
End If
'Update ovlpStart and ovlpEnd values for cases i and j if overlap region has increased for either
If x < ovlpStart(i) Then
ovlpStart(i) = x
End If
If x < ovlpStart(j) Then
ovlpStart(j) = x
End If
If y > ovlpEnd(i) Then
ovlpEnd(i) = y
End If
If y > ovlpEnd(j) Then
ovlpEnd(j) = y
End If
End If
Next
Next
'DETERMINE DURATION OF OVERLAP, PRINT ONTO SPREADSHEET
Dim ovlpDuration As Double
For i = 2 To totalRows
ovlpDuration = ovlpEnd(i) - ovlpStart(i)
If Not ovlpDuration Then
Cells(i, 7).Value = ovlpDuration
Else
Cells(i, 7).Value = 0
End If
Next`
【问题讨论】:
-
按你的逻辑,为什么(1,4)之间没有重叠?
-
您应该发布一个代码示例来汇总重叠部分。
-
您是否同意“重复计算”您的重叠?例如在您的逻辑中,您显示事件 2 为重叠 (2,4) 计数 1 小时,并且您显示事件 4 为重叠 (2,4) 计数 1 小时。如果这不行,您将如何决定要计算哪个事件?
-
您打算修复此问题中的数据吗?如果没有,您是否打算解决这些 cmets 中提到的问题并回答有关您的逻辑有效性的回应?
-
我还是不明白为什么事件 2 是 4 小时。 (2, 1) 在 3 小时时是正确的,但 (2, 4) 已经被 (2, 1) 覆盖。缺少的是 (2, 5) ,它比其他任何东西都晚了 2 小时。在我看来正确答案是 5,而不是 4。