|
改成调用分班函数的算法:- Option Explicit
- Sub kagawa()
- Dim arr, xh, c&, i&, j&, k&, l&, m&, n&, t&, tms#
- tms = Timer '开始计时
- k = Sheets("分班").Range("g1") '获取分班数k
- Sheets("报名信息").Activate
- m = [a65536].End(3).Row - 2 '数据表有效行数m
- n = 17 '数据表有效列数n=17 (到Q列)
- Range("a3").Resize(m, n).Sort [c3], 1, [p3], , 2, , , 2 '按男女、总分 进行工作表倒序排序
- arr = Range("a3").Resize(m, n) '工作表排序后的数据读入数组arr
-
- ReDim brr(1 To k)
- ReDim crr(m \ k, 1 To n) '记录每个班信息的嵌套子数组
- For j = 1 To n
- crr(0, j) = Cells(2, j) '写入班级信息标题栏
- Next
- For j = 1 To k
- brr(j) = crr '嵌套数组初始化
- Next
-
- ReDim crr(1 To 10, 1 To 3)
- xh = bj(m, k) '对于排序后的学生数据表 直接调用分班函数得到分班班级序号
- For t = 1 To m Step k '按排序后的顺序 遍历原始数据各行
- i = i + 1 '插入各个班级是的当前行号
- For l = 0 To k - 1
- c = xh(t + l, 1)
- For j = 1 To n '第1-18列 照搬原始数据
- If j = 5 Or j = 10 Then brr(c)(i, j) = "'" & arr(t + l, j) Else brr(c)(i, j) = arr(t + l, j)
- Next
- If arr(t + l, 3) = "男" Then crr(c, 1) = crr(c, 1) + 1 Else crr(c, 2) = crr(c, 2) + 1
- crr(c, 3) = crr(c, 3) + arr(t + l, 16)
- Next
- Next
- MsgBox Format(Timer - tms, "0.000s") '172个学生分成5个班计算耗时约 0.03-0.04秒
- Range("a3").Offset(, n).Resize(m) = xh '在报名信息表最后一列输出现在的分班班序
-
- Sheets("分班").Range("c2:e11") = crr '分班后统计结果输出
- ' Stop
- '删去以前的工作表
- Application.DisplayAlerts = False
- For i = Sheets.Count To 3 Step -1
- Sheets(i).Delete
- Next
-
- '下面是新建工作表并逐个输出各班级结果
- For i = 1 To k
- Sheets.Add After:=Sheets(Sheets.Count)
- Sheets(Sheets.Count).Name = "班" & Right(0 & i, 2)
- Sheets(Sheets.Count).Range("a1").Resize(m \ k + 1, n) = brr(i)
- Next
- Sheets("分班").Activate
- End Sub
- Function bj(m&, k&) 'm个学生排序后 按错位法分班的函数过程
- '按班级错位分配: 12345 54321 23451 15432 34512 21543 45123 32154 51234 43215
- Dim i&, t&
- t = k ^ 2 * 2 '循环基数t
- ReDim a&(t - 1) '定义存放顺序循环结果的数组a
- For i = 0 To k - 1 '首先、生成第一组基数
- a(i) = i '升序 01234
- a(k * 2 - i - 1) = i '降序 43210
- Next
- '接下来 生成余下的基数
- For i = k * 2 To t - 1
- a(i) = (a(i - k * 2) + 1) Mod k '其实只是比第1组基数+1 然后求余即可
- Next
- For i = 0 To t - 1
- a(i) = a(i) + 1 '为提高效率 +1转换为 1开始的班级序号 01234 -> 12345
- Next
-
- '下面m个学生需要分班 则计算得到班级分配序号的一维数组
- ' ReDim b&(1 To m)
- ReDim b&(1 To m, 1 To 1) '或生成多行单列的二维数组以便直接输出结果到工作表
- For i = 1 To m
- ' b(i) = a((i - 1) Mod t)
- b(i, 1) = a((i - 1) Mod t)
- Next
-
- bj = b '这样得到一维或二维数组对应的分班序号结果数组bj
- End Function
复制代码 |
评分
-
1
查看全部评分
-
|