这一篇要动手做的,是几乎每月都重复的事:明细表里躺着几千上万行订单,你要在上面算出一张“区域 × 月份”的汇总表——每个格子是金额合计,旁边一列是单数。做完以后,新增一个月的数据,你只需要换掉表头日期,整张表自己就变了,不用再筛选、复制、粘贴、求和。
准备两样东西。一份明细,一行一条记录,中间没有合并单元格、没有小计行(这类表为什么必须先改规范,前面那篇讲过),日期列必须是真正的日期,不是“2024年3月”这样的文字。再加一张空表放汇总结果。
本文用一份 8 行的明细来核对结果,放在工作表 明细 的 A1:E9:A 列订单号、B 列日期、C 列区域、D 列销售员、E 列金额。金额依次 1200、800、1500、900、600、700、1100、400;日期依次 3/2、3/15、3/20、4/1、4/8、3/28、4/15、3/30;区域依次华东、华北、华东、华东、华南、华东、华北、华南。
求和区域排在第一个,后面才是成对的条件
多数人的直觉是先说条件、再说加哪一列。SUMIFS 恰好反过来:
1=SUMIFS(求和区域, 条件区域1, 条件1, 条件区域2, 条件2, ...)第一个位置放 要加总的那些数,然后成对地写“去哪一列看、看到什么才算数”。算华东区 3 月的合计:
1=SUMIFS(明细!$E$2:$E$9, 明细!$C$2:$C$9, "华东", 明细!$B$2:$B$9, ">="&DATE(2024,3,1), 明细!$B$2:$B$9, "<="&DATE(2024,3,31))读法:把 E2:E9 的金额加起来,但只加那些“C 列是华东”并且“B 列不早于 2024/3/1”并且“B 列不晚于 2024/3/31”的行。拿这 8 行数一遍是 1200 + 1500 + 700 = 3400,能对上就说明三个条件的位置放对了。
一个对照要记住:只能写一个条件的 SUMIF 是 SUMIF(条件区域, 条件, 求和区域),求和区在最后。两个函数长得像、顺序不同,从旧公式改过来时抄错位置很常见 1。
所有区域必须一样大,否则整个公式报错
上面每个区域都写成 $2:$9。SUMIFS 要求 求和区域和每一个条件区域的行数、列数完全一致,不一致就直接得到 #VALUE!——不是算错,是整个公式不算 2。比如求和区域手滑写成 $E$2:$E$8(少一行),条件区域还是 $2:$9,立刻报错。这种错反而好,因为它藏不住。
难发现的是行数刚好相同、起点错开一格的情况,比如 $B$3:$B$10 配上 $E$2:$E$9:不报错,算出来却是错位的行,只能手工核对才看得出。
顺带说清一个容易混的点:单条件的 SUMIF 不要求一样大,文档明确说它会拿条件区域的左上角当起点、自己扩展成和求和区域一样大 2。所以“SUMIF 能跑、换成 SUMIFS 就 #VALUE!”是正常现象,不是 Excel 坏了。
条件怎么写
条件不是单纯的值,而是一段会被 Excel 解释的比对文本,写法决定怎么比。
文字要带引号。 "华东" 是条件,华东 不是。少了引号,Excel 会当它是一个定义好的名称去找,找不到就显示 #NAME?。
比较符要跟值拼在同一个字符串里。 ">=1000" 可以;要引用单元格时用 & 拼,写成 ">="&$G$1。
日期用 DATE 拼,别手写日期串。 ">=2024/3/1" 要靠本机日期格式去猜,换台电脑结果可能不同;">="&DATE(2024,3,1) 把日期换成 Excel 内部的日期序号再拼进去,跟设置无关。日期边界放在单元格里就直接 ">="&$B$1,前提是那一格真的是日期。
“某个月”是两遍同一个区域。 它不是一次比较,而是“不早于月初”且“不晚于月末”,所以日期列出现两次,一次配 >=、一次配 <=。两边都带等号,说明边界包含在内:3 月 1 日和 3 月 31 日当天的单都算进 3 月。月末用 EOMONTH($B$1,0) 求:给一个日期和偏移 0,它返回那个日期所在月的最后一天,2 月和闰年都不用你记天数。
拖成一张表:哪一半要锁
汇总表 A2:A4 写华东、华北、华南,B1 和 C1 分别放 2024/3/1 和 2024/4/1 两个真日期,单元格格式设成 m"月",屏幕显示“3月”“4月”,格子里还是日期。在 B2 写:
1=SUMIFS(明细!$E$2:$E$9, 明细!$C$2:$C$9, $A2, 明细!$B$2:$B$9, ">="&B$1, 明细!$B$2:$B$9, "<="&EOMONTH(B$1,0))三个区域用 $ 钉死,它们永远不变;$A2 锁列、放开行,因为它要跟着往下走(华东→华北),不能跟着往右走;B$1 锁行、放开列,因为它要跟着往右走(3月→4月),但永远在第 1 行。这就是上一篇相对、绝对、混合引用里说的“锁住哪一半”,只是这里两个方向各出现一次、锁法相反。
双击右下角填满 B2:C4,应该得到 3400/900、800/1100、400/600。三行两列都能拿明细对上,这张表就能长期用了。加 5 月只需把 C 列整列复制到 D 列、改 D1 的日期,公式自动变成 >="&D$1,其它一个字都不用动。唯一要留意的是 $2:$9 写死了行数,明细新增行会漏算;改成整列引用(明细!$E:$E)或把明细转成表格、用列名引用,范围就会自己长大。
出错时你会看到什么
#VALUE! → 求和区域和某个条件区域行列数不一致。逐个参数框一下,看是不是都从同一行到同一行 2。
#NAME? → 文字条件漏了引号,或工作表名写错、没加感叹号。
结果是 0 → 最危险的一种。SUMIFS 一条都没匹配上时返回 0,不报错也不留空,和“这个区域这个月确实卖了 0 元”长得一样 1。看到 0 先别信:手动筛一下这个区域这个月到底有没有单;检查日期条件有没有写反(>= 配成 <=,区间就空了);检查日期列是不是被存成了文本——文本“2024-03-05”在比较大小时不被当作日期,结果常常是算不出来或报 #VALUE!。用 =ISNUMBER(明细!B2) 查一格,返回 FALSE 就是文本,用“数据 → 分列”转成真日期。
合计明显偏小 → 金额列里混着“看着是数字”的文本,SUMIFS 不会把它们加进去,直接跳过。同样用 ISNUMBER 查,同样用分列转。
条件格是空的 → COUNTIFS、SUMIFS 会把空单元格当 0 来比 3,于是变成“金额 >= 0”这类宽得离谱的条件,把不该算的都算进来。所以表头和条件格先填好再拖。
笔数:拿掉求和区域就是 COUNTIFS
COUNTIFS 就是 SUMIFS 去掉第一个参数:
1=COUNTIFS(条件区域1, 条件1, 条件区域2, 条件2, ...)在 E2 写:
1=COUNTIFS(明细!$C$2:$C$9, $A2, 明细!$B$2:$B$9, ">="&B$1, 明细!$B$2:$B$9, "<="&EOMONTH(B$1,0))填满后华东 3 月 3 单、4 月 1 单,华北和华南各月各 1 单。区域约束、条件写法都和 SUMIFS 完全一样。
笔数不只是给人看的,它顺手解决了上面那个“0 到底是什么”的问题:笔数 0、合计 0,仍然要再查明细才知道是不是真没数据;但笔数是 3、合计却是 0,那几乎一定是金额列存成了文本,而不是没有数据。
每月只做三件事
把新月份的明细贴进 明细(行数变多就改用整列或表格引用);在汇总表新增一列,只填表头日期;把上一列整列复制过去。
核对顺序建议固定:挑一个月一个区域,用筛选手工加一遍和 SUMIFS 比,这一步能同时抓住区域写错和金额是文本;再把某一行各月加起来,和全年合计对一下;最后让笔数列合计等于明细的有效行数,不等就说明有条件写宽了,最常见的是日期边界。
两个自测题(先自己想,再展开)
- 把 3 月那一列复制成 5 月,除了改表头日期,公式里还要改什么?
- 某个格子显示 0,怎么判断是“这个月没卖”还是“公式有问题”?
参考答案:
- 什么都不用改。区域都锁死了,月份通过
B$1跟着列走,EOMONTH会自动算出 5 月的最后一天。 - 先看旁边的 COUNTIFS 笔数,再用筛选确认明细里有没有这个区域、这个月的记录;笔数不为 0 而合计为 0,就查金额列是不是文本。
一句话收束:SUMIFS 第一个位置是“要加的数列”,后面成对写“看哪列、认什么”;所有区域必须一样大;月份是靠两个日期条件围出来的区间;返回 0 从不能证明“真的没有”,要靠笔数和抽查去确认。