|
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件 ★ 免费下载 ★ ★ 使用帮助★
实例12:解法有点小问题返修和报废不是二三级排序,而是型号内同级排序,互不干扰。
还可以考虑返修和报废种类数不对等的情况。
- Sub lastDemo()
- Dim d(1 To 3), arr(), originArr, fNum%, bNum%, xhNum%, targetArr(), xh, fxArr, bfArr, minRow%, maxRow%, dataRows&, tempVal, y%
- Application.ScreenUpdating = False
- Application.DisplayAlerts = False
- ReDim arr(1 To 7, 1 To 100)
- ReDim targetArr(1 To 11, 1 To 100)
- For i = 1 To 3
- Set d(i) = CreateObject("Scripting.Dictionary")
- Next
- originArr = Worksheets("日报表").Range("a3:g" & Worksheets("日报表").Range("g" & Worksheets("日报表").Rows.Count).End(xlUp).Row)
- For i = 1 To UBound(originArr)
- If Not d(1).Exists(originArr(i, 2)) Then
- xhNum = xhNum + 1 '累计不重复型号(也是每个型号对应行)
- d(1)(originArr(i, 2)) = xhNum
- If xhNum > UBound(arr, 2) Then ReDim Preserve arr(1 To 7, 1 To UBound(arr, 2) + 100) '减少数组扩容次数
- arr(1, xhNum) = originArr(i, 2)
- End If
- arr(2, d(1)(originArr(i, 2))) = arr(2, d(1)(originArr(i, 2))) + originArr(i, 3) '型号内生产数量累计
- arr(3, d(1)(originArr(i, 2))) = arr(3, d(1)(originArr(i, 2))) + originArr(i, 5) '型号内返修数量累计
- arr(4, d(1)(originArr(i, 2))) = arr(4, d(1)(originArr(i, 2))) + originArr(i, 7) '型号内报废数量累计
- '型号内指定返修原因返修数量汇总
- d(2)(originArr(i, 2) & "|" & originArr(i, 4)) = d(2)(originArr(i, 2) & "|" & originArr(i, 4)) + originArr(i, 5)
- '型号内指定报废原因报废数量汇总
- d(3)(originArr(i, 2) & "|" & originArr(i, 6)) = d(3)(originArr(i, 2) & "|" & originArr(i, 6)) + originArr(i, 7)
- Next
- ReDim Preserve arr(1 To 7, 1 To xhNum)
- dataRows = 0
- For Each xh In d(1).Keys
- '每个型号
- '其下所有返修原因
- fxArr = Filter(d(2).Keys, xh & "|")
- '其下所有报废原因
- bfArr = Filter(d(3).Keys, xh & "|")
- '需考虑可能出现某个型号对应的返修、报废种类数不对等
- If UBound(fxArr) < UBound(bfArr) Then
- minRow = UBound(fxArr): maxRow = UBound(bfArr)
- arr(6, d(1)(xh)) = dataRows + minRow + 1 & "|" & (maxRow - minRow + 1) '返修可能需合并行起始|行数
- ElseIf UBound(fxArr) > UBound(bfArr) Then
- maxRow = UBound(fxArr): minRow = UBound(bfArr)
- arr(7, d(1)(xh)) = dataRows + minRow + 1 & "|" & (maxRow - minRow + 1) '报废可能需合并行起始|行数
- Else
- minRow = UBound(fxArr): maxRow = UBound(fxArr)
- End If
- arr(5, d(1)(xh)) = dataRows + 1 & "|" & (maxRow + 1) '序号、型号、总返修、报废率需合并行起始|行数
- For i = 0 To minRow
- dataRows = dataRows + 1
- If dataRows > UBound(targetArr, 2) Then ReDim Preserve targetArr(1 To 11, 1 To UBound(targetArr, 2) + 100)
- targetArr(1, dataRows) = d(1)(xh) '序号
- targetArr(2, dataRows) = xh '型号
- targetArr(3, dataRows) = arr(2, d(1)(xh)) '生产数量
- targetArr(4, dataRows) = fxArr(i) '返修原因
- targetArr(5, dataRows) = d(2)(fxArr(i)) '返修数量
- targetArr(6, dataRows) = Val(d(2)(fxArr(i))) / Val(arr(2, d(1)(xh))) '返修率
- targetArr(7, dataRows) = Val(arr(3, d(1)(xh))) / Val(arr(2, d(1)(xh))) '总返修率
- targetArr(8, dataRows) = bfArr(i) '报废原因
- targetArr(9, dataRows) = d(3)(bfArr(i)) '报废数量
- targetArr(10, dataRows) = Val(d(3)(bfArr(i))) / Val(arr(2, d(1)(xh))) '报废率
- targetArr(11, dataRows) = Val(arr(4, d(1)(xh))) / Val(arr(2, d(1)(xh))) '总报废率
- Next
- For i = minRow + 1 To maxRow
- dataRows = dataRows + 1
- If dataRows > UBound(targetArr, 2) Then ReDim Preserve targetArr(1 To 11, 1 To UBound(targetArr, 2) + 100)
- If arr(6, d(1)(xh)) <> "" Then '报废多
- targetArr(8, dataRows) = bfArr(i) '报废原因
- targetArr(9, dataRows) = d(3)(bfArr(i)) '报废数量
- targetArr(10, dataRows) = Val(d(3)(bfArr(i))) / Val(arr(2, d(1)(xh))) '报废率
- targetArr(11, dataRows) = Val(arr(4, d(1)(xh))) / Val(arr(2, d(1)(xh))) '总报废率
- ElseIf arr(7, d(1)(xh)) <> "" Then '返修多
- targetArr(4, dataRows) = fxArr(i) '返修原因
- targetArr(5, dataRows) = d(2)(fxArr(i)) '返修数量
- targetArr(6, dataRows) = Val(d(2)(fxArr(i))) / Val(arr(2, d(1)(xh))) '返修率
- targetArr(7, dataRows) = Val(arr(3, d(1)(xh))) / Val(arr(2, d(1)(xh))) '总返修率
- End If
- targetArr(1, dataRows) = d(1)(xh) '序号
- targetArr(2, dataRows) = xh '型号
- targetArr(3, dataRows) = arr(2, d(1)(xh)) '生产数量
- Next
- Next
- ReDim Preserve targetArr(1 To 11, 1 To dataRows)
- '排序
- '直接取dataRows,或重新Preserve
- For i = UBound(targetArr, 2) To 2 Step -1 'UBound(targetArr, 2) 数组容量赋得大,导致后面列空值最小,排到前面去了
- For j = 1 To i - 1
- If targetArr(2, j) > targetArr(2, j + 1) Then
- For y = 1 To 11
- tempVal = targetArr(y, j): targetArr(y, j) = targetArr(y, j + 1): targetArr(y, j + 1) = tempVal
- Next
- ElseIf targetArr(2, j) = targetArr(2, j + 1) Then
- '同一型号内返修、报废原因各自需要排序
- If targetArr(4, j) > targetArr(4, j + 1) And targetArr(4, j + 1) <> "" Then
- For y = 4 To 6
- tempVal = targetArr(y, j): targetArr(y, j) = targetArr(y, j + 1): targetArr(y, j + 1) = tempVal
- Next
- End If
- If targetArr(8, j) > targetArr(8, j + 1) And targetArr(8, j + 1) <> "" Then
- For y = 8 To 10
- tempVal = targetArr(y, j): targetArr(y, j) = targetArr(y, j + 1): targetArr(y, j + 1) = tempVal
- Next
- End If
- End If
- Next
- Next
- With Worksheets("Sheet2")
- .Range("a3:k" & Rows.Count).Clear
- .Range("f3:g" & Rows.Count).NumberFormatLocal = "0.00%"
- .Range("j3:k" & Rows.Count).NumberFormatLocal = "0.00%"
- .Range("a3").Resize(dataRows, 11) = Application.Transpose(targetArr)
- .Range("D:D").Replace What:="*|", Replacement:="", LookAt:=xlPart
- .Range("H:H").Replace What:="*|", Replacement:="", LookAt:=xlPart
- End With
- For i = 1 To UBound(arr, 2)
- tempVal = arr(5, i)
- '1 2 3 7 11
- For x = 1 To 3
- Worksheets("Sheet2").Cells(Val(Split(tempVal, "|")(0)) + 2, x).Resize(Val(Split(tempVal, "|")(1)), 1).Merge
- Next
- Worksheets("Sheet2").Cells(Val(Split(tempVal, "|")(0)) + 2, 7).Resize(Val(Split(tempVal, "|")(1)), 1).Merge
- Worksheets("Sheet2").Cells(Val(Split(tempVal, "|")(0)) + 2, 11).Resize(Val(Split(tempVal, "|")(1)), 1).Merge
- For x = 1 To 2
- tempVal = arr(x + 5, i)
- If tempVal <> "" Then
- Worksheets("Sheet2").Cells(Val(Split(tempVal, "|")(0)) + 2, x * 4).Resize(Val(Split(tempVal, "|")(1)), 1).Merge
- Worksheets("Sheet2").Cells(Val(Split(tempVal, "|")(0)) + 2, x * 4 + 1).Resize(Val(Split(tempVal, "|")(1)), 1).Merge
- Worksheets("Sheet2").Cells(Val(Split(tempVal, "|")(0)) + 2, x * 4 + 2).Resize(Val(Split(tempVal, "|")(1)), 1).Merge
- Exit For
- End If
- Next
- Next
- With Worksheets("Sheet2").Range("a3").Resize(dataRows, 11).Borders
- .LineStyle = xlContinuous
- .Weight = xlThin
- End With
- Application.ScreenUpdating = True
- Application.DisplayAlerts = True
- End Sub
复制代码 |
|