摘要:a.获取月底日期:使用 EOMONTH(start_date, months) 函数。A2:A21 作为起始日期(start_date),0 表示从起始日期所在的月份开始偏移 0 个月,也就是直接计算该月的最后一天的日期。
a.获取月底日期: 使用 EOMONTH(start_date, months) 函数。A2:A21 作为起始日期(start_date),0 表示从起始日期所在的月份开始偏移 0 个月,也就是直接计算该月的最后一天的日期。
a.EOMONTH 函数: 核心函数。用途是返回指定日期在偏移指定月份数后的该月最后一天的日期。关键参数 months=0 表示不偏移月份,计算起始日期当月的最后一天。这是最直接获取月末日期的函数。
b.DAY 函数: 用于从日期序列中提取该日期是当月的第几天(1-31)。当输入是月末日期时,它返回的就是该月的总天数。
c.数组输入 (A2:A21): 公式中对 EOMONTH 和 DAY 的输入都是一个单元格区域 A2:A21。在现代Excel(支持动态数组的版本,如MS 365, Excel 2021)中,这允许公式自动将结果“溢出”(Spill)到对应的 B2:B21 区域,一次性计算出所有行对应的结果。
a.拼凑一个“下月第0天”的日期: 使用 DATE(year, month, day) 函数。参数提取方式如下:
nyear = YEAR(A2:A21):获取原始日期对应的年份。
nmonth = MONTH(A2:A21) + 1:获取原始日期对应的月份,并加 1(即计算下个月)。
nday = 0:这是关键技巧!在 DATE 函数中,day 参数设置为 0 会被解释为指定月份(即month参数计算的月份)的前一天的日期。
b.“下月第0天”就是本月的最后一天:DATE(YEAR(A2:A21), MONTH(A2:A21)+1, 0) 实际构造的是下个月份的第0天。Excel将第0天解释为上一个月的最后一天。所以这步操作相当于直接构造了原始日期所在月份的最后一天。
a.DATE 函数: 用于根据给定的年、月、日构造一个日期。
b.YEAR/MONTH 函数: 用于从日期中提取年份和月份。
c.DATE 函数 day 参数为 0 的特殊行为: 这是该公式的核心技巧。DATE(year, month, 0) 返回 month 月份的前一个月的最后一天的日期。
d.日期计算逻辑: 理解 month+1 结合 day=0 实际得到的是 上个月(即目标月)的最后一天。
e.数组输入 (A2:A21): 同公式一,利用动态数组溢出功能一次性计算区域结果。
l总结: 这是一个历史悠久的技巧,在没有 EOMONTH 函数的早期Excel版本中使用。它巧妙地利用了 DATE 函数处理第 0 天的特殊规则来获取月末日期,再结合 DAY 提取天数。效果与公式一相同,但需要理解这个特殊规则,且公式稍长。
1 B2=LET(A,SEQUENCE(3650,,--A2),B,DATE(YEAR(A),MONTH(A),1),VLOOKUP(--A2:A21,GROUPBY(B,B,COUNTA),2,0))
a.定义变量 A (日期序列):A = SEQUENCE(3650,, --A2):
n--A2:将 A2 单元格的日期(或文本)转换为数值(序列值)。确保计算起点。
nSEQUENCE(3650,, start_value):生成一个包含 3650 个连续数字的数组(代表3650天),起始值为 --A2(即第一个数据的日期序列值)。
b.定义变量 B (每月的第一天):B = DATE(YEAR(A), MONTH(A), 1):
n对序列 A 中的每一个日期序列值,计算其所在月份的第一天日期(DATE(年, 月, 1))。
c.聚合计算每月天数:GROUPBY(B, B, COUNTA):
nGROUPBY(row_fields, [values], [function], ...):将生成的日期序列 B(每月第一天)作为行字段和值字段。
nCOUNTA:对同一月份第一天(即同一个 B)出现的次数进行计数。B 序列包含了3650天的每月第一天,这个计数结果就是该月的总天数(因为在该月的每一天,这个“当月第一天”的值都是相同的)。结果是一个两列数组:第一列是月份第一天 (B),第二列是该月的天数 (COUNTA)。
d.查找原始日期对应的月天数:VLOOKUP(--A2:A21, groupby_result, 2, 0):
n--A2:A21:将原始数据区域转换为日期序列值(查找值)。
ngroupby_result:上一步 GROUPBY 生成的表格(两列数组)。
n2:表示在 GROUPBY 结果中取第二列(天数)。
n0:表示精确匹配 (FALSE)。
nVLOOKUP 将查找原始日期(序列值),在 GROUPBY 生成的结果表中找到对应的月份第一天所在的行,并返回该行第二列的值(即该月的天数)。
a.LET 函数: 用于定义局部变量 (A, B) 和计算结果表达式。提高公式可读性(本例中效果有限)和避免重复计算。
b.SEQUENCE 函数: 创建数字序列。此处用于模拟一个连续的日子序列(3650天)。
c.-- (双负号) 强制类型转换: 用于确保日期被当作数字(序列值)处理。
d.YEAR/MONTH/DATE 函数: 用于日期处理(同公式二)。
e.GROUPBY 函数 (新函数): 强大的分组聚合函数(类似于数据透视表操作)。这里用于按“月份第一天”分组并计数(计算天数)。
f.COUNTA 函数: 用于 GROUPBY 中对分组内的元素计数。这里的“元素”都是同一个“月份第一天”重复出现,每个月的“月份第一天”出现的次数就等于该月的天数。
g.VLOOKUP 函数: 经典的查找函数。用于在 GROUPBY 生成的天数表中查找原始日期对应的天数。
h.日期序列值: Excel 内部将日期存储为数字(从1900-01-01开始的序列号)。
i.数组操作与动态数组: 整个公式依赖现代Excel对数组公式的强大支持(动态溢出)。涉及处理多个数组:A, B, GROUPBY 结果。
j.复杂度与效率: 该方法极其复杂、低效且不必要。它绕了一大圈:生成大量日期 -> 提取月份第一天 -> 聚合计数天数 -> 再反查原始日期对应的天数。其真正价值可能在于演示 LET、SEQUENCE 和 GROUPBY 的组合使用场景(一个非常低效的场景)。
来源:古哥计划一点号