SUMIFS 多条件统计:日期区间加多字段

先把参数顺序记牢

SUMIFS 是日常报表里出场率最高的函数之一,因为它能一次性解决“按某几个条件求和”的需求。但它的参数顺序和它的兄弟 SUMIF 完全相反,这是无数人第一次用时报错的根源。

SUMIFS 的语法是 =SUMIFS(求和区域, 条件区域1, 条件1, [条件区域2, 条件2], ...)。求和区域在最前面,之后是成对出现的条件区域和条件,最多可以写一百二十七对。

SUMIF 的语法则是 =SUMIF(条件区域, 条件, [求和区域])。求和区域在最后,而且只能有一个条件。

两者的差异可以这样记:单数 SUMIF 是老函数,参数设计时把求和区域当成了可选的后缀;复数 SUMIFS 是新函数,把求和区域提到了最前面。所以你写 SUMIFS 却按 SUMIF 的习惯把求和区域放最后,一定会得到 #VALUE!,因为函数会把你的求和区域当成第二个条件区域,发现尺寸对不上就报错。

对比项 SUMIF SUMIFS
语法 =SUMIF(条件区域,条件,求和区域) =SUMIFS(求和区域,条件区域,条件)
求和区域位置 最后一个参数 第一个参数
条件数量 只有一个 最多一百二十七对
区域尺寸要求 求和区域可自动扩展 所有区域尺寸必须一致
日期区间写法 需要两个函数相减 同一函数写两对条件

表格里最后一行值得展开说。SUMIF 只能表达一个条件,所以要做日期区间,只能写两个 SUMIF 相减,比如 =SUMIF(日期列,">="&开始日,金额列)-SUMIF(日期列,">"&结束日,金额列),逻辑绕且容易出错。而 SUMIFS 可以直接写两对条件,一次搞定:

=SUMIFS(C2:C100,A2:A100,">="&开始日,A2:A100,"<="&结束日)

其中 C2:C100 是要求和的金额列,A2:A100 是日期列。两对条件共用同一个日期列,这在 SUMIFS 里是完全允许的,也是日期区间统计的标准写法。

还有一个经常被忽略的好处:SUMIFS 的条件区域和求和区域可以任意指定,不需要相邻,也不需要排序。这比 VLOOKUP 那类要求首列的查找函数自由得多,几乎可以应对任何布局的明细表。

顺带记住同一家族的两个函数:COUNTIFS 和 AVERAGEIFS。它们的参数结构和 SUMIFS 完全一致,都是先给统计区域再给成对的条件,区别只在于最后统计的是个数还是平均值。学会 SUMIFS 之后,这两个几乎是白送的,把函数名换掉即可:

=COUNTIFS(A2:A100,">="&$H$1,B2:B100,"华东")
=AVERAGEIFS(D2:D100,A2:A100,">="&$H$1,B2:B100,"华东")

做报表时把这三个函数搭配使用,能一口气得到笔数、金额、平均单价三个指标,基本覆盖了管理层最常问的几个问题。

日期区间的三种写法

SUMIFS日期区间三种写法

写法一:引用单元格

最推荐的做法是把开始日和结束日放在两个单独的单元格里,比如 H1 和 H2,然后公式里引用它们:

=SUMIFS(C2:C100,A2:A100,">="&$H$1,A2:A100,"<="&$H$2)

这里的关键是条件不能直接写成 ">=H1",那样 Excel 会把 H1 当成文本字符串而不是单元格引用。必须把比较运算符用双引号包起来,再用连接符 & 接上单元格引用。这是日期条件最重要的写法,务必记住。

用 $H$1 这种绝对引用是为了让公式在横向纵向填充时都指向同一个参数单元格。做一份按月份排列的汇总表时,这个细节能省掉大量返工。

写法二:直接写死日期

如果日期是固定的,也可以直接写:

=SUMIFS(C2:C100,A2:A100,">=2023/1/1",A2:A100,"<=2023/12/31")

这种写法的问题在于,Excel 会先尝试把 2023/1/1 解析成日期,解析结果受系统区域设置影响。在中文环境下通常没问题,但文件发给区域设置不同的同事时可能出错。所以固定日期也建议放在单元格里引用,更稳妥。

写法三:动态区间

最常见的动态需求是“统计本月”。配合 EOMONTH 可以写成:

