在excel里做「凑数求和」,最靠谱的方法就是用solver规划求解:在金额列旁边加一列0/1的标记,用sumproduct函数算出选中金额的总和,再让solver自动调整,把总和凑到你要的目标数。这里演示用的是microsoft excel哈,要是你功能区里找不到solver,得先手动启用「规划求解加载项」才行。
下面我拿一组报销金额来演示:目标是从这些明细里挑出几笔,让加起来刚好等于1200。这个方法比较适合几十行以内的单目标凑数,要是行数特别多的话,建议先按日期、部门或者金额范围筛一下,缩小要处理的明细范围。
第一步:整理金额和辅助列
先把所有要参与凑数的金额整理到同一列,旁边新建一列叫「是否选中」的辅助列,一开始先全部填0。然后在结果单元格里输入公式 =SUMPRODUCT(B2:B15,C2:C15),这里B列是金额列,C列就是刚才的0/1标记列;哪一行被Solver改成1,对应的这笔金额就会被算到总和里。

第二步:打开规划求解
切换到「数据」选项卡,找到「规划求解」按钮。要是找不到的话,就去「文件 → 选项 → 加载项」里,在Excel加载项那栏把「规划求解加载项」勾上。等按钮出来之后回到数据表就行,不用改原来的金额,我们只让Solver去调整辅助列的内容。

第三步:设置目标单元格
打开Solver参数窗口后,把「Set Objective(设置目标)」选成刚才输了SUMPRODUCT公式的合计单元格;目标类型选「Value Of(目标值)」,右边输入你要凑的数,比如这里是1200。下面的「By Changing Variable Cells(可变单元格)」就填辅助列的范围,比如 C2:C15,意思就是让Excel自己决定哪些行填1。

第四步:添加二进制约束
点「Add(添加)」加一个约束,把辅助列的范围设置为 bin(二进制)。这个约束特别重要,它能把辅助列的数值限制在0或1,防止Solver算出0.38、1.6这种没意义的小数。毕竟咱们的金额是整笔算的,不能拆分,二进制约束就相当于「选或不选」的开关。

第五步:执行求解
回到Solver参数窗口后点「Solve(求解)」就行。要是当前这些金额里确实有组合能刚好凑出目标数,Solver会弹出结果窗口,你选保留求解结果就好。要是提示找不到可行解,一般不是公式错了,而是这批金额里本来就没有刚好等于目标值的组合,这时候可以放宽一点目标,或者先把明显不可能的金额剔掉再试。

第六步:核对选中结果
你可以看看辅助列里被改成1的行,这些行对应的金额就是凑出来的组合。合计单元格的数值应该刚好等于目标数;要是不放心,也可以在旁边用 =SUM(C3,C5,C9) 这种普通求和公式手动核对一遍,确认没把没选中的行算进去。

SUMPRODUCT 函数语法
这次用到的核心公式是 =SUMPRODUCT(array1,[array2],...)。它的作用是把两个数组对应位置的数先相乘,再把所有乘积加起来,所以用「金额 × 是否选中」刚好就能算出选中金额的总和。
| 参数 | 写法示例 | 作用 |
|---|---|---|
| array1 | B2:B15 |
存放要参与凑数的金额的区域。 |
| array2 | C2:C15 |
辅助列,0代表不选这笔,1代表选中这笔。 |
| 更多数组 | D2:D15 |
要是需要同时叠加更多筛选条件就再加,注意所有区域的行数必须一致。 |
大家最容易踩的坑有两个:一是金额区域和辅助列的行数对不上,公式会返回 #VALUE! 错误;二是忘了给辅助列加二进制约束,算出来的结果看似接近目标,实际上选中的金额根本没法按整笔业务来用。
扩展示例:按部门先筛一层
要是你只想在「销售部」的金额里凑1200,还可以再加一列部门判断,比如在D2输入 =--(A2="销售部") 然后向下填充,再把合计公式改成 =SUMPRODUCT(B2:B15,C2:C15,D2:D15)。这样Solver还是调整C列的0/1,但非销售部的金额会因为D列是0,根本不会参与合计计算。
做完之后别急着删辅助列哈。把值为1的行筛出来,复制到新表或者标个颜色,后面对账、报销核销、库存配套的时候复查起来都方便很多。











