如何使用VBA代码计算总和为某个值的组合

论坛 期权论坛 期权     
VBA编程学习与实践   2019-6-9 21:26   3515   0
宁静的夏天 天空中繁星点点 心里头有些思念  思念着你的脸……

我们今天分享的内容目的只有一个,就是凑数。
当然,不是滥竽充数的凑数,而是科学发展观指导下的……凑数~好吧,反正就是凑数……
举个例子,还是。


如上图所示。A列是发票号,B列是发票金额,假设你有一笔汇款,不多,也就五百万……美金而已……
现在你想知道这五百万美金是由哪些发票金额组成的?
很久以前,我们在另外一个公众号分享了规划求解的方案,参考链接:聊下如何用【规划求解】计算总和为某个值的组合
规划求解的方案有很多好处,当然,也有很多缺点。本着君子坦荡荡的胸怀,咱们这里就只说坏处呗,比如说,这家伙只能得出一个解,甚至很多时候磨磨唧唧半天,还得不出一个解,或者得出一个错误解……
嘿,何不用VBA呢?
来个图,一键得解……吼~就是这么爽利~


如图所示,A列为发票号,B列为发票金额,D1单元格为目标合计值,D2单元格为求解的个数。

求解的个数可以设置为一个,也可以是多个,或者所有解……
代码也并不复杂
如下:
Sub MatchNum()    Dim arr, brr, i&, j&, k&, n&, mb, sl    mb = Val([e1].Value): sl = [e2].Value    arr = Range("b2:b" & Cells(Rows.Count, 2).End(xlUp).Row)    '金额装入数组arr    ReDim brr(2 ^ UBound(arr), 1 To 1)    'brr是结果数组    [f:i].ClearContents    [g1:i1] = [{"方案","金额组合","票号"}]    k = 0    For i = 1 To UBound(arr)        For j = 0 To k            k = k + 1            brr(k, 1) = brr(j, 1) & "+" & arr(i, 1)            '利用结果数组brr错位引用,遍历所有组合,使用加号相连            If Evaluate(brr(k, 1)) = mb Then            '使用Evaluate函数计算表达式                n = n + 1                Cells(n + 1, 7) = "解法" & n                Cells(n + 1, 8) = brr(k, 1)                If n >= sl Then Exit Sub        End If        Next    Next    If n = 0 Then MsgBox "无解"    Erase brrEnd Sub
不过话说回来,这代码当然也不是万能的,当B列的数值过多,而求解的个数又设置为所有时,程序必然会卡死,毕竟遍历的组合可能极其多,甚至无穷尽……
这个时候,建议求解的个数设置一下,比如一个?一心一意一见钟情一生一世嘛……嗯,没别的要说的了。
关于代码……已经有注释了,其实核心就是下面这句,类似于函数公式中的错位引用,多运行几次代码应该也就明白了。
brr(k, 1) = brr(j, 1) & "+" & arr(i, 1)
然后留了一个小尾巴。
如何根据H列计算出的数值组合得出对应的发票号码?
嘿嘿嘿,很简单,下期再说。
当然啦,您也可以动手写下代码,点击【阅读原文】可以下载示例文件(提取码d8kc)。注意,B列的金额可能重复。
OVER~
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:220
帖子:44
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP