一、概述 1、 项目背景 当今时代是飞速发展的信息时代。在各行各业中离不开信息处理,这正是计算机被广泛应用于信息管理系统的环境。计算机的最大好处在于利用它能够进行信息管理。使用计算机进行信息控制,不仅提高了工作效率,而且大大的提高了其安全性。 尤其对于复杂的信息管理,计算机能够充分发挥它的优越性。计算机进行信息管理与信息管理系统的开发密切相关,系统的开发是系统管理的前提。目前随着个大高校的扩招,在校学生数量庞大。拥有一款好的学习成绩管理系统软件,对于加强对在校生的成绩管理起到积极作用。并且,可以为在校生随时查阅自己的成绩信息、教师录入成绩、管理员进行信息维护等提供方便,为学校节省大量人力资源本系统就是为了管理好学生成绩信息而设计的。 2、 编写目的 首先,学生成绩管理是一个学校不可缺少的部分,它的内容对于学校的管理者和学生以及学生家长来说都至关重要,所以一个良好的学生成绩管理系统应该能够为用户提供充足的信息和快捷的查询手段。学生成绩管理系统对学校加强学生成绩管理有着极其重要的作用. 作为计算机应用的一部分,使用计算机对学生成绩信息进行管理,具有手工管理所无法比拟的优点。例:检索迅速、查找方便、可靠性高、存储量大、保密性好、寿命长、成本低等。这些优点能够极大地提高管理者管理的效率,也是学校走向科学化、正规化管理,与世界接轨的重要条件。 因此,开发设计这样一套学生成绩管理软件成为很有必要的事情。其次,初步掌握软件开发的流程,熟悉delphi与SQL的使用方法,达到能够较好的运用两者制成能实现初步功能的管理系统,锻炼自己的动手能力,同时,在合作中更好的与同学交流,这些都是必要的。最后,自己动手编程序,能更好的提升对本专业的爱好,初步了解本专业的发展方向,为将来的毕业与找工作奠定基础。 3、 软件定义 该学生管理管理信息系统是基于Internet/Intranet 及C 技术,建立以以数据库为后台核心应用、以服务为目的信息平台,对资源进行科学的加工整序和管理维护,为教学和科学研究提供文献信息保障和提高管理学生成绩的效率而设计的系统。 4、 开发环境 本系统采用,XP作为操作平台,前台开发工具采用delphi7.0,数据库管理采用SQL SERVER 2008。 二、需求分析 1、 问题的提出 为了提高高校学生成绩信息的管理效率,方便学生和教师对学生成绩信息进行查询、方便学校里面管理员去管理和查询学生信息,建立一个学生成绩管理系统,使学生信息管理工作规范化,系统化,程序化,避免学生成绩管理的随意性,提高信息处理的速度和准确性,能够及时、准确、有效的查询和修改学生信息是必须而且十分迫切的工作。本次课程设计题目为《学生成绩管理系统》,涉及成绩管理系统的登录界面、老师对学生成绩的查询、学生对学生成绩的查询、教务员对学生成绩的增删改查统计等内容。本功能实现对学生信息、教师信息情况信息的管理和统计、课程信息和成绩信息查看及维护。 2、系统的业务功能分析 学生成绩管理系统应当将学生与教务员区分开来,因为增、删、改、统计的权限应当只有教务员才拥有,学生只能查询与自己相关的记录,老师查询自己所授课程的记录,而教务员则录入数据,进行增删改与统计。另外,在日常学习生活中,为了方便老师和同学了解情况,需要提供平均分、最高(低)分、排名等供老师和学生查询。 具体分析:按照教师,学生,管理员三种角色设计系统功能。 ①学生要能够查询自己所学课程的成绩,查看自己不同课程的成绩、GPA以及排名,查看个人信息、修改个人登录密码等。 ②教师要实现对自己所教授课程中所有学生成绩的查询、以及对自己所教班上同学的各分数段成绩单人数成绩的查询(排序功能),个人资料的修改和修改个人登录密码等。 ③管理员要能够实现对管理员、教师、学生基本信息的增加、删除、修改、查询以及实现对学生成绩的增加、删除(按学号、按班级、按课程号、按院系)、修改、查询(按学号、按班级、按课程号、按院系)和数据统计分析以及对结果提供打印功能等。 3、系统业务流程分析 个人信息修改密码 4、完成的功能 系统的功能模块划分 《学生成绩管理系统》包括八个模块:系统登录、学生基本信息管理、教师基本信息管理、管理员基本信息管理、学生成绩信息查询、学生成绩信息管理,学生成绩信息统计,系统退出。 1、系统登录模块 (1)用户人员在登录界面中输入用户名与密码。 (2)通过用户名与数据库里的用户表相比配,将学生、教师与管里员区分开,三者各自进入自己的页面,初始密码为:000000,登录成功后,可以修改密码。 (3)三者拥有各自权限,分别拥有不同的功能。 2、学生基本信息管理:管理员对所有学生信息进行增删改查,学生只能查询自己的基本信息。 3、教师基本信息管理:管理员对所有教师信息进行增删改查,学生只能查询自己的基本信息。 4、管理员基本信息管理:管理员对所有管理员信息进行增删改查。 5、学生成绩信息查询:管理员查询功能:可以按学号、班级、院系、教师工号等对学生成绩分别进行查询、查某门课程的排名、最高分、最低分、绩点、不及格人数等、查某班级某科目分数段的人数。教师查询功能:查询所教课程的最高分、最低分、各分数段人数、不及格人数等。学生查询功能:查某学生所学课程的排名、最高分、最低分、绩点、不及格人数等。 6、学生成绩信息管理:管理员对学生成绩进行增删改查。 7、学生成绩信息统计:按学号、班级、院系、教师工号等分别进行统计,并对结果提供打印能。 8、退出程序:退出该程序。 9、数据流程图 数据流图 10、数据字典 (1).数据流 ①院信息,包括学院编号,学院名称等信息。 ②班级信息,包括班级编号,学院编号等信息。 ③生信息,包括学生编号,学生姓名,性别,班级,联系方式等信息。 ④教师信息,包括教师工号,教师姓名,性别,学院编号,联系方式等信息。 ⑤管理员信息,包括管理员编号,管理员姓名,性别等信息。 ⑥用户信息,包括用户名,登录密码等信息。 ⑦课程信息,包括课程号,课程名称,学分,学时,教师工号等信息。 (2).数据存储 绩表信息,包括学生编号,课程编号,课程绩点,课程成绩等信息。 课程安排信息,包括课程编号,课程名称,教师工号等信息。 三、系统设计 、数据表: (1)、数据库的关系模式: (sno, sname, sex, classno, departed, phone); teacher(tno, tname, departid, sex, phone); course(cno, cname, credit, ctime, tno); score(sno, sname, cno, cname, grade, GPA); administror(adminino,adimniname,sex); department(departed, departname); class(departed, classno, classname); user(userno,password); (2)、表的物理设计: 表一学生信息表student table student( sno char(10) primary key, char(20) not null default ‘Noname’, sex char(10) not null , char(10) foreign key references class(classno) , departid char(10) foreign key references department(departid), phone char(20) ); 表二教师信息表teacher Create table student( tno char(10) primary key, char(10) not null default ‘Noname’ , sex char(10) not null , char(10) forgein key refrences department(departid), phone char(20) ); 表三课程信息表course table student( cno char(10) , cname char(20) not null, credi char(10) not null , char(10) not null, tno char(10) , primary key(cno, tno) ); 表四学生成绩表score Create table score ( sno char(10), sname char(20) not null, cno char(10), cname char(20) not null, Score char(10) not null, GPA float, primary key(sno,cno) ); 表五管理员信息表administror Create table student( char(10) primary key, char(20) not null default ‘Noname’, sex char(10) not null ); 表六院系表department table student( char(10) primary key, departname char(20) not null ); 表七班级表class table class ( char(10) foreign key references department(departid), classno char(10)primary key , classname char(10) not null); 表八用户表user Create table user( char(10) primary key, password char(6)not null ); 2、视图,索引,数据库权限:这些在这个学生成绩管理系统中没有用到。 3、软件功能设计 (1)、系统的结构图 显示制作人和版本 (2)、功能表: (3)、功能描述:同功能表。 四、系统实施 (1)、系统的界面设计: 1、登陆界面 2、密码修改 3、个人信息 4、操作页面 5、信息管理 6、成绩查询 7、成绩管理 8、成绩统计 (2)、事件的设计过程: ②行软件进入主界面,在主界面登录进入各自操作主界面。 ③生登录后可在登录界面进行成绩查询、个人信息查询及密码修改。 ③教师登录后可在登录界面进行功能选择来完成自己所选择的查询与维护。 ④管理员登录后可在登录界面点击各页面标签选择功能进入相应页面。 (3)、主要代码描述: 1、登录 TfrmLogin.btnOKClick(Sender: TObject); var sSQL: string; begin Trim(Edit1.Text) = '' then begin _MessageBox('请填写用户名!', MB_OK); Edit1.SetFocus; Exit; end else Trim(Edit2.Text) = '' then begin _MessageBox('请填写密码!', MB_OK); Edit2.SetFocus; Exit; end; := iErrorCount 1; := 'select ' ' from [user] a ' ' left join (select tno,tname,1 as UserType from teacher ' ' union all ' ' select sno,sname,2 from student ' ' union all ' ' select adminino,admininame,0 from administror) b on erno = b.tno ' ' where erno = ' QuotedStr(Trim(Edit1.Text)) ' and a.password = ' QuotedStr(Trim(Edit2.Text)); gf_OpenSQL(sSQL, DM.aqPublic); if DM.aqPublic.IsEmpty then begin iErrorCount >= 3 then begin _MessageBox('账号或密码错误三次,程序自动关闭!',MB_OK); Application.Terminate; end; _MessageBox('账号或密码错误,请重试!还剩' IntToStr(3 - iErrorCount) '次将自动关闭程序!',MB_OK); Edit1.SelectAll; Edit1.SetFocus; end else begin _LoginUser.sUserID := DM.aqPublic.FieldByName('userno').AsString; gr_LoginUser.sUserName :=DM.aqPublic.FieldByName('tname').AsString; gr_LoginUser.iType := DM.aqPublic.FieldByName('usertype').AsInteger; SetLoginInfo; Self.Hide; .CreateForm(TfrmStuSource, frmStuSource); case gr_LoginUser.iType of 0: .sbMain.Panels[0].Text := '工号:' gr_LoginUser.sUserID; .sbMain.Panels[1].Text := '姓名:' gr_LoginUser.sUserName; .sbMain.Panels[2].Text := '登录身份:管理员'; end; 1: .S1.Visible := False; frmStuSource.N3.Visible := False; frmStuSource.N10.Visible := False; .sbMain.Panels[0].Text := '工号:' gr_LoginUser.sUserID; .sbMain.Panels[1].Text := '姓名:' gr_LoginUser.sUserName; .sbMain.Panels[2].Text := '登录身份:教师'; end 2: .S1.Visible := False; frmStuSource.N10.Visible := False; frmStuSource.N11.Visible := False; .sbMain.Panels[0].Text := '学号:' gr_LoginUser.sUserID; .sbMain.Panels[1].Text := '姓名:' gr_LoginUser.sUserName; .sbMain.Panels[2].Text := '登录身份:学生'; end; end; .ShowModal; end; end; TfrmLogin.FormShow(Sender: TObject); begin:= 0; TfrmLogin.Edit1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin Key = 13 then Edit2.SetFocus; end; TfrmLogin.Edit2KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin Key = 13 then (Sender); end; 2、修改密码 TfrmChangPwd.ChangePwd: Boolean; var : string; ,NewPwd: string; begin:= True; Trim(edtNewPwd1.Text) = Trim(edtNewPwd2.Text) then begin _MessageBox('两次输入的新密码不相同',MB_OK); edtNewPwd2.SetFocus; Result := False; Exit; end; := Trim(edtOldPsw.Text); NewPwd := Trim(edtNewPwd1.Text); := 'update [user] set password = ' QuotedStr(NewPwd) ' where userno = ' QuotedStr(gr_LoginUser.sUserID); gf_ExecSQL(sSQL,DM.aqSQL); end; TfrmChangPwd.btnOKClick(Sender: TObject); begin not ChangePwd then begin _MessageBox('密码修改成功!', MB_OK); Exit; end; end; 、查询数据 TfrmScoreMange.SearchData; sSQL: string; begin sSQL := 'select a.sno,a.sname,b.sex,b.phone,o,ame,a.score,a.GPA,d.departname,c.classname ' ' from score a ' ' left join student b on a.sno = b.sno ' ' left join class c on b.classno = c.classno ' ' left join department d on b.departid = d.departid ' ' where 1 = 1'; gr_LoginUser.iType of 0: end; 1: := sSQL ' and exists(select 1 from course where cno = o and tno = ' QuotedStr(gr_LoginUser.sUserID) ')'; end; 2: := sSQL ' and a.sno = ' QuotedStr(gr_LoginUser.sUserID); end; end; Trim(edtSNo.Text) '' then:= sSQL ' and a.sno = ' QuotedStr(Trim(edtSNo.Text)); if Trim(edtSName.Text) <> '' then:= sSQL ' and a.sName = ' QuotedStr(Trim(edtSName.Text)); if Trim(edttno.Text) <> '' then:= sSQL ' and exists(select * from course where cno = o and tno = ' QuotedStr(Trim(edttno.Text)) ')'; if Trim(cbxSDepart.Text) <> '全部' then:= sSQL ' and d.departname = ' QuotedStr(Trim(cbxSDepart.Text)); Trim(cbxSClass.Text) <> '全部' then:= sSQL ' and c.ClassName = ' QuotedStr(Trim(cbxSClass.Text)); gf_OpenSQL(sSQL, aqMaster); end; 4、增加记录 parprocedure TfrmScoreMange.AddData; var sSQL: string; fScore: Double; begin Trim(edtNo.Text) = '' then begin _MessageBox('插入数据时未填写学号!',MB_OK); edtNo.SetFocus; Exit; end else Trim(edtName.Text) = '' then begin_MessageBox('插入数据时未填写姓名!',MB_OK); edtName.SetFocus; Exit; end else Trim(edtCourse.Text) = '' then begin_MessageBox('插入数据时未填写课程号!',MB_OK); edtCourse.SetFocus; Exit; end else Trim(edtCourseName.Text) = '' then begin _MessageBox('插入数据时未填写课程名称!',MB_OK); edtCourseName.SetFocus; Exit; end else Trim(edtScore.Text) = '' then begin _MessageBox('插入数据时未填写成绩!',MB_OK); edtScore.SetFocus; Exit; end else Trim(edtGPA.Text) = '' then begin _MessageBox('插入数据时未填写平均绩点!',MB_OK); edtGPA.SetFocus; Exit; end; if not TryStrToFloat(Trim(edtScore.Text),fScore) then begin_MessageBox('成绩输入不合法,请重输!',MB_OK); edtScore.SetFocus; Exit; end else not TryStrToFloat(Trim(edtGPA.Text),fScore) then begin_MessageBox('平均绩点输入不合法,请重输!',MB_OK); edtGPA.SetFocus; Exit; end; gf_MessageBox('是否新增所输数据?',MB_YESNO MB_ICONWARNING) = IDNO then Exit; := sSQL 'insert into score(sno,sname,cno,cname,score,GPA)' ' values(%s,%s,%s,%s,%s,%s)'; sSQL := Format(sSQL,[QuotedStr(Trim(edtNo.Text)),QuotedStr(Trim(edtName.Text)),QuotedStr(Trim(edtCourse.Text)) ,QuotedStr(Trim(edtCourseName.Text)),QuotedStr(Trim(edtScore.Text)),QuotedStr(Trim(edtGPA.Text))]); try _ExecSQL(sSQL,aqPublic); except E: Exception do begin_MessageBox('保存数据发生错误。错误信息:' E.Message,MB_OK); end; end; ; end; 、删除记录 TfrmScoreMange.DelData; var sSQL: string; begin (aqMaster.IsEmpty) or (not aqMaster.Active) then begin _MessageBox('没有数据可以删除!',MB_OK MB_ICONWARNING); Exit; end; gf_MessageBox('删除数据后将不能恢复,是否删除?',MB_YESNO MB_ICONWARNING) = IDNO then Exit; sSQL := 'delete from score where sno = ' QuotedStr(aqMaster.FieldByName('sno').AsString) ' and cno = ' QuotedStr(aqMaster.FieldByName('cno').AsString); gf_ExecSQL(sSQL,aqPublic); SearchData; end; 、修改记录 TfrmScoreMange.EditData; var: string; sno: string; begin (aqMaster.IsEmpty) or (not aqMaster.Active) then begin_MessageBox('没有数据可以修改!',MB_OK MB_ICONERROR); Exit; end; := aqMaster.FieldByName('sno').AsString; := 'update score set sno = %s,sname = %s, cno = %s, cname = %s, score = %s, GPA = %s where sno = ' QuotedStr(aqMaster.FieldByName('sno').AsString) ' and cno = ' QuotedStr(aqMaster.FieldByName('cno').AsString); sSQL := Format(sSQL,[QuotedStr(Trim(edtNo.Text)),QuotedStr(Trim(edtName.Text)),QuotedStr(Trim(edtCourse.Text)) ,QuotedStr(Trim(edtCourseName.Text)),QuotedStr(Trim(edtScore.Text)),QuotedStr(Trim(edtGPA.Text))]); try _ExecSQL(sSQL,aqPublic); except E: Exception do begin _MessageBox('修改数据发生错误。错误信息:' E.Message,MB_OK); end; end; .Locate('sno',sno,[]); end; 7、统计 TfrmScoreStat.StatData(iType: Integer); var: string; sCondition 2: string; i: Integer; begin i := 0 to dgMaster.Columns.Count - 1 do dgMaster.Columns[i].Visible := True; := ' from score a ' ' left join student b on a.sno = b.sno ' ' left join class c on b.classno = c.classno ' ' left join department d on b.departid = d.departid '; case iType of 1: := 'select a.sno,a.sname,c.classname,d.departname,o,ame,max(a.score) as MaxScore, ' ' min(a.score) as MinScore,convert(decimal(18,2),avg(convert(float,a.score))) as avgScore, ' ' sum(case when convert(float,a.score) <60 then 0 else 1 end) as Fail '; := ' group by a.sno,a.sname,c.classname,d.departname,o,ame'; end; 2: .Columns[0].Visible := False; dgMaster.Columns[1].Visible := False; sCondition1 := 'select c.classname,d.departname,o,ame,max(a.score) as MaxScore, ' ' min(a.score) as MinScore,convert(decimal(18,2),avg(convert(float,a.score))) as avgScore, ' ' sum(case when convert(float,a.score) <60 then 0 else 1 end) as Fail '; := ' group by c.classname,d.departname,o,ame'; end; 3: .Columns[0].Visible := False; dgMaster.Columns[1].Visible := False; dgMaster.Columns[2].Visible := False; sCondition1 := 'select d.departname,o,ame,max(a.score) as MaxScore, ' ' min(a.score) as MinScore,convert(decimal(18,2),avg(convert(float,a.score))) as avgScore, ' ' sum(case when convert(float,a.score) <60 then 0 else 1 end) as Fail '; := ' group by d.departname,o,ame'; end; 4: .Columns[0].Visible := False; dgMaster.Columns[1].Visible := False; dgMaster.Columns[2].Visible := False; dgMaster.Columns[3].Visible := False; := 'select o,ame,max(a.score) as MaxScore, ' ' min(a.score) as MinScore,convert(decimal(18,2),avg(convert(float,a.score))) as avgScore, ' ' sum(case when convert(float,a.score) <60 then 0 else 1 end) as Fail '; := ' group by o,ame'; end; end; := sCondition1 sSQL sCondition2; _OpenSQL(sSQL, aqMaster); end; 8、打印 CopyDbDataToExcel(Args: array of const); var, jCount: Integer; XLApp: Variant; Sheet: Variant; I: Integer; begin.Cursor := crHourGlass; if not VarIsEmpty(XLApp) then begin .DisplayAlerts := False; XLApp.Quit; (XLApp); end; XLApp := CreateOleObject('Excel.Application'); except .Cursor := crDefault; Exit; end; .WorkBooks.Add; .SheetsInNewWorkbook := High(Args) 1; I := Low(Args) to High(Args) do begin .WorkBooks[1].WorkSheets[I 1].Name := TDBGrid(Args[I].VObject).Name; Sheet := XLApp.Workbooks[1].WorkSheets[TDBGrid(Args[I].VObject).Name]; not TDBGrid(Args[I].VObject).DataSource.DataSet.Active then begin .Cursor := crDefault; Exit; end; (Args[I].VObject).DataSource.DataSet.first; iCount := 0 to TDBGrid(Args[I].VObject).Columns.Count - 1 do Sheet.Cells[1, iCount 1] := (Args[I].VObject).Columns.Items[iCount].Title.Caption; := 1; not TDBGrid(Args[I].VObject).DataSource.DataSet.Eof do begin iCount := 0 to TDBGrid(Args[I].VObject).Columns.Count - 1 do begin .Cells[jCount 1, iCount 1] := (Args[I].VObject).Columns.Items[iCount].Field.AsString; end; (jCount); (Args[I].VObject).DataSource.DataSet.Next; end; .Visible := True; end; .Cursor := crDefault; end; 五、系统测试 (1)、给出单元测试的测试用例: 1、按教师工号查询 2、按学号查询 3、按班级查询 4、新增数据 5、删除数据 6、统计 (2)、给出系统测试的测试用例: 1、登录用户名或密码错误 2、修改密码 两次密码不一致修改成功 六、收获和体会 一次软件设计带给我们的收获很多很多,想着刚接触delphi时的茫然无知到现在可以做出的成品的进步,带给我们的不仅仅是高兴,更多的是收获知识的满足。 学习成绩管理系统时一个与我们息息相关的软件系统,如何把它做好是一个难题。作为学生,很容易知道作为学生应该拥有的权限,然而对于教师、管理员的职权我们却是似懂非懂。通过我们小组人员的讨论,分析最终确定了他们的职权,完成他们的功能。 通过对这次学习成绩管理系统的设计,我们明白了创建一个小型管理系统的流程与步骤。判断一个管理系统的好坏,最重要的一个依据就是看这个系统是否满足用户的需求。所以首先进行一个系统的需求分析至关重要。我们要站在用户的角度分析什么功能是常用的,什么功能时重要的,什么功能时次要的,我们要根据实际的情况调整按钮的排列顺序,功能实现的复杂程度和所耗系统内存,以及实现时间。只有这样我们才能做好一个满足需求的软件。一个好的软件设计不仅要满足用户的需求,还需要站在管理员的角度和层面上分析,一个管理层应该具备哪些职权才能更快捷地实现对整个系统的管理。也就是说在系统开发方面要以用户为主体,兼顾管理员对整个资料的掌控来实现软件,而不是自己想当然,即做到有理有据。这种统筹兼顾的思想应该是一个IT人才应该具备的基本思想。 同时也让我们体会到编写源代码时对语言运用的能力的要求,我们应该力求在满足功能的基础上让我们的代码语言简洁、易懂。我们绝不能满足于自己所懂得知识,要明白作为一个合格的计算机人才,不断创新、不断发展科技才能跟上时代发展的要求,才能与时俱进! 软件设计的主要目的便是对同学们动手实践能力的一个锻炼。通过课程设计,让同学们更好的掌握delphi这个软件,了解和掌握pascal语言的用法。一次课程设计所教会我们的绝对比我们从书本上得到的更多更印象深刻。从控件的熟悉到界面的设计,再到代码的编写,到debug的出现,然后就是不断修改调试,直到最后的成功运行。每一步都是一个进步,每一次进步都是一次心获得心灵满足感的时候。翻阅书籍、网上查询、询问同学 每一次问题的解决都是艰难的,但在每一次艰难的尝试后获得的成功的喜悦确实溢于言表的。从完全不懂代码到自己会敲代码再到今天程序的顺利完成,这是我们朝着人生的道路又前进了一步。 但是,我们也明白,虽然完成了这次课程设计,我们对delphi的认识、对pascal语言的了解也只是在一个层面上,以后我们还需要学习的很多很多。我相信我们都不是停滞不前的人,我们都渴望知识的浇灌,未来我们一定可以“更上一层楼”! 一次课程设计所教会我们的绝不仅仅是技能的提高,动手能力的锻炼,这次组队的结果更是让大家相互理解,相互合作,相互帮助相互扶持,增进了友谊。知识的增加、能力的锻炼、友谊的增进、团结合作是我们收获的宝贵财富!
信息发布:广州名易软件有限公司 http://www.myidp.net
|