更新:2014-04-18 下午
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
前言- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
代码
History: (代码修改历史记录列表)
1. Date:2013/10/6
Modification:部分注释错别字,解释错误的改动
2. Date:2013/10/10
Modification:科目名称超过15个字用8号字体
3. Date:2013/10/21
Modification:运行完后,弹出友情提示窗口
Sub 成绩表()
'Author:代号4101 首次发布:2013/10/6
Dim 行范围, 列范围, 有效范围, 计数, i, j, title, 总学分, logo, str
'去掉获得学分为0的行
i = 4
While Cells(i, 4) <> ""
If Cells(i, 4) = 0 Then
Rows(i).Delete Shift:=xlUp
Else
i = i + 1
End If
Wend
行范围 = i + 1 '这里有中间计算过程,算出的是最终确立的,最后条数据的行号
'完成行的确定
title = Cells(1, 1)
Rows(2).Delete Shift:=xlUp
Rows(2).Insert Shift:=xlDown
Rows("4:5").Insert Shift:=xlDown
'删除第一列与第四列
Columns(1).Delete Shift:=xlToLeft
Columns(3).Delete Shift:=xlToLeft
'去掉含不计入综测的科目
有效范围 = 2 * (i - 3) / 3
j = 3
While Cells(3, j) <> ""
计数 = 0
For i = 6 To 行范围
If Len(Cells(i, j)) Then
计数 = 计数 + 1
End If
Next
'①成绩比例小于2/3 ②形势与政策、专业导论等只分合格与不合格的不计入(该处采用不严密的算法,但出错,即定位的6位同学都没有出现“合格”字眼几乎是不可能事件)
If (计数 < 有效范围) Then
Columns(j).Delete Shift:=xlToLeft
ElseIf (Mid(Cells(6, j), 1, 2) = "合格") Or (Mid(Cells(10, j), 1, 2) = "合格") Or (Mid(Cells(20, j), 1, 2) = "合格") Then
Columns(j).Delete Shift:=xlToLeft
ElseIf (Mid(Cells(25, j), 1, 2) = "合格") Or (Mid(Cells(28, j), 1, 2) = "合格") Or (Mid(Cells(30, j), 1, 2) = "合格") Then
Columns(j).Delete Shift:=xlToLeft
Else
j = j + 1
End If
Wend
列范围 = j - 1
Range(Cells(1, 1), Cells(1, 列范围)).FormulaR1C1 = title '有个标题会没掉的BUG,不知道问题在哪,所以在此处补充回来
'提取出第三行的科目类型、科目名称、学分数据
Dim 第一个位置, 第二个位置, 长度 '找出斜杆的位置
For j = 3 To 列范围
i = 1
Cells(3, j).Select
While Mid(ActiveCell, i, 1) <> "/"
i = i + 1
Wend
第一个位置 = i
i = i + 1
While Mid(ActiveCell, i, 1) <> "/"
i = i + 1
Wend
第二个位置 = i
长度 = Len(ActiveCell)
Cells(2, j) = Mid(ActiveCell, 第一个位置 + 1, 第二个位置 - 第一个位置 - 1)
Cells(4, j) = Mid(ActiveCell, 第二个位置 + 1, 长度 - 第二个位置)
Cells(3, j) = Left(ActiveCell, 第一个位置 - 1)
Next
'下面是列交换,先按科目类别名降序排序,再按学分降序排序,完成列的交换
Range(Cells(2, 3), Cells(行范围, 列范围)).Select
ActiveSheet.Sort.SortFields.Clear
ActiveSheet.Sort.SortFields.Add Key:=Range(Cells(2, 3), Cells(2, 列范围)), _
SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal
ActiveSheet.Sort.SortFields.Add Key:=Range(Cells(4, 3), Cells(4, 列范围)), _
SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal
With ActiveSheet.Sort
.SetRange Range(Cells(2, 3), Cells(行范围, 列范围))
.Header = xlGuess
.MatchCase = False
.Orientation = xlLeftToRight
.SortMethod = xlPinYin
.Apply
End With
'第二行类别名相同合并
i = 3
While i <= 列范围
j = i + 1
While Cells(2, j) = Cells(2, i)
Cells(2, j).Clear
j = j + 1
Wend
If j = i + 1 Then
Cells(2, i).MergeCells = False
Else
Range(Cells(2, i), Cells(2, j - 1)).MergeCells = True
End If
i = j
Wend
'所有缺数据的地方用0分填充,考察课文本转为数值成绩
For i = 6 To 行范围
For j = 3 To 列范围
Cells(i, j).Select
If Len(ActiveCell) = 0 Then
Cells(i, j) = "0"
Else
Select Case ActiveCell
Case "优秀"
ActiveCell = 90
Case "良好"
ActiveCell = 80
Case "中等"
ActiveCell = 70
Case "及格"
ActiveCell = 60
Case "不及格"
ActiveCell = 50
End Select
End If
Next
Next
'再做些小修改后,进入下一个阶段
Cells(5, 1) = Cells(3, 1)
Cells(5, 2) = Cells(3, 2)
Cells(3, 1).Clear
Cells(3, 2).Clear
Cells(2, 1) = "课程类别"
Range(Cells(2, 1), Cells(2, 2)).MergeCells = True
Cells(3, 1) = "课程名称"
Range(Cells(3, 1), Cells(3, 2)).MergeCells = True
Range(Cells(4, 1), Cells(4, 2)).MergeCells = True
Range(Cells(1, 1), Cells(1, 列范围 + 3)).MergeCells = True
Cells(2, 列范围 + 1) = "加权平均分"
Cells(2, 列范围 + 2) = "学业基本分"
Cells(2, 列范围 + 3) = "排名"
Range(Cells(2, 列范围 + 1), Cells(4, 列范围 + 1)).MergeCells = True
Range(Cells(2, 列范围 + 2), Cells(4, 列范围 + 2)).MergeCells = True
Range(Cells(2, 列范围 + 3), Cells(4, 列范围 + 3)).MergeCells = True
'进入下一阶段
Dim 区域 As Range
i = 6
While Cells(i, 1) <> ""
i = i + 1
Wend
行范围 = i
i = 3
While Cells(4, i) <> ""
i = i + 1
Wend
列范围 = i + 3
'窗口拆分与冻结
Range("C5").Select
With ActiveWindow
.SplitColumn = 2
.SplitRow = 4
End With
ActiveWindow.FreezePanes = True
'前四行表头填充颜色
Range(Cells(1, 1), Cells(1, 列范围 - 1)).Select
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 16764108
.TintAndShade = 0
.PatternTintAndShade = 0
End With
Range(Cells(2, 1), Cells(4, 列范围 - 4)).Select
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 16764057
.TintAndShade = 0
.PatternTintAndShade = 0
End With
Range(Cells(2, 列范围 - 3), Cells(4, 列范围 - 1)).Select
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 13421619
.TintAndShade = 0
.PatternTintAndShade = 0
End With
'全表格单元格格式统一
Range(Cells(1, 1), Cells(行范围 - 1, 列范围 - 1)).Select
With Selection
.HorizontalAlignment = xlCenter
.VerticalAlignment = xlCenter
.WrapText = True
.Orientation = 0
.AddIndent = False
.IndentLevel = 0
.ShrinkToFit = False
.ReadingOrder = xlContext
End With
With Selection.Font
.Name = "微软雅黑"
.FontStyle = "常规"
.Size = 12
.Strikethrough = False
.Superscript = False
.Subscript = False
.OutlineFont = False
.Shadow = False
.Underline = xlUnderlineStyleNone
.TintAndShade = 0
.ThemeFont = xlThemeFontNone
End With
For i = 3 To 列范围 - 4
If Len(Cells(3, i)) < 16 Then
Cells(3, i).Font.Size = 10 '课程名称用10号字体
Else
Cells(3, i).Font.Size = 8 '课程名称大于15个字时用8号字体
End If
Next
For i = 3 To (列范围 - 1) '课程类别只有单科目时字体要缩小点,不然难看
If Cells(2, i).MergeCells = False Then
Cells(2, i).Font.Size = 10
End If
Next
'绘制网格线
Range(Cells(1, 1), Cells(行范围 - 1, 列范围 - 1)).Select
Selection.Borders(xlDiagonalDown).LineStyle = xlNone
Selection.Borders(xlDiagonalUp).LineStyle = xlNone
With Selection.Borders(xlEdgeLeft)
.LineStyle = xlContinuous
.ColorIndex = 0
.TintAndShade = 0
.Weight = xlThin
End With
With Selection.Borders(xlEdgeTop)
.LineStyle = xlContinuous
.ColorIndex = 0
.TintAndShade = 0
.Weight = xlThin
End With
With Selection.Borders(xlEdgeBottom)
.LineStyle = xlContinuous
.ColorIndex = 0
.TintAndShade = 0
.Weight = xlThin
End With
With Selection.Borders(xlEdgeRight)
.LineStyle = xlContinuous
.ColorIndex = 0
.TintAndShade = 0
.Weight = xlThin
End With
With Selection.Borders(xlInsideVertical)
.LineStyle = xlContinuous
.ColorIndex = 0
.TintAndShade = 0
.Weight = xlThin
End With
With Selection.Borders(xlInsideHorizontal)
.LineStyle = xlContinuous
.ColorIndex = 0
.TintAndShade = 0
.Weight = xlThin
End With
'再进行科目成绩格式标准化
For j = 3 To (列范围 - 4) Step 1
'先判断出该列是否为考察课,是则logo记为1,否则记为0
logo = 1
For i = 6 To (行范围 - 1) Step 1
If Cells(i, j) Mod 10 Then
logo = 0
Exit For
End If
Next i
If logo = 0 Then '如果为非考查课,使用条件格式,不小于90分的以紫色背景标记
Range(Cells(6, j), Cells(行范围 - 1, j)).Select
Selection.FormatConditions.Add Type:=xlCellValue, Operator:=xlGreater, _
Formula1:="=89.5"
Selection.FormatConditions(Selection.FormatConditions.Count).SetFirstPriority
With Selection.FormatConditions(1).Interior
.PatternColorIndex = xlAutomatic
.Color = 10498160
.TintAndShade = 0
End With
Selection.FormatConditions(1).StopIfTrue = False
End If
Next j
'科目成绩小于60分的红色背景标记
Range(Cells(6, 3), Cells(行范围 - 1, 列范围 - 4)).Select
Selection.FormatConditions.Add Type:=xlCellValue, Operator:=xlLess, _
Formula1:="=60"
Selection.FormatConditions(Selection.FormatConditions.Count).SetFirstPriority
With Selection.FormatConditions(1).Interior
.PatternColorIndex = xlAutomatic
.Color = 255
.TintAndShade = 0
End With
Selection.FormatConditions(1).StopIfTrue = False
Cells(4, 1).FormulaR1C1 = "=""学分/"" & SUM(R4C3:R4C" & (列范围 - 4) & ") & ""分"" " 'A4格的数据修正
'第六行同学的加权平均分,学业基本分,排名计算
Cells(6, 列范围 - 3).Select
str = "=(0"
For i = 3 To (列范围 - 4) Step 1
str = str & "+R4" & "C" & i & "*IF(" & "R[0]C[" & (i - 列范围 + 3) & "]<60,0," & "R[0]C[" & (i - 列范围 + 3) & "])"
Next i
str = str & ")/SUM(" & "R4C3:R4C" & (列范围 - 4) & ")"
Cells(6, 列范围 - 3).Select
ActiveCell.FormulaR1C1 = str
ActiveCell.Offset(0, 1).FormulaR1C1 = "=0.9*R[0]C[-1]"
ActiveCell.Offset(0, 2).FormulaR1C1 = "=RANK(R[0]C[-1],R6C" & (列范围 - 2) & ":R" & (行范围 - 1) & "C" & (列范围 - 2) & ",0)"
'公式复制,计算出所有成绩
Range(Cells(6, 列范围 - 3), Cells(6, 列范围 - 1)).Select
Selection.AutoFill Destination:=Range(Cells(6, 列范围 - 3), Cells(行范围 - 1, 列范围 - 1)), Type:=xlFillDefault
'行高、列宽的调整,若使用者觉得不美观,也可以自己修改下面的参数
Rows("1:1").RowHeight = 28.5
Rows("2:2").RowHeight = 21.75
Rows("3:3").RowHeight = 51
Rows("4:200").RowHeight = 16
Columns("A:A").ColumnWidth = 13
Columns("B:B").ColumnWidth = 8.38
str = "C:" & Chr(列范围 + 60)
Columns(str).ColumnWidth = 8.18
Columns(Chr(列范围 + 61) & ":" & Chr(列范围 + 62)).ColumnWidth = 11.25
Columns(Chr(列范围 + 61) & ":" & Chr(列范围 + 62)).NumberFormatLocal = "0.00000_);[红色](0.00000)" '加权平均值和学业基本分保留5位小数
Columns(Chr(列范围 + 63)).ColumnWidth = 6.5
'第五行设置筛选命令
Range(Cells(5, 1), Cells(5, 列范围 - 1)).AutoFilter
Cells(5, 3).Select
'工作表重命名
If Mid(title, 13, 1) = 1 Then
ActiveSheet.Name = "成绩表(上)"
Else
ActiveSheet.Name = "成绩表(下)"
End If
MsgBox "友情提示" & vbCrLf & _
"1、注意是否有同学含0分的科目,询问是否为缓考或免修。" & vbCrLf & _
"2、了解后,把0分改为特定的数值即可。加权平均分,学业基本分,排名都是用公式完成的,会自动更新。" & vbCrLf & _
"3、程序也不是万能的,如果遇到特殊情况,如交换生的成绩,要手动进行一些处理。"
End Sub
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
使用说明
文件下载:“测试数据.xlsm”
程序适用范围:对厦门理工教务系统给的原始成绩表,或其他来源,但具有相同排版的原始成绩表。
程序功能:对于每个班级的原始期末成绩表,自动完成综合测评中所需的“成绩表”,即获得综合测评中每位同学学业基本分及排名信息。
笔者使用软件:Microsoft Excel 2010
使用者需要了解的相关知识:①VBA,宏;②建议阅读下《学生手册》(厦门理工学院学生综合测评办法)第九条。要知道学业基本分是等于期末考试中,主要科目成绩的加权平均值乘以0.9得到的。学业基本分对综合测评总分起着主导作用。
注意事项:程序完成表格后,请仔细核对表格中成绩为0的地方,了解是否为缓考或免修,并直接改动对应地方的成绩,全表会自动更新。
使用方法基本介绍:下载 “测试数据.xlsm”文件,并打开,首界面如下