|
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件 ★ 免费下载 ★ ★ 使用帮助★
- Option Explicit
- 'https://club.excelhome.net/thread-1691405-1-1.html
- Sub test1() '纯个人练习,可以分校分年级处理,但没有年级信息,这里当作同一年级
-
- Dim data, per, num() As Long
- Dim i As Long, j As Long, x As Long, y As Long
- Dim cnt As Long, pos As Long, col As Long, sum_ As Long
-
- per = Application.Rept(Worksheets("分值表").Range("B8:F8").Value, 1)
- ReDim num(LBound(per) To UBound(per))
-
- data = Worksheets("原始成绩").Range("A1").CurrentRegion.Offset(1).Value
- ReDim Preserve data(1 To UBound(data), 1 To UBound(data, 2) + 1)
-
- col = 2
- For j = 4 To UBound(data, 2) - 1
- col = col + 1
- For i = 1 To UBound(data) - 1
- data(i, col) = Replace(data(i, j), "缺考", "")
- Next
- Next
- col = col + 2
- data(1, col - 1) = "总分"
- For i = 2 To UBound(data) - 1
- data(i, col - 1) = ""
- data(i, col) = UBound(data) - i '最后一列写入降序序号,便于后面排序恢复原来顺序
- Next
-
- QuickSort data, 2, UBound(data) - 1, 1, col, 1, False '按校排序,若有序则不用
- For j = 4 To col - 2
- pos = 1
- For i = pos + 1 To UBound(data) - 1
- If data(i, 1) <> data(i + 1, 1) Then '判断学校
- cnt = 0
- sum_ = 0
- QuickSort data, pos + 1, i, 1, col, j, True '同一校内年级成绩降序
- For y = pos + 1 To i
- If Len(data(y, j)) Then cnt = cnt + 1 Else Exit For '计算有成绩人数
- Next
- For x = LBound(num) To UBound(num)
- num(x) = per(x) * cnt '计算有成绩人数内 各等级 人数,总数可能多也可能少(概率大于多)
- '用四舍五入 可能导致人数变多,这里四舍六入五单双 也可能导致人数变多,后面有处理
- sum_ = sum_ + num(x)
- Next
- If sum_ < cnt Then num(UBound(num)) = num(UBound(num)) + (cnt - sum_) '可能人数变少时加在最后一个等级中
- For x = LBound(num) To UBound(num) '按 各等级 人数 写入相应等级
- For y = pos + 1 To pos + num(x)
- data(y, j) = Chr(x + 64)
- data(y, col - 1) = data(y, col - 1) & Chr(x + 64)
- pos = pos + 1
- cnt = cnt - 1
- If cnt = 0 Then Exit For '处理可能 人数多于有效成绩数
- Next
- Next
- pos = i
- End If
- Next
- Next
-
- QuickSort data, 2, UBound(data) - 1, 1, col, col, True '按写入的序号降序排序,恢复原来顺序
- With Worksheets("成绩等级(效果)").Range("A2")
- .CurrentRegion.Offset(1).Clear 'Contents
- With .Resize(UBound(data) - 1, col - 1)
- .Borders.LineStyle = xlContinuous
- .HorizontalAlignment = xlCenter
- .Font.Name = "宋体"
- .Font.Size = 10
- .Value = data
- End With
- End With
-
- Beep
- End Sub
- Function QuickSort(ar, u As Long, d As Long, l As Long, r As Long, pCol As Long, Optional Flag As Boolean = True)
- Dim t As Long, b As Long, x As Long, pivot, swap
- t = u
- b = d
- pivot = ar((u + d) \ 2, pCol)
- While t <= b
- If Flag Then 'Order by number Descending
- Do
- If ar(t, pCol) > pivot Then t = t + 1 Else Exit Do
- Loop While t < d
- Do
- If ar(b, pCol) < pivot Then b = b - 1 Else Exit Do
- Loop While b > u
- Else 'Order by text Ascending
- Do
- If StrComp(ar(t, pCol), pivot, vbTextCompare) = -1 Then t = t + 1 Else Exit Do
- Loop While t < d 'vbTextCompare 1 vbBinaryCompare 0
- Do
- If StrComp(pivot, ar(b, pCol), vbTextCompare) = -1 Then b = b - 1 Else Exit Do
- Loop While b > u
- End If
- If t < b Then
- For x = l To r
- swap = ar(t, x): ar(t, x) = ar(b, x): ar(b, x) = swap
- Next
- t = t + 1: b = b - 1
- Else
- If t = b Then t = t + 1: b = b - 1
- End If
- Wend
- If t < d Then QuickSort ar, t, d, l, r, pCol, Flag
- If b > u Then QuickSort ar, u, b, l, r, pCol, Flag
- End Function
复制代码 |
评分
-
1
查看全部评分
-
|