返回Excel催化剂目录

产品文档 / Excel催化剂

第31波-数量金额分组凑数功能,财务表哥表姐最爱

在财务工作过程中,很大时候需要使用到凑数的需求,花了两三天时间认真研究了一下,本人水平也只能做代码搬运工,在用户体验上作了一下完善。完成了Excel版的凑数功能。 更新及修复 20180812 重新修复一下函数,加入判断原始数据的小数点位数问题,原来的方式粗爆地对其乘10000,致使要凑数的数值变得

在财务工作过程中,很大时候需要使用到凑数的需求,花了两三天时间认真研究了一下,本人水平也只能做代码搬运工,在用户体验上作了一下完善。完成了Excel版的凑数功能。

更新及修复

  • 20180812
    重新修复一下函数,加入判断原始数据的小数点位数问题,原来的方式粗爆地对其乘10000,致使要凑数的数值变得虚大,一般财务的数据也就两位小数。修复后性能提升明细(凑数原理:输入的数值越大,两个数值之间的间隙越大,中间值越多,如10和20两个数,中间值有10个,但扩大10000倍后,中间值变为10万个,对底层算法影响很大)
    为Google的Or-Tools正名,修复后的性能不比EH差,初测貌似更快一些。

业务场景

有财务的朋友分享了一需求,开发票的过程中,需要一张发票发多个商品明细,有可能累计了许多的款项一次性给予开具发票,而同时发票又有面额最大的限制要求。

企业的每月可开发票数量也有限,故很需要有一个凑数的功能,帮助其从众多记录中抽取出部分记录,然后汇总求和得到接近或相等于发票最大开票面额。

其他的凑数场景略感觉还是有,一下子没想得太清晰,有相关的应用场景欢迎反馈补充,供后来人更多了解和使用。

功能演示

凑数的问题,涉及到规划求解类的知识,本人在数学方面造诣太浅,翻看ExcelHome论坛得知香川群子大神是这方面的专家,也无私公开了源代码,具体链接可查看:

http://club.excelhome.net/thread-1359141-1-1.html

同时顺藤摸瓜,按着这个背包算法,在师傅水晶鸡翼的指导下,得知Google的OR-Tools工具包里有同样的算法实现。抱着对Google科学家们的敬仰,学习了一点皮毛,也放到插件里使用了。

使用方式

本篇的功能,仍然采用自定义函数的方式实现,自定义函数较功能区按钮优越的地方,在前面29波中已有阐述,不再重复。

内容插图

因凑数计算量大,而使用函数向导的方向输入的话,每输入一个参数都运算一遍,还有可能卡机报错等,建议使用手动输入的方式,输入两个参数。

  1. 参数srcRange
    数据源的部分,就是引用用于凑数的记录对应的数量或金额字段,最多处理4位小数点,且需要正数。
  2. 参数groupRange
    用于分组的部分,有可能不止凑一个组合,且多个组合间有可能不一定是相等的,开发此设置,方便处理各种灵活场景。

手动输入时,可利用名称功能,输入更方便,输入某个参数时,若已经定义好名称,可按F3快捷键调出粘贴名称来选择。同时函数的可读性也得到加强。

内容插图

请务必输入区域时,不要全选整列数据,自定义函数没作整列的较验处理,整列选择意味着运算量是几万倍的增加,已经用到这些功能的表哥表姐们,也很必须学习好规范的Excel操作,减少不必要的麻烦和性能损耗

同样的引用的数据源,请务必保证是数字格式,最多4位小数点精度, 正数,中间没有空数据和字符等,不然函数计算会报错!

内容插图

计算的结果存放在记录表的某一列中,用的是数组公式的方式返回多个值,故若需要修改删除,请使用功能区的数组函数相关的删除、数值化、选择等快捷操作。

内容插图

若使用OR-TOOLS函数,在B列上可以看到更多的信息,如组名,组的大小,组的实际记录和和期望和的差异(0为无差异)

内容插图

同一功能两个函数差异

EH版香川群子大神的代码,在分组的大小较大时,性能仍然保持优异,而用OR-TOOLS实现的函数,就有很大的性能瓶颈。

例如某300条记录,总和是1000,我要分一个900的组,不知道为何OR-TOOLS的函数很慢,甚至最后报超时错误(OR-TOOLS因大小太大了,做了个网络版部署,网络访问太久会超时,同时也需要有连接外网的能力)。

EH版的函数,因原代码没有太多的封装,部分细节不太会改写,故没法做成像OR-TOOLS的分组形式,其实其他额外信息,大可用透视表汇总一下组名,很快得到,也非必须的信息。

建议使用EH版的凑数函数,OR-TOOLS版可能后续其他应用场景再开发其他的函数。

总结

Excel的原生功能并非万能,虽然自带了规划求解功能,但貌似比较鸡肋的功能,经常报找不到结果,借助代码的力量,结合网络世界中一些现成的轮子,Excel的使用也能玩出很高的、很出乎意料、超越常规的事情来。

凑数功能就是其中一例,用人工的方法去做,那不是一般的累人,可能到某几年之后才能算出来的结果。大胆地去想吧,脑洞大开一下,许多的不可能将成为可能。