- 已 关闭 * * 。 此 问题 需要 更多 focused 。 当前 不 接受 答案 。
- 想要 改进 此 问题 吗 ? * * 更新 问题 , 使 其 仅 关注 editing this post 的 一 个 问题 。
13 天 前 关闭 。
这 篇 文章 是 9 天 前 编辑 并 提交 审查 的 。
Improve this question 格式
我 有 以下 输入 数据 , 其中 包含 * * Employee * * 和 项目 信息 ( 日期 格式 为 MM/DD/YYYY
) :
| 员工|角色|专业|开始 日期|结束 日期|
| - -| - -| - -| - -| - -|
| 鲍勃|高级 程序 员|程序 设计|2020 年 12 月 1 日|2021 年 5 月 3 日|
| 戴夫|中级 程控 仪|程序 设计|2020 年 1 月 2 日|2020 年 5 月 30 日|
| 彼得|高级 程序 员|程序 设计|2020 年 1 月 2 日|2020 年 1 月 30 日|
| 杰克|初级 程序 员|程序 设计|2020 年 1 月 2 日|2020 年 6 月 30 日|
| 理查德 德|资深 艺术 家|艺术|2020 年 1 月 3 日|2020 年 4 月 30 日|
| 罗德尼|QA 负责 人|质量 保证 部|2020 年 1 月 3 日|2020 年 6 月 30 日|
| 项目 1 - 聘用 1|高级 制片 人|生产 部|2020 年 1 月 2 日|2020 年 5 月 30 日|
| 罗杰|质量 保证 部|质量 保证 部|2020 年 1 月 1 日|2020 年 4 月 30 日|
| 韦斯利|中级 程控 仪|程序 设计|2020 年 1 月 2 日|2020 年 5 月 31 日|
| 拉 结|资深 艺术 家|艺术|2020 年 1 月 1 日|2020 年 6 月 30 日|
| 项目 1 - 聘用 2|首席 程序 员|程序 设计|2020 年 1 月 1 日|2020 年 7 月 31 日|
然后 , 我 有 一 个 花名 册 表 , 其中 包含 每个 雇员 的 工资 信息 :
| 员工|薪资 起始 日期|薪资 终止 日期|薪资|月薪|日薪|
| - -| - -| - -| - -| - -| - -|
| 鲍勃|2020 年 1 月 1 日|二零二一 年 三 月 三十一 日|五万 两 千 美元|四千 三百 三十三 元|217 美元|
| 鲍勃|2021 年 4 月 1 日|2022 年 3 月 31 日|五万 五千 美元|四千 五百 八十三 元|229 美元|
| 鲍勃|2022 年 4 月 1 日||五万 八千 美元|四千 八百 三十三 元|242 美元|
| 戴夫|2020 年 1 月 1 日|二零二一 年 三 月 三十一 日|三万 八千 美元|三千 一百 六十七 元|一百 五十八 美元|
| 戴夫|2021 年 4 月 1 日||四万 两 千 美元|三千 五百 元|一百 七十五 美元|
| 韦斯利|2020 年 1 月 1 日||四万 五千 美元|三千 七百 五十 元|一百 八十八 元|
| 杰克|2020 年 1 月 1 日||两 万 五|2,083 美元|一百 零四 美元|
| 理查德 德|2020 年 1 月 1 日||四万 五千 美元|三千 七百 五十 元|一百 八十八 元|
| 罗德尼|2020 年 1 月 1 日||五万 两 千 美元|四千 三百 三十三 元|217 美元|
| 项目 1 - 聘用 1| 2020 年 1 月 1 日||四万 一千 五百 元|三千 四百 五十八 元|173 美元|
| 罗杰|2020 年 1 月 1 日||两 万 美元|一千 六百 六十七 元|83 美元|
| 史 提|2020 年 1 月 1 日||两 万 七千 美元|2,250 美元|一百 一十三 美元|
| 拉 结|2020 年 1 月 1 日||4 万 美元|三千 三百 三十三 元|167 美元|
| 彼得|2020 年 1 月 1 日||三万 四千 美元|两 千 八百 三十三 元|142 美元|
| 萨拉|2020 年 1 月 1 日||两 万 两 千 美元|一千 八百 三十三 元|92 美元|
| 克洛伊|2020 年 1 月 1 日||三万 三千 美元|两 千 七百 五十 美元|一百 三十八 元|
| 马修|2020 年 1 月 1 日|二零二一 年 三 月 三十一 日|两 万 三千 美元|一千 九百 一十七 元|96 美元|
| 马修|2021 年 4 月 1 日||两 万 八千 美元|2,333 美元|一百 一十七 美元|
| 项目 1 - 聘用 2| 2020 年 1 月 1 日||三万 六千 美元|三千 美元|150 美元|
以下 条件 适用 于 上 表 :
1.一 个 员工 可以 有 多 个 薪金 , 但 相应 的 时间 间隔 不能 重叠 ( * * Start * / * End Dates * * 列 ) - 用于 年度 加薪 。
1.如果 " * * 结束 日期 * * " 值 为 空 , 则 员工 当前 使用 的 是 设置 的 薪金 。
我 发布 了 一 个 相关 的 问题 :* Sequence a 'sumif' with exclusions in Excel * , 计算 月薪 成本 , 仅 考虑 整个 月 的 分配 , 即 只有 在 整个 月 都 为 员工 分配 资源 时 才 分配 资源 。
现在 我 想 考虑 部分 分配 , 即 根据 总 工作 日 数 计算 成本( 星期 一到 星期 五 ) 考虑 到 上 表 中 * * Daily Salary * * 列 的 值 , 为 员工 分配 了 由 * * Start Date * * 和 * * End Date * * 定义 的 部分 月份 。 我 试图 根据 DavidLeal 提供 的 答案 修改 公式 ,但 我 找 不到 一 个 方法 来 适应 它 。
下面 是 用于 解决 上 一 个 非 部分 分配 问题 的 公式 。
=LET(namePrj, TB_Prj[Employee], startPrj, TB_Prj[Start Date], endPrj,
TB_Prj[End Date],name, TB_Roster[Employee],start, TB_Roster[Salary Start Date],
end, TB_Roster[Salary End Date],salary, TB_Roster[Salary Monthly],
SOMs, H1:S1, EOMs, EOMONTH(SOM,0),
BYCOL(SOMs, LAMBDA(SOM, LET(EOM, EOMONTH(SOM,0),
namesActive, FILTER(namePrj, (startPrj <= SOM) * (endPrj >= EOM)),
cost, FILTER(salary, (start <= SOM) * (IF(end > 0, end, EOM) >= EOM) *
(ISNUMBER(XMATCH(name,namesActive))),0), sum(cost)
)))
)
中 的 每 一 个
我 正在 寻找 一 个 Excel 公式 , 该 公式 将 返回 序列 的 第 一 个 月 的 每月 薪金 成本 :
=EDATE(DATE(2020,1,1), SEQUENCE(1, 12, 0))
格式
然后 将 其 扩展 到 周期 的 末尾 或者 仅 返回 整个 周期 1/1/2020-12/31/2020
的 1x12
数组 。
1条答案
按热度按时间uxh89sit1#
在单元格
I2
中,输入以下公式(有关简化版本,请参阅UPDATE部分):这是整个周期内单个数组
1x12
的输出。注:在单元格
I15
中,我使用了问题答案中建议的想法:sequence a sumif with exclusions in Excel,用于检查花名册数据集的间隔不重叠。更新
公式可以简化如下,不需要定义用户
LAMBDA
函数:SPLIT
。我们可以让MAP
函数只返回索引位置的重叠部分,然后使用此信息查找其余信息。我们还使用DROP/REDUCE/VSTACK/HSTACK
组合返回多个值(我们受到MAP
的限制,只能返回单个列)说明
总体思路
对于计算,我们使用两个主要思想:
1.检查两个间隔(
A
,B
)是否重叠的条件:(StartA <= EndB) AND (EndA >= StartB) -> TRUE
1.如果两个区间
A
、B
重叠,则两个区间的交集为:[MAX(StartA, StartB), MIN(EndA, EndB)]
我们将遍历每个月。首先查看项目数据集,以查找在给定月份重叠的间隔,并查找与当前月份重叠的每个间隔的交集。
一旦我们有了资源清单及其Map的交集。我们需要寻找符合间隔的Map工资。我们再次重复在项目数据集中找到的交集,但现在在工资数据集中寻找第二个交集。
公式
我们使用
LET
函数来定义输入和中间结果。我们开始定义两个数据集setPrj
,用于表示项目信息的数据,以及setRoster
,用于输入集所需的名册信息和相关名称。我们将使用
MAP
函数(用于查找每个重叠)这对于进行转换非常方便,它可以接受多个相同大小的输入数组,但然后返回单个数组。为了避免这种情况,MAP
的输出将是nx1
数组,并且在每行上,我们在LET
中定义了一个用户自定义的LAMBDA
函数,用于将结果从CSV格式转换回2D数组。此用户函数名为
SPLIT
(不要将其与TEXTSPLIT
标准Excel函数混淆)。在LET
函数内定义此函数,作用域将限于该函数,无需为其创建命名区域。因为输入参数
x
是一个由逗号分隔的值组成的nx1
数组,所以一旦我们将其转换为二维数组,就需要将一些列转换回它们的原始数据类型。我们使用第二个输入参数case
来考虑主公式中使用的所有转换方案。case=1
,将列2
与3
转换为数字case=2
,将所有列转换为数字注意:
case=0
不用于主公式,仅用于测试目的。MAP
的输出将在两个调用中是一个三列数组。最后,输出将是一个已删除空行的
nxm
数组(",,"
。有一个为它定义的名称:empty
)。如果所有行都为空,FILTER
将返回错误(Excel中不存在空集合),以防止我们使用此函数的第三个输入参数返回NA()
(我们在主公式的其他部分使用相同的想法)现在我们使用
BYCOL
来迭代月份(我们使用此函数是因为月份是列格式)。对于每个月份(表示为该月的第一天)我们使用SOM
(月初)和EOM
(月末)名称来查找重叠和交叉。第一个MAP
调用执行此操作,结果命名为intersecPrj
:注:这里我们可以使用
FILTER
代替MAP
,但使用后者我们可以同时找到重叠和交叉。结果以CSV格式按行存储,包含以下信息:name, startDate, endDate
,其中日期表示交叉点日期。现在,我们通过
SPLIT
函数将信息转换回2D数组:SPLIT(intersecPrj,1)
,因为我们希望将name
保留为文本,所以我们使用case=1
并将其命名为:setPrjAdj
它是一个数组nx3
,其中n
表示找到的交集的数目。现在,我们需要在
setPrjAdj
中查找姓名对应的薪金。这里,我们需要考虑未找到交集的方案,即对于给定月份,没有与资源关联的项目。计算intersecRoster
的条件防止出现以下情况:我们可以检查
NA()
,因为SPLIT
函数在没有交集的情况下返回这个值,所以如果条件是TRUE
,我们返回NA()
。如果ISNA
的输入是一个数组,它返回一个数组。因此我们使用ROWS
将测试缩减到单个单元格。如果数组的任何元素具有#N/A
值,则ROWS
输出将是#N/A
。如果找到项目交集,我们需要找到工资以及
setPrjAdj
中的日期信息与花名册数据集中的日期之间的相应新交集。这通过以下
MAP
调用完成,并将结果命名为intersecRoster
对于每个
name
、start
和end
(来自setPrjAdj
),HSTACK(starts, endsAdj, salaries)
由name
过滤并查找重叠。它使用
endsAdj
、而不是ends
原始输入数据,因为我们需要处理空白结束日期。结果保存在found
名称中。现在我们需要检查FILTER
的空集。筛选器的not found条件(空集)由以下输出NA()
表示。可能是找不到名称(拼写错误或名称丢失)。如果它返回多行(不应发生此情况,因为花名册集的间隔不应重叠,即员工不能同时有两个薪金)。我们分配了
empty
行。由于无法确定薪金,因此此资源不会计入薪金每月成本。否则,我们使用相应的信息通过TEXTJOIN
构建字符串:起始日期、终止日期和相应的薪金。其中起始日期和终止日期表示start
和end
日期(来自setPrjAdj
)与花名册数据集的起始日期和终止日期(来自FILTER
输出)之间的交叉点。现在,
intersecRoster
具有CSV格式的以下信息:start, end, salary
。我们现在通过SPLIT
将字符串信息转换为二维数组,并将结果命名为setRosterAdj
。我们使用case=2
,因为所有信息都是数字。这里我们需要防止名字在花名册表中找不到,以避免出现任何意外的结果。如果没有找到资源,那么我们通过下面的条件返回
0
:现在我们有了所有要查找的信息。为了计算工作日期,我们使用
NETWORKDAYS(startEffDates, endEffDates)
,其中日期是setRosterAdj
中的相应列,它被命名为days
。最后道:
提供我们要寻找的结果。我们使用
Eff
(有效)作为Map数据行的名称,来命名setRosterAdj
中的所有数据行。非部分分配月薪
前一种方法是根据工作日和日薪来计算成本。如果您要考虑每月成本,而不是资源整个月都分派给您的月份,以及部分分派给您的月份的日薪,则调整后的公式如下:
提示
由于这是一个大型公式,而Excel没有提供正确调试某些数组函数的方法,因此,有一种调试某些部分结果的方法是很有帮助的。由于
BYCOL
每列返回一个单元格,因此,在LET
中定义另一个用户的LAMBDA
函数以实现此目的是很方便的。例如,下面的函数,并将其命名为DEBUG
。则它可用于返回
DEBUG
的输出,而不是用于测试目的的最终结果。