你好,欢迎来到电脑编程技巧与维护杂志社! 杂志社简介广告服务读者反馈编程社区  
合订本订阅
 
 
您的位置:杂志经典 / 编程语言
利用宏实现成绩登记表
 

摘 要 本文介绍了在Word中使用“宏”技术实现对成绩登记表的自动计算,实现各种格式要求的方法。

关键字 宏,VBA,成绩登记表,计算

 

 

一、前言

成绩登记表是高校中每个任课老师在学期末都要统计填写的。通常的做法是先根据总成绩的计算要求,比如总成绩由平时成绩、实验成绩、期末考试成绩按教学大纲规定比例进行合计,利用Excel电子表格的计算功能,计算出总成绩。再将平时成绩、实验成绩、期末考试成绩等各项成绩粘贴到Word的成绩登记表中。这是一项繁琐费时的工作。特别当成绩登记表还有一些特殊处理要求:如考试课成绩以百分计,考查课成绩以“优”、“良”、“中”等标记;低于60分的成绩加方框;考试成绩低于某一分数的加阴影;统计各分数段成绩分布等处理时;虽然这些处理在ExcelWord中通过能通过一系列操作完成,但这些操作一则繁琐、费时,易出错;二则有些操作还是比较复杂,对于非计算机专业的老师要求过高,不易掌握。为此笔者在我校成绩登记表模板的基础上,使用“宏”技术实现了成绩登记表的成绩自动计算及其他各项处理要求。

二、处理要求

我校成绩登记表Word模板如图1和图2所示。

                                     1  成绩登记部分


2 成绩分布及总成绩构成比例

 

根据我校成绩登记表的填写要求,自动处理应具备的功能为:

1.    根据课程性质,输入学生成绩。可以输入分数、也可以输入等第;

2.    根据课程性质,计算学生期末总成绩。如果是考试课程,期末成绩为分数,如果是考查,则期末成绩是等级;

3.    对于各项不及格成绩,成绩上加方框;考试课程期末成绩小于45分,总成绩即为期末成绩,不再考虑其他成绩;并加上阴影;

4.    统计成绩分布;

5.    程序应放宽输入要求,对输入数据进行必要的检查,即程序应具有一定的健壮性,操作方便。

三、设计方案

设计方案是在基本不改变原来成绩登记表原有模板的基础上,利用Word提供的 “宏”,使用VBA,设计相应的程序,完成上述5项功能。

1.为方便操作,建立一自定义工具栏。建立过程如下:

使用Word “视图”菜单中的“工具栏”子菜单,自定义成绩统计工具栏并生成“成绩统计”和“帮助”2个按钮,在“工具”菜单中的“宏”子菜单中确定2个按钮对应的2个宏名,即宏的过程名。本例中宏名分别为calculatehelp,并确定将宏保存在本文档中。这样每次打开成绩登记表,该工具栏自行打开(如图3所示)。


3 自定义成绩统计工具栏

2.在成绩登记表上增加2个单选按钮,将其caption属性设置为“考试”、“考查”,用来确定课程性质。

3.设计calculate宏,calculate的主要功能如下:

确定课程性质;检查总成绩构成比例是否为100;初始化统计过程中使用的数组变量,表格字体字号,对齐方式等;对表中每个学生的成绩,调用自定义过程Score_Statistic,逐个统计并作相应处理;统计成绩分布。由于成绩分布百分比要求保留一位小数,因此需要对成绩分布的百分比作处理,保证各百分比之和为100

4.设计自定义过程Score_Statistic宏,Score_Statistic的主要功能如下:

从表格的单元格中取出学生的3项成绩调用Convert_Int函数进行数据转换;根据课程性质和总成绩构成的百分比计算期末总成绩;对学生的4项成绩进行格式处理:低于60分加框,考试课程期末总成绩低于45分加阴影、考查课总成绩以5级等第表示、缺考的成绩不作处理;根据期末总成绩进行各分数段人数累计;统计期末总成绩低于45分的人数;Score_Statistic的参数为为待处理的单元格的行列号。

四、操作过程

进入Word打开待处理的成绩登记表,确定考试性质、输入学生各项成绩的分数或等第、输入总成绩构成比例后,鼠标左击图3中的“成绩统计”按钮,即可进行成绩自动处理。

经过处理以后的成绩表如图4、图5和图6所示。


                              4  处理以后的考试课程成绩表


5  处理以后的考查课程成绩表


                                                   6 成绩分布

五、源代码

alculate宏代码

