从列表中为选定的月份派生部门分配

Derive Department assignment from list for chosen month-year

我需要在 Excel 中创建某种基本报告。

主要问题是我从中收集数据的数据库将部门分配存储在三列中,但只存储每个新分配的 Start_Date。

所以文件看起来像:

    Pers_ID Department_ID Start_Date
    1001    01            2012-01-01
    1001    02            2013-05-01
    1001    05            2015-08-01

我需要某种公式来检查单元格(例如 A1 为“2013-08-01”)并在给定时间返回 Pers_ID 的 Department_ID。

我尝试使用数组公式计算所有日期和 "A1" 之间的最小差异,但这也可能导致将来分配 department_ID。

非常感谢您的帮助,因为我苦苦挣扎了几个小时却没有任何可行的解决方案。提前致谢!

根据您的列表,我添加了额外的记录来测试公式,如下所示:

Pers_ID Department_ID Start_Date
1001    01            2012-01-01
1001    02            2013-05-01
1001    05            2015-08-01
1002    02            2012-05-01
1002    04            2013-01-01
1003    01            2016-01-01

Selection criteria
Person: 1002
Date:   2016-03-06

Intermediate Results
Begin:  <First formula below>
End:    <Second formula below>

Results
Dept.   <The last formula goes here>

做出以下假设:

  • 您的数据库按 Pers_ID
  • 排序
  • Table header 位于单元格位置 A1(因此您的数据从第 2 行开始)
  • 您在 B10B11
  • 两个字段中编写 selection 标准

为了区分不同的 Pers_ID,我们首先必须知道特定 Pers_ID 的许多记录在您的数据源中以及在哪个位置。由于数据按 Pers_ID 排序,我们只需搜索出现的第一行:

MATCH(B10;A2:A7;0) // will return 4 as it's the 4th line in the range A2:A7

并计算指定的 Pers_ID 出现的频率:

COUNTIF(A2:A7;B10) // will return 2

为了简化生成的公式,我们可以 "cache" 单元格 B14B15.

中的结果

之后我们可以使用 OFFSET() 函数创建一个范围。我们从数据集的开头开始,根据我们的计算将范围 向下 移动。注意 MATCH() - 1,因为如果所需的 Pers_ID 位于第一行(因此指定偏移量为 0),我们不必移动范围。根据 COUNTIF 的结果,我们指定范围的高度:

OFFSET(B2;MATCH(B9;A2:A7;0)-1;0;COUNTIF(A2:A7;B9)) // without "cache"
OFFSET(B2;B14-1;0;B15) // with "cache"

OFFSET(B2;4-1;0;2) // partially evaluated

他们都 return B5:B6 作为 Pers_ID = 1002

的部门范围

到 select 范围内的适当行用 INDEX():

换行公式
INDEX(OFFSET(B2;B14-1;0;B15);<Row>;<Column>)

<Column>到select很简单。由于我们没有在 OFFSET() 公式中指定宽度,范围只有 1 列宽,所以 select 的列将为 1:

INDEX(OFFSET(B2;B14-1;0;B15);<Row>;1)

<Row> 有点棘手。我们需要在列 C 中指定日期范围,其高度与我们在 Pers_ID 的范围中所做的相同。 我们主要使用与现在相同的公式,但我们不想在 B11 中搜索指定的日期,而是最近的日期(即确切日期或更早的日期)。为此,我们使用 SMALL() ...

SMALL(OFFSET(C2;B14-1;0;B15);COUNTIF(OFFSET(C2;B14-1;0;B15);"<="&B11)) // returns 2013-01-01 (in fact it returns 41275 which is the 1st March 2013)

... 并用 MATCH():

确定范围内的行号
MATCH(SMALL(OFFSET(C2;B14-1;0;B15);COUNTIF(OFFSET(C2;B14-1;0;B15);"<="&B11));OFFSET(C2;B14-1;0;B15);0) // returns 2

那么整个公式就是:

// Without "cache"
=INDEX(OFFSET(B2;MATCH(B10;A2:A7;0)-1;0;COUNTIF(A2:A7;B10));MATCH(SMALL(OFFSET(C2;MATCH(B10;A2:A7;0)-1;0;COUNTIF(A2:A7;B10));COUNTIF(OFFSET(C2;MATCH(B10;A2:A7;0)-1;0;COUNTIF(A2:A7;B10));"<="&B11));OFFSET(C2;MATCH(B10;A2:A7;0)-1;0;COUNTIF(A2:A7;B10));0);1)

// With "cache"
=INDEX(OFFSET(B2;B14-1;0;B15);MATCH(SMALL(OFFSET(C2;B14-1;0;B15);COUNTIF(OFFSET(C2;B14-1;0;B15);"<="&B11));OFFSET(C2;B14-1;0;B15);0);1)

也许有一种 easier/cleaner 方法可以实现这一点(例如,我不太熟悉的数组公式或 VBA)。