=SUMIFS(C2:C100,A2:A100,">="&EOMONTH(TODAY(),-1)+1,A2:A100,"<="&EOMONTH(TODAY(),0))

意思是大于等于本月第一天,且小于等于本月最后一天。日期推算的更多写法参见 日期推算:EDATE、EOMONTH、DATEDIF、NETWORKDAYS。

还有一个更简洁的写法,利用月份相等来判断:

=SUMIFS(C2:C100,A2:A100,">="&DATE(YEAR(TODAY()),MONTH(TODAY()),1),A2:A100,"<"&DATE(YEAR(TODAY()),MONTH(TODAY())+1,1))

这种写法用“小于下个月第一天”来代替“小于等于本月最后一天”,好处是完全避开了时间小数的问题。如果明细数据里有些日期带了时分秒,用“小于等于月末”会漏掉月末当天下午的记录,而“小于次月一号”则能完整覆盖。这是一个非常实用的技巧,建议养成习惯。

文本条件、通配符与不等于

条件写法的四个要点

文本条件最简单的形式是直接写内容:

=SUMIFS(C2:C100,B2:B100,"华东")

它等同于“等于华东”。如果要表达不等于,用 <>:

=SUMIFS(C2:C100,B2:B100,"<>华东")

不等号同样可以接单元格引用:=SUMIFS(C2:C100,B2:B100,"<>"&$H$3)。

通配符有两个:星号 * 代表任意长度的任意字符,问号 ? 代表单个字符。统计所有以“上海”开头的记录:

=SUMIFS(C2:C100,B2:B100,"上海*")

统计包含“分部”两个字的记录:

=SUMIFS(C2:C100,B2:B100,"*分部*")

如果内容里本身就有星号或问号,需要在前面加波浪号 ~ 转义,写成 "~*" 表示查找字面意义上的星号。这个转义规则很容易被忽略,遇到查不到结果时先想想是不是撞上了通配符。

数值条件同样支持比较运算符:

=SUMIFS(C2:C100,C2:C100,">1000")

注意这里求和区域和条件区域是同一列,这种写法合法且常用,意思是只统计金额大于一千的那些行。

条件为空值和非空值有专门的写法。统计某列为空的金额合计:

=SUMIFS(C2:C100,D2:D100,"")

统计某列非空的金额合计:

=SUMIFS(C2:C100,D2:D100,"<>")

这里有个陷阱:如果单元格里是公式返回的空字符串,"" 能匹配到,但 "<>" 也认为它非空,因为空字符串确实是长度为零的文本。想要严格判断真正空白,需要配合 ISBLANK,参见 信息函数:ISERROR、ISNUMBER、ISBLANK。

多字段组合与常见陷阱

把多个条件叠加起来是 SUMIFS 的核心能力。比如统计华东地区、产品为 A、金额大于一千的销售合计:

=SUMIFS(D2:D100,B2:B100,"华东",C2:C100,"A",D2:D100,">1000")

三个条件是“且”的关系,必须同时满足才会被计入。

如果需要“或”的关系,比如统计华东或华南两个地区,SUMIFS 本身做不到,只能把两个结果相加:

=SUMIFS(D2:D100,B2:B100,"华东")+SUMIFS(D2:D100,B2:B100,"华南")

条件越多,相加的项越多,公式会变得很长。这种情况下改用 SUMPRODUCT 通常更优雅,具体写法参见 SUMPRODUCT:不用数组也能多条件。

陷阱一:区域尺寸不一致

SUMIFS 要求求和区域和所有条件区域的行数完全相同。写 =SUMIFS(C2:C100,A2:A100,"华东",B2:B50,"A") 会直接返回 #VALUE!,因为 B2:B50 只有四十九行。这个错误在公式变长时最容易发生,尤其是后来插入了新行却只改了其中一个区域。

陷阱二:数字被存成文本

如果金额列里有些数字是从系统导出的文本,SUMIFS 会直接跳过它们,导致结果偏小。更麻烦的是它不会报错,你只会觉得数字好像不太对。检查办法是用 ISNUMBER 抽查,或者在条件里用 ">0" 看看是否所有行都被计入。

陷阱三:条件区域和求和区域写反

