|
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件 ★ 免费下载 ★ ★ 使用帮助★
用网上代码拼凑了一个,凑合着用吧。借鉴了CSDN薛定谔_51大神的贴子,https://blog.csdn.net/hhhhh_51/article/details/132037091
- Sub 凑数问题()
- ' by zeng3915 https://club.excelhome.net/thread-1713384-1-2.html
- Dim arr, brr(), i&, j&, s&, jj&, dc&
- Dim dic As Object, rg As Range
- Set dic = CreateObject("scripting.dictionary")
- arr = Sheet1.UsedRange
- Sheet2.Cells.Clear
- Sheet2.Cells(1, 1).Resize(1, 15) = Array(arr(1, 3), arr(1, 14), arr(1, 140), arr(1, 141), arr(1, 160), "箱数", "箱数*系数", "1-5箱", "6-10箱", "11-15箱", "16-20箱", "21-25箱", "26-30箱", "31-35箱", "36-40箱")
- For i = 2 To UBound(arr)
- If Len(arr(i, 14)) > 0 Then
- s = s + 1
- ReDim Preserve brr(1 To 15, 1 To s)
- brr(1, s) = arr(i, 3) '型号
- brr(2, s) = arr(i, 14) '待装箱数
- brr(3, s) = arr(i, 140) '长度
- brr(4, s) = arr(i, 141) '单个产品内含个数
- brr(5, s) = arr(i, 160) '包装系数
- brr(6, s) = Int(arr(i, 14) / 5) '箱数
- brr(7, s) = brr(6, s) * brr(5, s) '箱数*系数
- End If
- Next i
- brr = Application.Transpose(brr)
- Sheet2.Cells(2, 1).Resize(UBound(brr), UBound(brr, 2)) = brr
- Set rg = Sheet2.Range("A1").Resize(UBound(brr, 1) + 1, UBound(brr, 2))
- rg.Sort Key1:="发货数量", Order1:=2, Header:=xlYes
- arr = rg.Value
- For i = 2 To UBound(arr)
- dic(i) = arr(i, 7)
- Next i
- dc = dic.Count
- Do '2层do方便有符合目标值时跳出,并继续组合
- Do
- For j = 2 To dc
- brr = combin_arr1(dic.keys, j)
- For r = 1 To UBound(brr)
- temp_sum = 0
- For c = 1 To UBound(brr(r))
- temp_sum = temp_sum + dic(brr(r)(c))
- Next
- If temp_sum = 56 Then
- jj = jj + 1
- For c = 1 To UBound(brr(r))
- arr((brr(r)(c)), 7 + jj) = arr((brr(r)(c)), 6)
- dic.Remove brr(r)(c) '写入箱号,删除行号
- Next
- Exit Do
- End If
- Next
- Next
- If dc = dic.Count Then Exit Do '无组合符合目标值,跳出
- Loop Until dc = 0
- If dc = dic.Count Then Exit Do
- dc = dic.Count
- Loop Until dc = 0
- jj = jj + 1
- For r = 1 To UBound(brr)
- For c = 1 To UBound(brr(r))
- arr((brr(r)(c)), 7 + jj) = arr((brr(r)(c)), 6)
- Next c
- Next r
- With Sheet2
- .UsedRange.Offset(1, 0).Clear
- .Cells(1, 1).Resize(UBound(arr), UBound(arr, 2)) = arr
- rg.Sort Key1:="产品型号", Order1:=1, Header:=xlYes
- r = .Cells(65536, 1).End(xlUp).Row
- For j = 8 To 15
- s = 0
- For i = 2 To r
- If .Cells(i, j) > 0 Then
- s = s + .Cells(i, j) * .Cells(i, 5)
- End If
- .Cells(r + 1, j) = s
- Next i
- Next j
- .Cells(r + 1, 2) = "=sum(R[-" & r & "]C:R[-1]C)"
- For j = 6 To 7
- .Cells(r + 1, j) = "=sum(R[-" & r & "]C:R[-1]C)"
- Next j
- Set rg = rg.Resize(rg.Rows.Count + 1, rg.Columns.Count)
- With rg
- .Borders.LineStyle = 1 '划框线
- End With
- End With
- Set dic = Nothing
- MsgBox "ok"
- End Sub
- Function combin_arr1(arr, n&)
- 'arr一维数组,内含m个元素,抽取n个进行组合,返回一维嵌套数组,每行为一个组合(数组从1开始计数)
- Dim i&, j&, k&, l&, m&, kk&, t&, temp
- If LBound(arr) = 0 Then '转为从1开始计数
- arr = WorksheetFunction.Transpose(WorksheetFunction.Transpose(arr))
- End If
- m = UBound(arr) - LBound(arr) + 1
- kk = Application.Combin(m, n): ReDim brr(1 To kk)
- If n = 1 Then
- For i = 1 To m
- brr(i) = WorksheetFunction.Transpose(WorksheetFunction.Transpose(Array(arr(i))))
- Next
- combin_arr1 = brr: Exit Function
- End If
-
- ReDim a&(1 To n), b(1 To n)
- For j = 1 To n - 1
- a(j) = j
- Next
-
- i = n - 1: k = 0 ': j = n '上面for结束后j=n,加不加j = n都一样
- Do
- For i = a(n - 1) + 1 To m '仅修改最后一位
- a(n) = i
- For l = 1 To n
- b(l) = arr(a(l))
- Next
- k = k + 1: brr(k) = b
- Next
- If a(n - 1) <> a(n) - 1 And a(n) = m Then
- a(n - 1) = a(n - 1) + 1
- ElseIf a(n - 1) = a(n) - 1 And a(n) = m Then
- For t = n - 1 To 1 Step -1 'a(j)进步,避免n=2情况报错,因而只n-1
- If a(t) <> a(t + 1) - 1 Then
- temp = a(t) + 1: a(t) = temp: t = t + 1
- Do Until t = n '为真退出,先判断;最后一位不修改
- a(t) = a(t - 1) + 1: t = t + 1
- Loop
- Exit For
- End If
- Next
- End If
- Loop Until k = kk
- combin_arr1 = brr
- End Function
复制代码
|
|