【问题标题】:Find number of concurrent, overlapping, date ranges查找并发、重叠、日期范围的数量
【发布时间】:2013-10-25 18:25:58
【问题描述】:

我有一个谜题,我多年来一直在尝试解决,但它完全超出了我的能力范围。

我有一个包含 3 列的电子表格。 A 列是教师 ID 号,B 列是他们的课程开始日期,C 列是他们的课程结束日期。每个讲师 ID 有多个课程。

我基本上是想回答这个问题,这位讲师在任何给定时间教授的最大课程数量是多少。 本质上,我需要为每个 ID 号找到最大、并发、重叠日期范围的数量。

问题是,虽然我知道如何找到重叠的日期范围,但我不知道如何计算并发课程的数量。

例如。 教师 115 列出了以下日期范围:

9/10/13 / 11/04/13 9/17/13 / 11/11/13 11/05/13 / 12/30/13 11/12/13 / 1/20/14

虽然 2013 年 5 月 11 日的课程与 2013 年 9 月 17 日的课程和 2013 年 11 月 12 日的课程有重叠,但它们之间并没有重叠……所以这位讲师最多只教 2随时上课。

有没有办法编写一个函数来为每个 ID 返回最大数量的并发重叠日期范围?

编辑不是来自 OP 以从评论中传输详细信息

我可以用几何方法解决这个问题,但我不知道如何在 VBA 函数中解决这个问题(我对编程还是很陌生)。如果我要在代码之外解决这个问题,我会为每个 ID 创建一个表,每天创建一个列。然后,我会为每个日期范围创建一行,在与范围重叠的每一列中标记一个 1。然后我会总结每天的总重叠。然后我会使用一个简单的 MAX 函数来返回最大数量的连续重叠。有没有办法在函数内部执行此操作而无需 Excel 物理绘制这些表?

【问题讨论】:

  • 我可以用几何方法解决这个问题,但我不知道如何在 VBA 函数中做到这一点(我对编程还是很陌生)。如果我要在代码之外解决这个问题,我会为每个 Id 创建一个表,为每一天创建一个列。然后,我会为每个日期范围创建一行,在与范围重叠的每一列中标记一个 1。然后我会总结每天的总重叠。然后我会使用一个简单的 max 函数来返回最大数量的连续重叠。有没有办法在函数内部执行此操作而无需 excel 物理绘制这些表?

标签: excel date-range vba


【解决方案1】:

使用 VBA,假设 A 列包含您的开始日期,B 列包含您的结束日期,并假设您的数据从第 1 行开始,并且您的数据中没有空白行,下面的子将执行您在评论:

Sub getMaxConcurrent()

    'get minimum date (startDate)
    Dim startDateRange
    Set startDateRange = Range("A1", Range("A1").End(xlDown))

    Dim startDate As Date
    startDate = WorksheetFunction.Min(startDateRange)

    'get maximum date (endDate)
    Dim endDateRange
    Set endDateRange = Range("B1", Range("B1").End(xlDown))

    Dim endDate As Date
    endDate = WorksheetFunction.Max(endDateRange)

    'get date range (dateInterval)
    Dim dateInterval As Integer
    dateInterval = DateDiff("d", startDate, endDate)

    'Create daily table header
    Rows("1:1").Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
    Dim x As Integer
    For x = 0 To dateInterval

        Dim dateVal As Date
        dateVal = DateAdd("d", startDate, x)
        Cells(1, 3 + x).Value = dateVal

    Next

    'Fill in daily table
    Dim y As Integer
    y = 2
    Dim startDateValue As Date
    startDateValue = Cells(y, 1).Value

    Do Until IsEmpty(Cells(y, 1).Value)

        For x = 3 To dateInterval + 3

            If (Cells(y, 1).Value <= Cells(1, x).Value) Then
                If (Cells(y, 2).Value >= Cells(1, x).Value) Then
                    Cells(y, x).Value = 1
                Else
                    Cells(y, x).Value = 0
                End If
            Else
                Cells(y, x).Value = 0
            End If

        Next

        y = y + 1
    Loop

    'sum up each day
    For x = 3 To dateInterval + 3
        Cells(y, x).Value = WorksheetFunction.Sum(Range(Cells(2, x).Address & ":" & Cells(y - 1, x).Address))
    Next

    MsgBox ("Max concurrent courses: " & WorksheetFunction.Max(Range(Cells(y, 3).Address & ":" & Cells(y, x).Address)))

End Sub

【讨论】:

    【解决方案2】:

    如果您的数据一直到第 1000 行,则此“数组公式”将给出 E2 中讲师 ID 的最大并发课程数

    =MAX(COUNTIFS(A:A,E2,B:B,"&lt;="&amp;B$2:C$1000,C:C,"&gt;="&amp;B$2:C$1000))

    CTRL+SHIFT+ENTER

    确认

    【讨论】:

    • 我对你的专栏感到困惑。您期望 A、B、C 列中的数据是什么?
    • @barryhoudini 什么是 C?
    【解决方案3】:

    假设只有一位讲师,并且您在 A1:B4 中有开始和结束日期。

    将 A1:A4 复制到 A7:A10,将 B1:b4 复制到 A11:a14(在它的正下方)。选择 A7:A14,点击排序(在数据选项卡上)并“删除重复项”。您有一个按升序排列的唯一日期列表。假设没有重复项(如您的示例),您的日期相同 A7:a14。选择它复制,然后将带有转置的空间粘贴到 C5。

    此时您在 A1:B4 中有开始和结束日期,在 C5:J5 中有唯一日期列表。将公式 =IF(AND($A1

    将公式 =SUM(C1:C4) 放入 C6 并复制到 C6:J6。

    C6:j6 中的最大数量是该讲师的最大并发课程数

    【讨论】: