Sub 考场安排()
Application.ScreenUpdating = False
Dim ar As Variant, br As Variant, arr As Variant
Dim i As Long, r As Long, rs As Long
Dim d As Object, dc As Object
Set d = CreateObject("scripting.dictionary")
Set dc = CreateObject("scripting.dictionary")
tt = Timer
With Sheets("设置")
r = .Cells(Rows.Count, 4).End(xlUp).Row
If r < 2 Then MsgBox "请先设置考场号和考场人数!": End
ar = .Range("d1").Resize(r, 2)
mc = .[b1] & .[b2] & "学年度" & .[b3] & .[b4] & "考场安排表"
End With
With Sheets("考生数据")
rs = .Cells(Rows.Count, 1).End(xlUp).Row
If rs < 2 Then MsgBox "考生数据为空!": End
arr = .Range("a1").Resize(rs, 5)
End With
With Sheets("考场安排")
With .UsedRange.Offset(1)
.Value = Empty
.Borders.LineStyle = 0
End With
With .[a2].Resize(UBound(arr), UBound(arr, 2))
.Value = arr
End With
.[a2].Resize(UBound(arr), UBound(arr, 2) + 3).Borders.LineStyle = 1
.[f2].Resize(1, 3) = Array("考号", "考场号", "座位号")
br = .Range("a3").Resize(rs - 1, 8)
'使用Fisher-Yates洗牌算法随机打散
Randomize ' 初始化随机数生成器
For i = UBound(br) To 2 Step -1
s = Int((i - 1) * Rnd) + 1 '生成1到i-1的随机数
'交换行数据
For j = 1 To UBound(br, 2) '
temp = br(i, j)
br(i, j) = br(s, j)
br(s, j) = temp
Next j
Next i
.[a1] = mc
nn = 0: dc.RemoveAll
For i = 2 To UBound(br)
If Not d.exists(br(i, 4)) Then
nn = nn + 1
d(br(i, 4)) = nn
End If
Next i
For i = 2 To UBound(br)
br(i, 6) = d(br(i, 4))
d(br(i, 4)) = d(br(i, 4)) + d.Count
Next i
For i = 2 To UBound(br)
For s = i + 1 To UBound(br)
If br(i, 6) > br(s, 6) Then
For j = 1 To UBound(br, 2)
kk = br(i, j)
br(i, j) = br(s, j)
br(s, j) = kk
Next j
End If
Next s
If br(i, 5) "" Then dc(br(i, 5)) = i
Next i
m = 2
For i = 2 To UBound(ar)
If ar(i, 1) "" Then
s = 0
m = m - 1
For w = 1 To ar(i, 2) + 10
m = m + 1
If m > UBound(br) Then GoTo 20
If br(m, 5) = "" Then
s = s + 1
zf = Format(ar(i, 1), "00") & Format(s, "00")
If dc.exists(zf) Then
s = s + 1
Else
s = s
End If
If s > ar(i, 2) Then GoTo 10
br(m, 7) = Format(ar(i, 1), "00")
br(m, 8) = Format(s, "00")
br(m, 6) = br(m, 7) & br(m, 8)
Else
br(m, 6) = br(m, 5)
br(m, 7) = Left(br(m, 5), 2)
br(m, 8) = Right(br(m, 5), 2)
End If
Next w
10:
End If
Next i
20:
.Columns("A:H").NumberFormatLocal = "@"
.Range("a3").Resize(rs - 1, 8) = br
.Range("a2").Resize(rs, 8).Sort .[f2], 1, , , , , , 1 '按考号排序
.Columns(5).Delete
.Columns("F:G").HorizontalAlignment = xlHAlignCenter
.Activate
End With
Set d = Nothing
Set dc = Nothing
Application.ScreenUpdating = True
MsgBox "耗时:" & Format(Timer - tt, "0.00") & "秒!"
End Sub