这是参数顺序带来的老问题。写 =SUMIFS(A2:A100,B2:B100,"华东") 时,函数会把 A2:A100 当求和区域、把 B2:B100 当条件区域,如果 A 列恰好是日期列,结果会得到一个莫名其妙的巨大数字(日期序列号的和)。看到结果大得离谱,先检查参数顺序。

陷阱四:日期列里有文本日期

和上面类似,如果日期列里混着文本日期,日期区间的条件会漏掉它们。用 ISNUMBER 全列检查一遍,把文本日期用分列功能转成真日期,是做日期统计前的标准动作。

陷阱五:整列引用

写 =SUMIFS(C:C,A:A,"华东") 虽然可行,但会让 Excel 扫描一百零四万行,在几千行的表上都会有明显卡顿。建议限定一个合理的上界,比如 C2:C5000,既覆盖当前数据又留出余量。

真实场景与兼容提示

场景:按月按地区交叉汇总

假设明细表里有日期列 A、地区列 B、产品列 C、金额列 D,共一百行数据。现在要做一张交叉表:行是月份,列是地区,交叉点是当月该地区的销售额。

在参数区放两个单元格:H1 放统计月开始日,H2 放统计月结束日。然后写:

=SUMIFS($D$2:$D$100,$A$2:$A$100,">="&$H$1,$A$2:$A$100,"<="&$H$2,$B$2:$B$100,I$1)

这里 I$1 是交叉表表头上的地区名,行方向填充时保持指向第一行,列方向填充时自动跟着换列,这就是混合引用的用法。所有明细区域都用绝对引用 $D$2:$D$100 锁定,公式随便拖都不会跑偏。

如果不想每月手工改 H1 和 H2,可以把它们换成公式:开始日写 =DATE(年份,月份,1),结束日写 =EOMONTH(开始日,0)。这样只要改年月两个数字,整张交叉表自动重算。

场景:排除某些状态的统计

销售明细里有一列状态,值包括“已完成”“已取消”“进行中”。要统计所有非取消状态的金额:

=SUMIFS(D2:D100,E2:E100,"<>已取消")

如果还要排除空白状态,就得再叠加一个条件:

=SUMIFS(D2:D100,E2:E100,"<>已取消",E2:E100,"<>")

因为 SUMIFS 的条件是“且”的关系,两个条件同时满足才会被计入,正好实现了排除两种情形的效果。

场景:跨工作表汇总

很多公司按月分表存放,一月到十二月各一张结构相同的工作表。要把十二张表按条件汇总,有两条路。

第一条路是用带 INTL 后缀的间接引用,写法复杂且容易出错,不推荐。更简单的第二条路是给每一张表单独写一段 SUMIFS,然后相加:

=SUMIFS(一月!D:D,一月!A:A,">="&$H$1)+SUMIFS(二月!D:D,二月!A:A,">="&$H$1)+...

十二项相加虽然长,但每一段都能单独检查,出错时一眼就能看出是哪张表的问题。如果工作表名称有规律,也可以先用 INDIRECT 拼出表名再传给 SUMIFS,但那样公式会失去可读性,且引用是易失的,重算变慢。

更根本的建议是:如果条件统计是常态,从一开始就不要按月拆表,把所有明细放在一张表里,用日期列区分月份。一张长表的统计效率远高于十几个分表,这也是做数据规范时最常被强调的一条原则。

场景:同比与环比

有了日期区间统计,同比环比就是两次数值相除。假设参数区放了本期开始日、本期结束日、上年同期开始日、上年同期结束日四个单元格:

=SUMIFS(金额列,日期列,">="&本期开始,日期列,"<"&本期结束)
=SUMIFS(金额列,日期列,">="&同期开始,日期列,"<"&同期结束)

同比增长率:

=IFERROR(本期/同期-1,"")

外套 IFERROR 是为了防止上年同期为零时出现除零错误。这里再次使用“小于结束日次日”的写法,保证区间端点不重不漏。

环比稍微复杂一点,因为上期不一定有相同的天数。如果按整月统计,上期的区间可以用 EOMONTH 推出来:开始日写 =EOMONTH(本月开始,-2)+1,结束日写 =EOMONTH(本月开始,-1)。这样不管每个月有多少天,区间都是完整的自然月,对比才有意义。

容错与验证

SUMIFS 在没有匹配项时返回零,而不是错误值,这是它的优点。但也正因如此,公式写错时你不会看到任何报警,只会得到一个偏小或为零的结果,容易蒙混过关。

