|
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件 ★ 免费下载 ★ ★ 使用帮助★
本帖最后由 一把小刀闯天下 于 2018-8-28 12:10 编辑
'"待调整名单"中有重名:132、282、307,,,
'因为使用姓名作匹配不得重名,所以做了重名检查
Option Explicit
Sub test()
Dim arr, brr, i, j, k, pos, t, cnt, min, s
s = "待调整名单"
arr = Sheets(s).[a1].CurrentRegion.Offset(1).Value
Call checkname(arr, 1, UBound(arr, 1) - 1, s) '检查重名
If Len(s) Then MsgBox s: Exit Sub
s = "分班名单"
With Sheets(s)
brr = .Range("a2:e" & .Cells(Rows.Count, "a").End(xlUp).Row + 1)
End With
Call checkname(brr, 1, UBound(brr, 1) - 1, s) '检查重名
If Len(s) Then MsgBox s: Exit Sub
For i = 1 To UBound(brr, 1) - 1: brr(i, 5) = vbNullString: Next
Call dsort(brr, 1, UBound(brr, 1) - 1, 4) '班级排序
pos = Array(4, 2, 3)
For i = 0 To UBound(pos) - 1 '性别、成绩排序
For j = 1 To UBound(brr, 1) - 1
For k = j To UBound(brr, 1) - 1
If brr(k, pos(i)) <> brr(k + 1, pos(i)) Then
Call dsort(brr, j, k, pos(i + 1)): j = k: Exit For
End If
Next k, j, i
For i = 1 To UBound(arr, 1) - 1
For j = 1 To UBound(brr, 1) - 1
If brr(j, 2) = arr(i, 2) And brr(j, 4) = arr(i, 5) Then '班级、性别相同
ReDim mark(1 To UBound(brr, 1), 1 To 2): cnt = 0
For k = j To UBound(brr, 1) - 1
If brr(k, 5) <> "R" Then '当前位置未换过
cnt = cnt + 1: mark(cnt, 2) = k
mark(cnt, 1) = Abs(arr(i, 3) - brr(k, 3))
End If
If brr(k + 1, 2) <> arr(i, 2) Then Exit For '性别不同退出
Next
If cnt = 0 Then MsgBox "未匹配成功:" & arr(i, 1): Exit Sub
min = mark(1, 1): pos = mark(1, 2)
For k = 1 To cnt '取分数最小偏差
If min > mark(k, 1) Then min = mark(k, 1): pos = mark(k, 2)
Next
For k = 1 To UBound(brr, 1) - 1
If brr(k, 1) = arr(i, 1) Then '姓名、分数对换
t = brr(pos, 1): brr(pos, 1) = brr(k, 1): brr(k, 1) = t '姓名
t = brr(pos, 3): brr(pos, 3) = brr(k, 3): brr(k, 3) = t '成绩
brr(pos, 5) = "R": Exit For
End If
Next
If k = UBound(brr, 1) Then MsgBox "分班名单中无此人" & arr(i, 1): Exit Sub
Exit For
End If
Next j, i
Call dsort(brr, 1, UBound(brr, 1) - 1, 5) '调换标志排序
With Sheets("NEW").[a2]
.Resize(Rows.Count - 1, UBound(brr, 2)).ClearContents
.Resize(UBound(brr, 1) - 1, UBound(brr, 2)) = brr
End With
End Sub
Function checkname(arr, first, last, s)
Dim dic, i
Set dic = CreateObject("scripting.dictionary")
For i = first To last
If dic.exists(arr(i, 1)) Then
s = s & "有重名:" & arr(i, 1): Exit Function
Else
dic(arr(i, 1)) = vbNullString
End If
Next
s = vbNullString
End Function
Function dsort(arr, first, last, key)
Dim i, j, k, t
For i = first To last - 1
For j = i + 1 To last
If arr(i, key) < arr(j, key) Then
For k = 1 To UBound(arr, 2)
t = arr(i, k): arr(i, k) = arr(j, k): arr(j, k) = t
Next
End If
Next j, i
End Function
|
|