# 【课程设计要求】
题目:职工工作量统计系统设计
## 1、问题描述
职工包括姓名、职工号、性别、年龄、所在部门、联系方式等信息。 工作量包括职工号、完成的产品数量等信息。 该设计系统能够对职工的工作量进行统计,并排出名次。注意,一个职工的工作量是可以多次输入的。
## 2、功能要求
(1)添加功能:程序能够添加职工的记录和工作量,可提供选择界面供用户选择所要添加的类别, 要求职工的编号要唯一,如果添加了重复职工号的职工记录时,则提示数据添加重复并取消添加。
(2)查询功能:可根据职工号、姓名等信息对已添加的职工记录进行查询。还可以按职工号对工 作量进行查询。如果未找到,给出相应的提示信息,如果找到,则显示相应的记录信息。
(3)显示功能:可显示当前系统中所有职工记录和工作量统计信息,每条记录占据一行。
(4)编辑功能:可根据查询结果对相应的记录进行修改,修改时注意编号的唯一性。
(5) 删除功能:主要实现对已添加的人员记录进行删除和工作量进行删除。如果当前系统中没有 相应的人员记录,则提示“记录为空!”并返回操作;否则,输入要删除的人员的编号,根据所输入的 信息删除该人员记录,如果没有找到该人员信息,则提示相应的记录不存在。
(6)统计功能:对职工可按工作量进行统计,并排名次。
(7)保存功能:可将当前系统中各类人员记录存入文件中,存入方式任意。
(8)读取功能:可将保存在文件中的人员信息读入到当前系统中,供用户进行使用。
## 3、问题的解决方案
根据系统功能要求,可以将问题解决分为以下步骤:
(1)应用系统分析,建立该系统的功能模块框图以及界面的组织和设计;
(2)分析系统中的各个实体及它们之间的关系;
(3)根据问题描述,设计系统的类层次;
(4)完成类层次中各个类的描述;
(5)完成类中各个成员函数的定义;
(6)完成系统的应用模块;
(7)功能调试;
(8)完成系统总结报告。
【题目分析】
此题我选择采用链表的思路,设置了Date类作为数据模板用来存放数据,开了一个核心头指针head并且应用于全局,所有功能的实现围绕head展开。并且应用了mfc使得界面可视化,增加了用户友好性。
【类结构设计】
根据题目分析。主要运用了Date类,如图1所示

图1 Date类图
因为运用了MFC进行界面设计,所以类比较多。其中MFC为我自动提供了一些支持程序的类如targetver.h,pch.h,MFCApplication3.h,afxdialogex.h,framework.h,MFCApplication3Dlg.h,Resource.h。其中主菜单类是SystemDlg.h,我在其中定义了一些按键接口如afx\_msg void OnBnClickedButton1();在cpp实现文件中通过DoModal()弹窗函数实现调用。其中数据类是Date.h,我在其中定义了数据类型,因为是用链表的思路,所以也定义了链表指针。其中每一个功能我都单独开了一个类,如添加功能就是Add.h实现。具体各类之间的关系如图2所示例

图2 类之间的关系
【流程图】

【工程结构组织】
本项目使用Visual Studio实现,工程文件结构图如图3所示。

图3 工程文件结构图

图4 头文件结构图

图5 源文件结构图
本项目主要由28个文件组成(不包括外部依赖项和资源文件),各文件的功能如下表(表1)所示。
表1. 本项目文件功能列表
|序号|文件名|说明|
| :-: | :-: | :-: |
|1|Date.h|数据类定义文件|
|2|targetver.h|MFC系统头文件|
|3|pch.h|MFC系统头文件|
|4|pch.cpp|Pch实现文件|
|5|afxdialogex.h|MFC系统头文件|
|6|framework.h|MFC系统头文件|
|7|Resource.h|MFC系统头文件|
|8|MFCApplication3Dlg.h|登录类定义头文件,包含账号密码|
|9|MFCApplication3Dlg.cpp|登录类定义实现文件|
|10|MFCApplication3.h|MFC系统头文件|
|11|SystemDlg.h|菜单类定义头文件|
|12|SystemDlg.cpp|菜单类实现文件,在其中嵌入了文件读写以及排序功能|
|13|Add.h|添加功能类定义头文件|
|14|Add.cpp|添加功能类实现文件|
|15|Addall.h|批量添加功能类定义头文件|
|16|Addall.cpp|批量添加功能类实现文件|
|17|AddWH.h|添加工作量功能定义头文件|
|18|AddWH.cpp|添加工作量功能实现文件|
|19|Delete.h|删除功能类定义头文件|
|20|Delete.cpp|删除功能类实现文件|
|21|Edit.h|编辑功能类定义头文件|
|22|Edit.cpp|编辑功能类实现文件|
|23|Find.h|查询功能类定义头文件|
|24|Find.cpp|查询功能类实现文件|
|25|jieguo.h|结果显示功能定义头文件|
|26|jieguo.cpp|结果显示功能类实现文件|
|27|xianshi.h|显示功能定义头文件|
|28|xianshi.cpp|显示功能实现文件|
【核心代码解释】
核心代码1:文件保存
如图6运用输入输出流进行文件保存,包含头文件<fstream>后定义一个ofstream的对象save,调用open函数以ios::out方式打开文件,如果文件不存在将会创建一个数据库的txt文件来保存信息,因为采用ios::out的方式,每次保存信息会覆盖之前的信息,避免了重复保存。保存方式是定义一个工作指针p,接收应用于全局的头指针head,遍历一遍链表通过重载运算符<<依次保存。保存成功后,调用close函数关闭文件,调用MFC的一个MessageBox函数进行一个保存成功的弹窗提示。

图6 文件保存
核心代码2:文件读取
如图7运用输入输出流进行文件保存,包含头文件<fstream>后定义一个ifstream的对象read,调用open函数打开文件,调用is\_open函数判断文件是否为空,如果文件不存在或者文件为空,将会调用MessageBox函数进行一个文件为空的弹窗提示;如果文件存在,则会通过while循环进行链表创建,其中定义一个工作指针node并为其开辟内存空间,通过read对象运用重载运算符>>初始化node的信息,然后判断node是头节点还是普通节点,循环创建,当node循环到文件末尾或者node里面的age为非正常值时候跳出循环。读入成功后,将会调用MessageBox函数进行一个读入成功的弹窗提示。创建链表的代码会再下一部分核心代码详细解释。

图7 文件读取
核心代码3:添加信息
如图8定义CString类型的数个变量与Date里面的数据对应,调用GetDlgItemText函数用于接收输入框内的文本类型的数值(其中变量是输入框的ID和接收变量的变量名),再调用CW2A函数进行强制类型转换,将CString类型的变量通过GetString函数转换成string类型存入工作指针node,调用GetDlgItemInt函数将输入框中的数据类型的变量转换为int型存入工作指针node。

图8接收信息
如图9 node指针已被成功定义,在添加信息之前