You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Excel中查找匹配付款金额的采购项组合:随机数求和匹配问题

采购记录匹配付款金额的解决方法

你碰到的是典型的子集和问题,Excel自带的数据透视表、普通公式确实搞不定,得用VBA或者Power Query来实现,下面给你两个实用方案:

方案一:VBA宏代码批量查找

这个方法直接在Excel里运行代码,能找出对应付款金额的采购组合:

  1. 按 Alt + F11 打开VBA编辑器,插入一个新模块
  2. 粘贴以下代码(记得根据你的实际单元格范围修改):
Sub FindPurchaseMatches()
    Dim purchaseRange As Range, paymentRange As Range
    Dim purchaseVals As Variant, paymentVals As Variant
    Dim i As Long, j As Long, targetAmt As Double
    Dim comboText As String, resultRow As Long
    
    ' 替换成你的采购金额区域(比如A列第2行到第58行,共57条)
    Set purchaseRange = ThisWorkbook.Sheets("Sheet1").Range("A2:A58")
    ' 替换成你的付款金额区域(比如B列第2行到第19行,共18条)
    Set paymentRange = ThisWorkbook.Sheets("Sheet1").Range("B2:B19")
    
    purchaseVals = purchaseRange.Value
    paymentVals = paymentRange.Value
    resultRow = 2 ' 结果输出到C、D列,从第2行开始
    
    ' 遍历每一笔付款
    For i = 1 To UBound(paymentVals)
        targetAmt = paymentVals(i, 1)
        ' 先筛选出小于等于目标付款的采购项,减少计算量
        Dim filteredList As Variant, filterCount As Long
        filterCount = 0
        ReDim filteredList(1 To UBound(purchaseVals), 1 To 1)
        For k = 1 To UBound(purchaseVals)
            If purchaseVals(k, 1) <= targetAmt Then
                filterCount = filterCount + 1
                filteredList(filterCount, 1) = purchaseVals(k, 1)
            End If
        Next k
        ReDim Preserve filteredList(1 To filterCount, 1 To 1)
        
        ' 枚举所有可能的采购组合
        For j = 1 To 2 ^ filterCount - 1
            Dim tempSum As Double, m As Long
            tempSum = 0
            comboText = ""
            For m = 1 To filterCount
                If (j And 2 ^ (m - 1)) <> 0 Then
                    tempSum = tempSum + filteredList(m, 1)
                    comboText = comboText & "$" & filteredList(m, 1) & ", "
                End If
            Next m
            ' 匹配成功就输出结果(用小误差避免浮点精度问题)
            If Abs(tempSum - targetAmt) < 0.0001 Then
                ThisWorkbook.Sheets("Sheet1").Cells(resultRow, "C").Value = "付款金额: $" & targetAmt
                ThisWorkbook.Sheets("Sheet1").Cells(resultRow, "D").Value = Left(comboText, Len(comboText) - 2)
                resultRow = resultRow + 1
            End If
        Next j
    Next i
End Sub
  1. 调整代码里的单元格范围(比如你的采购记录不在A2:A58,就改成你实际的区域)
  2. 运行宏,结果会显示在C、D列,每一行对应一笔付款的匹配采购组合

方案二:Power Query自定义函数(无VBA)

如果不想用宏,也可以用Power Query来实现:

  • 把采购和付款记录分别导入Power Query
  • 新建自定义函数,生成所有采购组合并计算总和
  • 对每笔付款,调用函数筛选出总和匹配的组合

不过要注意,57条记录的组合数极大,必须先筛选掉大于目标付款的采购项,否则计算会非常慢甚至崩溃。

实用小提示

  • 先手动预处理:对每笔付款,先删掉采购记录里比它大的金额,大幅减少需要计算的组合数
  • 处理小数精度:比较金额时一定要留小误差(比如Abs(总和 - 付款) < 0.0001),避免因为Excel的浮点精度问题漏匹配

内容的提问来源于stack exchange,提问作者Richard K.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 11:52:52