Private Sub calculate()

  Dim number_of_stu As Integer, i As Integer, j As Integer

  Dim student_id As String

  Dim fraction As Single

  exam_or_check = ThisDocument.OptionButton1.Value

  proportion(1) = Val(ThisDocument.Tables(1).Cell(33, 2).Range.Text)

  proportion(2) = Val(ThisDocument.Tables(1).Cell(33, 4).Range.Text)

  proportion(3) = Val(ThisDocument.Tables(1).Cell(33, 6).Range.Text)

  If proportion(1) + proportion(2) + proportion(3) <> 100 Then

    MsgBox "平时成绩:实验成绩:期末成绩三项之和不等于100", vbOKOnly, message_title

    Exit Sub

  End If

  number_of_stu = 0

  For i = 1 To 7: grade_proportion(1, i) = 0: grade_proportion(2, i) = 0: Next      '成绩分布初始化

  For i = 1 To 25

    ThisDocument.Tables(1).Cell(i + 1, 4).Range.Font.Size = 9    '设置字号

    ThisDocument.Tables(1).Cell(i + 1, 5).Range.Font.Size = 9

    ThisDocument.Tables(1).Cell(i + 1, 6).Range.Font.Size = 9

    ThisDocument.Tables(1).Cell(i + 1, 7).Range.Font.Size = 9

    ThisDocument.Tables(1).Cell(i + 1, 4).Range.ParagraphFormat.Alignment = wdAlignParagraphCenter 

'设置对齐方式

    ThisDocument.Tables(1).Cell(i + 1, 5).Range.ParagraphFormat.Alignment = wdAlignParagraphCenter

    ThisDocument.Tables(1).Cell(i + 1, 6).Range.ParagraphFormat.Alignment = wdAlignParagraphCenter

    ThisDocument.Tables(1).Cell(i + 1, 7).Range.ParagraphFormat.Alignment = wdAlignParagraphCenter

    student_id = Trim(ThisDocument.Tables(1).Cell(i + 1, 2).Range.Text)     '取学号

    If Len(student_id) > 2 Then      '计算成绩表左侧成绩

      number_of_stu = number_of_stu + 1

      Call Score_Statistic(i, 4)

    End If

    ThisDocument.Tables(1).Cell(i + 1, 11).Range.Font.Size = 9

    ThisDocument.Tables(1).Cell(i + 1, 12).Range.Font.Size = 9

    ThisDocument.Tables(1).Cell(i + 1, 13).Range.Font.Size = 9

    ThisDocument.Tables(1).Cell(i + 1, 14).Range.Font.Size = 9

    ThisDocument.Tables(1).Cell(i + 1, 11).Range.ParagraphFormat.Alignment = wdAlignParagraphCenter

    ThisDocument.Tables(1).Cell(i + 1, 12).Range.ParagraphFormat.Alignment = wdAlignParagraphCenter

    ThisDocument.Tables(1).Cell(i + 1, 13).Range.ParagraphFormat.Alignment = wdAlignParagraphCenter

    ThisDocument.Tables(1).Cell(i + 1, 14).Range.ParagraphFormat.Alignment = wdAlignParagraphCenter

    student_id = Trim(ThisDocument.Tables(1).Cell(i + 1, 9).Range.Text)     '取学号

    If Len(student_id) > 2 Then     '计算成绩表右侧成绩

      number_of_stu = number_of_stu + 1

      Call Score_Statistic(i, 11)

    End If

  Next i

  If number_of_stu = 0 Then MsgBox "没有学生成绩数据", vbExclamation + vbOKOnly, message_title: Exit Sub

  '计算成绩分布

  fraction = 100

  For i = 1 To 7

  If grade_proportion(1, i) > 0# Then

  grade_proportion(2, i) = Round(grade_proportion(1, i) / number_of_stu * 100, 1)

  If i < 7 Then fraction = fraction - grade_proportion(2, i): j = i   '考试课程卷面成绩<45

