|
发表于 2015-12-29 14:14
|
显示全部楼层
本楼为最佳答案
按8楼思路弄的代码。我觉得总的原则是对冲掉尽可能多的行。- Sub 统计()
- arr = Sheet1.[a1].CurrentRegion.Offset(1)
- Set df = CreateObject("scripting.dictionary") '记录相同物资的负值
- Set ddf = CreateObject("scripting.dictionary") '记录相同物资的负值的行
- Set dz = CreateObject("scripting.dictionary") '记录相同物资的最小正值
- Set ddz = CreateObject("scripting.dictionary") '记录相同物资的最小正值的行
- Set d = CreateObject("scripting.dictionary") '记录需要删除的行
- Set sy = CreateObject("scripting.dictionary") '记录所有key
- For i = 2 To UBound(arr)
- x = arr(i, 7) & arr(i, 9) & arr(i, 11) '以名称+计量单位+单价 为key
- If Len(x) > 0 Then
- sy(x) = "" '所有key
- sl = arr(i, 10) '数量
- If sl < 0 Then '数量小于0
- df(x) = df(x) + sl
- ddf(x) = ddf(x) & "," & i
- ElseIf sl > 0 Then '数量大于0
- dz(x) = dz(x) + sl
- ddz(x) = ddz(x) & "," & i
- Else '数量等于0,直接进删除字典
- d(x) = d(x) & "," & i
- End If
- End If
- Next
-
- For Each x In sy.keys
- frr = Split(ddf(x), ",")
- zrr = Split(ddz(x), ",")
- If UBound(frr) >= 1 And UBound(zrr) >= 1 Then '有正负数才开始消除
- If UBound(frr) > 1 Then
- For i = 1 To UBound(frr) - 1 '负值数量从大到小排序
- For j = i + 1 To UBound(frr)
- If arr(frr(i), 10) < arr(frr(j), 10) Then tmp = frr(i): frr(i) = frr(j): frr(j) = tmp
- Next
- Next
- End If
- If UBound(zrr) > 1 Then
- For i = 1 To UBound(zrr) - 1 '正值数量从小到大排序
- For j = i + 1 To UBound(zrr)
- If arr(zrr(i), 10) > arr(zrr(j), 10) Then tmp = zrr(i): zrr(i) = zrr(j): zrr(j) = tmp
- Next
- Next
- End If
- zs = dz(x): fs = df(x) '正负数
- If zs >= Abs(fs) Then '正数大于等于负数
- For i = 1 To UBound(frr) '负值行全部消除
- d(Val(frr(i))) = ""
- Next
- tmp = 0
- For i = 1 To UBound(zrr) '正值行消除到最后一个去余值
- k = Val(zrr(i))
- tmp = tmp + arr(k, 10)
- If tmp <= Abs(fs) Then
- d(k) = ""
- Else
- arr(k, 10) = tmp + fs: Exit For
- End If
- Next
- Else '正数小于负数
- For i = 1 To UBound(zrr) '负值行全部消除
- d(Val(zrr(i))) = ""
- Next
- tmp = 0
- For i = 1 To UBound(frr) '负值行消除到最后一个去余值
- k = Val(frr(i))
- tmp = tmp + arr(k, 10)
- If Abs(tmp) <= zs Then
- d(k) = ""
- Else
- arr(k, 10) = tmp + zs: Exit For
- End If
- Next
- End If
- End If
- Next
-
- ReDim brr(1 To UBound(arr), 1 To UBound(arr, 2)) '把未删除的行保留
- For i = 1 To UBound(arr)
- If Not d.exists(i) Then
- n = n + 1
- For j = 1 To UBound(arr, 2)
- brr(n, j) = arr(i, j)
- Next
- End If
- Next
- With Sheets(3) '结果显示
- .Cells.Clear
- .[a1].Resize(n, UBound(arr, 2)) = brr
- .Activate
- End With
- End Sub
复制代码 |
|