建议养成三个验证习惯。第一,用 COUNTIFS 数一下符合条件的行数,看数量级是否合理。第二,用筛选功能手工筛一遍同样的条件,对比小计是否一致。第三,检查明细表的最后一行是否在公式区域内,很多人加了数据却忘了扩展区域。

版本兼容性

SUMIFS 从 Excel 2007 起提供,WPS 表格同样支持,可以放心使用。如果文件需要在 Excel 2003 里打开,就只能用 SUMPRODUCT 替代,后者的写法在本书下一篇里有详细说明。

条件里使用通配符的行为在 Excel 与 WPS 中一致,但要注意 WPS 对某些全角字符的通配符匹配略有差异。如果条件里包含中文标点,建议先用 SUBSTITUTE 统一成半角,再做统计,清洗手法参见 文本清洗:TRIM、CLEAN、SUBSTITUTE、REPLACE。

常见问题

为什么 SUMIFS 返回 #VALUE!

最常见的原因是区域尺寸不一致。检查求和区域和每一个条件区域的行数是否完全相同,比如 C2:C100 是九十九行,那所有条件区域也必须是九十九行。第二个常见原因是在旧版本 Excel 里打开了新函数,Excel 2003 及更早版本不认识 SUMIFS,会返回 #NAME? 而不是 #VALUE!。

还有一种情况是条件里引用了整行或者跨表区域,某些情况下会导致计算失败。排查办法是把公式拆开,先只留一对条件看是否正常,再逐对加回去,哪一步开始报错就是那一对有问题。

日期条件为什么要写成比较符接单元格引用的形式

因为条件参数本质上是一个文本字符串,Excel 需要先把它解析成“运算符加数值”的形式。如果直接写 ">=H1",Excel 会把 H1 当成两个普通字符,找不到名为 H1 的区域,结果要么是零要么是报错。

用连接符把运算符和单元格引用拼起来,函数拿到的就是 >=45261 这样的合法条件。这条规则适用于所有带比较运算符的条件,包括大于、小于、不等于,只要条件不是纯常量,就必须用 & 拼接。

怎么统计某个日期区间内、且满足多个文本条件的数据

直接在 SUMIFS 里叠加条件对即可,每一对是“条件区域加条件”的形式。日期区间算两对,每个文本条件算一对:

=SUMIFS($D$2:$D$100,$A$2:$A$100,">="&$H$1,$A$2:$A$100,"<"&$H$2,$B$2:$B$100,"华东",$C$2:$C$100,"A")

上面用了“小于结束日次日”的写法,这样即使明细里的时间带时分秒也不会漏算。这是做日期区间统计时最稳妥的表达方式,比“小于等于结束日”可靠。

SUMIFS 能不能实现“或”的条件

单个 SUMIFS 不行,它的所有条件是“且”的关系。要实现“或”,有两种办法。第一种是把多个 SUMIFS 相加,每个对应一个取值:

=SUMIFS(D2:D100,B2:B100,"华东")+SUMIFS(D2:D100,B2:B100,"华南")

第二种是改用 SUMPRODUCT,用加号连接多个判断:

=SUMPRODUCT(((B2:B100="华东")+(B2:B100="华南"))*D2:D100)

第二种写法在取值较多时明显更短,也不会因为漏加某项而算错。它的原理是把两个真假判断相加再乘以金额,满足任一条件时判断结果为真,参与乘法时按一计算。

结果比手工筛选的小计少,可能是什么原因

按概率排序,前四个原因是:区域没有覆盖到最后一行、数字被存成了文本、日期列里混着文本日期、条件里有多余的空格。

第五个原因是条件区域里存在合并单元格。合并单元格只有左上角那一格真正有值,其余格子是空的,统计时这一整块只会被计入一次甚至完全漏掉。解决办法是取消合并后填充,选中区域取消合并,再按 F5 定位空值,输入等号指向上一格,按 Ctrl + 回车批量填充。

排查顺序建议这样:先用 COUNTA 数一下明细行数,确认公式区域是否够长;再用 ISNUMBER 抽查金额列和日期列,看是不是文本;最后用 LEN 检查条件列的内容长度,看有没有尾巴上的空格。有空格就先用 TRIM 清洗一遍再统计,这一步能解决相当大一部分对不上的问题。