`不用调整百分比

    Else

    grade_proportion(2, i) = 0

    End If

  Next

  '百分比调整为100%

  If Abs(fraction) >= 0.05 Then grade_proportion(2, j) = Round(grade_proportion(2, j) + fraction, 1)

  For i = 1 To 7

    ThisDocument.Tables(1).Cell(31, i + 1).Range.Text = grade_proportion(1, i)

    ThisDocument.Tables(1).Cell(32, i + 1).Range.Text = grade_proportion(2, i)

  Next

  MsgBox "成绩登记完毕,请检查", vbOKOnly, message_title

End Sub

 

'Score_Statistic自定义过程代码

Private Sub Score_Statistic(ByVal row As Integer, ByVal column As Integer)

Dim grade(3) As Single, total As Single

With ThisDocument.Tables.Item(1)

'调用自定义函数Convert_Int进行字符型数据到数值型数据转换

If Len(Trim(.Cell(row + 1, column + 2).Range.Text)) = 2 Then    '缺考

    .Cell(row + 1, column + 3).Range.Text = "缺考"

    grade(1) = Convert_Int(.Cell(row + 1, column).Range.Text)        '平时成绩

    grade(2) = Convert_Int(.Cell(row + 1, column + 1).Range.Text)     '实验成绩

    grade(3) = -1

    total = -1                                                     

  Else                                                       '不缺考

    grade(1) = Convert_Int(.Cell(row + 1, column).Range.Text)        '平时成绩

    grade(2) = Convert_Int(.Cell(row + 1, column + 1).Range.Text)     '实验成绩

    grade(3) = Convert_Int(.Cell(row + 1, column + 2).Range.Text)   '期末成绩

    '期末考试成绩小于45,总成绩为期末考试成绩

    If exam_or_check Then                                   '考试

      total = IIf(grade(3) < 45, grade(3), Round((grade(1) * proportion(1) + grade(2) * proportion(2) + grade(3) * proportion(3)) / 100, 0))

      .Cell(row + 1, column + 3).Range.Text = total

    Else                                                    '考查

      total = Round((grade(1) * proportion(1) + grade(2) * proportion(2) + grade(3) * proportion(3)) / 100, 0)

      .Cell(row + 1, column + 3).Range.Text = IIf(total >= 90, "", IIf(total >= 80, "", IIf(total >= 70, "", IIf(total >= 60, "及格", IIf(total >= 0, "不及格", "")))))

    End If

  End If

  '各项成绩小于60分加框

  .Cell(row + 1, column).Range.Font.Borders.Enable = IIf(grade(1) >= 0 And grade(1) < 60, True, False)

  .Cell(row + 1, column + 1).Range.Font.Borders.Enable = IIf(grade(2) >= 0 And grade(2) < 60, True, False)

  .Cell(row + 1, column + 2).Range.Font.Borders.Enable = IIf(grade(3) >= 0 And grade(3) < 60, True, False)

  .Cell(row + 1, column + 3).Range.Font.Borders.Enable = IIf(total >= 0 And total < 60, True, False)

  '期末考试成绩小于45,加阴影

  If exam_or_check Then

    .Cell(row + 1, column + 3).Range.Shading.BackgroundPatternColor = IIf(grade(3) >= 0 And grade(3) < 45, wdColorGray20, wdColorWhite)

  Else

    .Cell(row + 1, column + 3).Range.Shading.BackgroundPatternColor = wdColorWhite

  End If

  '统计成绩分布

  Select Case total

    Case Is >= 90                                           '优秀

      grade_proportion(1, 1) = grade_proportion(1, 1) + 1

    Case Is >= 80                                           '良好

      grade_proportion(1, 2) = grade_proportion(1, 2) + 1

    Case Is >= 70                                           '中等

      grade_proportion(1, 3) = grade_proportion(1, 3) + 1

    Case Is >= 60                                           '及格

      grade_proportion(1, 4) = grade_proportion(1, 4) + 1

    Case Is >= 0                                            '不及格

      grade_proportion(1, 5) = grade_proportion(1, 5) + 1

    Case Else                                               '缺考

      grade_proportion(1, 6) = grade_proportion(1, 6) + 1

  End Select

  '统计考试课程卷面成绩小于45

  If exam_or_check Then

    If grade(3) >= 0 And grade(3) < 45 Then

      grade_proportion(1, 7) = grade_proportion(1, 7) + 1

    End If

  End If

  End With

End Sub

 

自定义函数Convert_Int代码:

Private Function Convert_Int(ByRef Txt As String) As Integer

  Dim Score As String * 1

  If Asc(Txt) > 0 Then                        '数字

    Convert_Int = Val(Txt)

  Else                                    

    Score = Txt

    Convert_Int = IIf(Score = "", 95, IIf(Score = "", 85, IIf(Score = "", 75, IIf(Score = "", 65, 55))))

  End If

End Function

 

`全局变量声明

Option Base 1

Option Explicit

Dim exam_or_check As Boolean

Dim grade_proportion(2, 7) As Single

Dim proportion(3) As Integer

Private Const Message_Title = "江苏技术师范学院学生成绩登记系统"

 

  推荐精品文章

·2024年9月目录 
·2024年8月目录 
·2024年7月目录 
·2024年6月目录 
·2024年5月目录 
·2024年4月目录 
·2024年3月目录 
·2024年2月目录 
·2024年1月目录
·2023年12月目录
·2023年11月目录
·2023年10月目录
·2023年9月目录 
·2023年8月目录 

  联系方式
TEL:010-82561037
Fax: 010-82561614
QQ: 100164630
Mail:gaojian@comprg.com.cn

  友情链接
 
Copyright 2001-2010, www.comprg.com.cn, All Rights Reserved
京ICP备14022230号-1,电话/传真:010-82561037 82561614 ,Mail:gaojian@comprg.com.cn
地址:北京市海淀区远大路20号宝蓝大厦E座704,邮编:100089