Sub CutPlan()
Me.Select
Dim ar, a&(), b(), c&(), d(), dic, tr, i&, i1&, j&, j1&, k&, l&, l1&, m&, m1&, n&, r&, r1&, r2&, s@, t&, u@, u1@, v@, v1@, w$, x#, tms#
n = [b1].End(4).Row - 1 'B列数据个数m
m = Application.Sum([c2].Resize(n)) 'C列个数总和n
u = Application.Max([b2].Resize(n)) 'B列最大值u
u1 = Application.Min([b2].Resize(n)) 'B列最小值u1
v = Val([d2]): v1 = Val([d3])
Do Until v >= u
v = Val(InputBox("输入每组最大限额", "凑数", u)): [d2] = v
'如当前数据中最大值u 超过了基础量v将无法正确计算,所以需要重新设置基础量v
Loop
v = v + v1
tms = Timer '开始计时
ar = WorksheetFunction.Transpose([a2].Resize(n, 4)) '读取3列原始数据到数组ar
ReDim a&(1 To m) '定义数组a
ReDim b(-1 To m, -3 To n)
b(-1, -3) = "项数": b(-1, -2) = "根数": b(-1, -1) = "需求计划: " & n & " 规格 / " & m & " 根": b(-1, 0) = "剩余数"
For j = 1 To n
b(-1, j) = ar(2, j)
u = ar(2, j): l = ar(3, j): ar(4, j) = u + v1 '取得规格长度数据u、根数l
s = s + u * l '统计长度Sum总和s
For l = 1 To l '遍历根数n
k = k + 1: a(k) = j '单根数据序号
Next
Next
i1 = s \ v: If i1 * v < s Then i1 = i1 + 1
b(0, -1) = "方案明细:规格*根数(理想数=" & i1 & ")"
Set dic = CreateObject("Scripting.Dictionary")
l1 = [d11]: If l1 = 0 Then l1 = m \ n 'l1 = Log(n)
For i = 1 To m
dic.RemoveAll
For l = 0 To l1
ReDim c&(1 To m): m1 = m
Do
ReDim d(n)
u = v
For k = 1 To m
If c(k) = 0 Then
j = a(k)
If u >= ar(4, j) Then
m1 = m1 - 1: c(k) = 1: d(j) = d(j) + 1
u = u - ar(4, j)
If u < u1 Then Exit For
End If
End If
Next
w = Join(d, ",")
If Not dic.exists(w) Then
r1 = m
For j = 1 To n
If d(j) Then r = ar(3, j) \ d(j): If r < r1 Then r1 = r
Next
dic(w) = Val(CCur(-(Int(-u / u1)) + 1 - r / m))
End If
Loop While m1
If l < l1 Then
Randomize '随机种子初始化 确保随机性
For k = 1 To m
r = Int(Rnd() * (m - k + 1)) + k
t = a(r): a(r) = a(k): a(k) = t
Next
End If
Next
tr = dic.items
x = WorksheetFunction.Min(dic.items)
l = WorksheetFunction.Match(x, tr, 0) - 1
w = dic.keys()(l)
tr = Split(w, ",")
k = 0: u = v: r1 = m: w = ""
For j = 1 To n
If tr(j) <> "" Then
k = k + 1: t = tr(j): u = u - ar(4, j) * t
r = ar(3, j) \ t: If r < r1 Then r1 = r
b(i, j) = t: w = w & "+" & ar(2, j) & "*" & t
End If
Next
For j = 1 To n
If tr(j) <> "" Then
t = tr(j): ar(3, j) = ar(3, j) - r1 * t: b(0, j) = b(0, j) + r1 * t: m = m - r1 * t
End If
Next
b(i, 0) = Val(u): b(i, -1) = mid(w, 2): b(i, -2) = r1: b(i, -3) = k:
b(0, -2) = b(0, -2) + r1
b(0, 0) = b(0, 0) + Application.Evaluate(w) * r1
Application.StatusBar = Format(Timer - tms, "0.00s") & " 已完成" & Format(b(0, 0) / s, "(0.0%)") & "、估计尚需 " & Format((s / b(0, 0) - 1) * (Timer - tms), "0.00s")
If b(0, 0) = s Then Exit For '【已完成总计】等于Sum总和s时 结束
' [g1].Resize(2 + i, 4 + n) = b
ReDim a&(1 To m): k = 0
For j = 1 To n
For l = 1 To ar(3, j)
k = k + 1: a(k) = j '单根数据序号
Next
Next
Next
b(0, -3) = i: t = b(0, -2)
[g1].CurrentRegion.Clear '清空输出数据区域
Cells.Font.Size = 9
[g1].Resize(2 + i, 4 + n) = b '输出数组br结果
[g3].Resize(i, 4 + n).Sort [j3], 1, [h3], , 2, [g3], 1, 2 '按第1列原数据序号进行恢复性排序
[g1].Resize(, 4 + n).EntireColumn.AutoFit '所有列进行列幅自动修正
[g1].Resize(2 + i, 4 + n).Borders.LineStyle = 1 '输出数据区域画格子线
MsgBox "OK"
End Sub
Sub splitbr()
b = Me.Range("g1").CurrentRegion
For x = 3 To UBound(b)
s = Split(b(x, 3), "+")
If UBound(s) > 3 Then
End If
Next
End Sub
G:\0.programming_order\0.稍早前\202005\0525\下料优化