一、设计目的
随着计算机的发展及网络技术的应用,当今社会正快速向信息自动化社会前进,信息自动化的作用也越来越大,特别是各行业的管理领域,智能化信息处理已是提高效率、规范管理、客观审查的最有效途径。考勤作为一个公司的基项管理,是单位对员工工作管理的基本依据。开发考勤管理系统,正是完善企业信息化管理的重要环节。对于员工考勤如果仍使用传统的手工方式录入将是一项复杂的工作。面对庞大的信息量,该方式现主要存在以下弊端:
- 浪费人力、效率低下;
2、考勤结果反映速度慢(一月才能汇总一次),主管部门不能及时全面地监督员工的出勤情况;
3、难避免考勤中的弄虚作假现象。一些单位上报的工资人数往往大于实际考勤和领工资的人数,造成公司大量工资流失;
4、由于考勤数据的不准确,公司劳动人事工资管理系统的许多基础数据也存在较大误差,给人事部门的许多全局性的统计工作也带来了不准确性;
5、考勤统计工作复杂繁重,难以保证统计结果的正确性、及时性。
因此,人工考勤已很难满足公司规范化管理的要求。建立现代化的智能考勤管理系统势在必行。
通过考勤管理系统能满足公司多种考勤及管理要求,能为公司带来巨大的经济效益:
1、考勤管理系统通过考勤机判断并记录员工上下班关信息,可以保证考勤数据的准确、公正、安全,减少考勤人员的工作负担,避免人为因素的干扰和弄虚作假现象;
2、所有员工的考勤信息可一次读回,考勤系统对信息统一处理,迅速、全面;
3、能为人事工资管理系统提供可靠的数据资料,确保人事统计的准确、可靠;
4、各管理用计算机及管理软件用Windows环境下的全中文界面平台,能灵活处理各种特殊情况,方便的修改各种基本信息,提供丰富的统计报表,查询方便,管理安全,操作简便易学;
二、设计任务
1. 能够方便地对上班时间进行设定;
2. 能够提供员工出入单位的情况记录。出入情况主要由考勤机来记录,但是需要设置人工添加的功能,如出勤记录、月度考勤统计、人员信息、部门设置等,已备特殊情况的处理;
3. 能够提供请假、加班和出差情况的记录,并实现查询、添加、修改、删除、浏览等处理功能;
4. 能够在每个月底进行整个月的出勤情况统计;
5. 能够具有一定的安全性、协调性和完整性。
三 、设计内容与步骤
在软、硬件方面对系统的需求,软件要求易学,容易掌握,可以很简单方便的管理各种信息。硬件的配置要求不能太高,这样可以很好的适应当前的企业情况。
- 系统功能模块设计:
系统功能模块如图1-1所示。
图1-1系统功能模块图
- 数据流程图:
系统的数据流程图1-2所示,出勤的原始记录主要来源于考勤机,并且以固定格式保存在数据库中。考勤管理系统的任务是如何处理这些数据。
图1-2考勤管理系统数据流程图
3.数据库概念结构设计(E-R图)如下所示:
图1-3 E-R 图
- 数据库需求分析:
根据数据流程,可以列出以下管理系统所需的数据项和数据结构。
出勤记录:记录号、员工、出入情况和出入时间,如图1-4所示。
图1-4 ATTENDANCE出勤记录表
月度考勤统计:记录号、员工、年月、累计正常工作时间、累计请假时间、累计加班时间、累计出差时间、迟到次数、早退次数和旷工次数,如图1-5所示。
图1-5 ATTENDANCE_STAT月度考勤统计表
请假记录:记录号、员工、假期起始时间/结束时间和请假缘由,如图1-6所示。
图1-6 LEAVE 请假记录表
加班记录:记录号、员工、加班时间长度和日期,如图1-7所示。
图1-7 OVERTIME 加班记录表
出差记录:记录号、员工、出差起始时间/结束时间和具体描述,如图1-8所示。
图1-5 ERRAND 出差记录表
人员信息:员工号、密码、权限、姓名、部门和当前状态等,如图1-9所示。
图1-9 PERSON 人员信息表
部门设置:部门编号、名称等,如图1-10所示。
图1-10 DEPARTMENT 部门设置表
5.数据库操作的准备:
为了使用ODBC类,需要在stdafx.h中加入#include”afxdb.h”一行。因本程序只需要连接一个数据库,所以定义了一个Cdatabase型的全局变量db,一次性打开和关闭数据库。数据库的打开在登录认证对话框中。在主程序结束前需关闭数据库,因此在App类的ExitInstance()函数中加入代码:if (db.IsOpen()) db.Close();为了编程便捷,可以为数据库中的每一个表映射一个记录集类(从CrecordSet类继承),其映射关系如表1-1所示。这些类通过RFX(Record Field Exchange)机制将成员变量与表格中的字段值联系起来,通过方问成员变量可以访问当前记录中字段的值。
Crecordset派生类 | 表格 |
CAttendanceRS | ATTENDANCE出勤记录表 |
CCounterRS | COUNTER计数器表 |
CdepartRS | DEPARTMENT部门信息表 |
CerrandRS | ERRAND出差记录表 |
CLeaveRS | LEAVE请假记录表 |
COvertimeRS | OVERTIME加班记录表 |
CPersonRS | PERSON员工个人信息表 |
CStatRS | ATTENDANCE_STAT月度考勤统计表 |
表1-1 CRecordset派生类对应的表格
6.主对话框的设计:
主对话框界面如图1-11所示。用户可以通过菜单进行方便的操作,如添加记录,统计记录等。每个菜单项关联了一个对话框,在相应的菜单项的初始化中使用:类名 dlg; dlg.DoModal();两条语句来进行实现。
图1-11 主对话框
- 考勤统计对话框的创建
考勤统计对话框界面设计如图1-12所示。用户可进行月度统计,也可以通过查找满足条件的记录如年月、员工、姓名等来进行相关的统计。
图1-12 考勤统计对话框
四、测试与评价
经过测试,该应用程序能够较好的实现上班时间的设定;能够提供员工出入单位的情况记录;能够提供请假、加班和出差情况的记录,并实现查询、添加、修改、删除、浏览等处理功能;能够在每个月底进行整个月的出勤情况统计;能够拥有一定的安全性、协调性和完整性。但在安全性上存在一定的漏洞;功能不够完善,不能进行统一查询;界面相对简单,所以总体评价为中等。
希望能得到彭老师的指导得以更加完善此系统,添补漏洞。
五、体会与收获
从确定课程设计的题目到现在将近二个月的时间,我们的”考勤管理系统”已初步形成。通过本次设计,又学习了一门新的软件和许多数据库的知识。
对于这一门软件来说我们算是初学者,所以我们先要从基础开始学习MIS系统设计,通过查找相关资料和老师这个学期的课堂讲解内容来了解到熟悉这个软件。所以从专业角度来讲,我们的整个设计还不太规范和完善。但是通来这次设计,我们在软件开发这个方面累积了许多知识和经验,为以后从事计算机工作打下了基础。
同时,在学习和设计中:
- 体验到VC++系统的强大性、多功能性、全面性和多样性。
- 了解到使用VC++所做的MIS系统的功能全面和界面良好等性能。
- 通过设计考勤管理系统,知道了如何开始一个系统的制作和其制作的工作流程与步骤。
- 学会了如何使用VC++来开发设计一个系统,如建立应用程序框架、构造人机交互界面、新建封装类、继承类、给类添加成员变量、类与数据库的关联和编制代码等功能。
六、附录
1.主界面源代码清单:
BOOL CAttendanceDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL
{ CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{ pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING,IDM_ABOUTBOX,strAboutMenu);
}
}
void CAttendanceDlg::OnBtnConfig()
{
// 显示工作时间设置对话框
CWorkplanDlg dlg;
dlg.DoModal();
}
2.考勤修改对话框源代码清单:
BOOL CAttDlg::OnInitDialog() //初始化对话框
{
m_Sheet.Create(this, WS_CHILD | WS_VISIBLE, 0); //创建窗口
m_Sheet.ModifyStyleEx (0, WS_EX_CONTROLPARENT); //修改风格
m_Sheet.ModifyStyle( 0, WS_TABSTOP ); //修改风格
// 设置窗口位置
m_Sheet.SetWindowPos( NULL, 0, 100, 0, 0,
SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE );
return TRUE;
}
为了方便地更新列表框内容,编写了UpdateList()函数,调用些函数可使列表框显示给定的数据表格。
void CPage1::UpdateList(CAttendanceRS& rs) //更新列表框内容
{
int i=0;
CString strID,strTime;
rs.Open(); // 打开出勤记录表
m_cList.DeleteAllItems(); // 清除列表框内容
while(!rs.IsEOF()) // 对数据表中所有记录进行处理
{
m_cList.InsertItem(i, ""); // 添加新Item
strID.Format("%d", rs.m_ID); // 转换为字符串
m_cList.SetItemText(i, 0, strID);
m_cList.SetItemText(i, 1, rs.m_PERSON);
m_cList.SetItemText(i, 2, rs.m_IN_OUT);
m_cList.SetItemText(i, 3, rs.m_IO_TIME.Format("%Y-%m-%d %H:%M"));
rs.MoveNext(); // 跳到下一条记录
i++;
}
rs.Close(); // 关闭出勤记录表
}
添加部门和全体员工出勤记录的过程最终可分解为添加单个员工记录的过程。为了避免程序的重复,设置了下面的子程序:
// 添加出勤记录函数
void CPage1::IO_Add(CString strPersonID)
{
int counter; // 用于计数
CString strIO; // 保存出入情况
CCounterRS rs_counter(&db); // 构造计数器记录表
// 记录编号
rs_counter.m_strFilter = "ID='A'"; // 设置过滤器,提取计数值
rs_counter.Open(); // 打开计数器记录表
counter=rs_counter.m_COUNTER_VALUE; // 提取计数值
counter++; // 计数值加1
rs_counter.Edit(); // 编辑计数器
rs_counter.m_COUNTER_VALUE=counter; // 保存当前计数
rs_counter.Update(); // 提交修改
rs_counter.Close(); // 关闭计数器记录表
// 添加记录
// 判断确定出入情况
if(((CButton*)GetDlgItem(IDC_RADIO_OUT))->GetCheck())
strIO="O";
else strIO="I";
// 转换出入时间类型
int nYear,nMonth,nDay,nHour,nMinute; // 年,月,日,时,分
sscanf(m_strIOTime.Left(4), "%d", &nYear); // 得到年
sscanf(m_strIOTime.Mid(5,2), "%d", &nMonth); // 得到月
sscanf(m_strIOTime.Mid(8,2), "%d", &nDay); // 得到日
sscanf(m_strIOTime.Mid(11,2), "%d", &nHour); // 得到时
sscanf(m_strIOTime.Mid(14,2), "%d", &nMinute); // 得到分
// 得到出入时间
CTime IO_time(nYear,nMonth,nDay,nHour,nMinute,0);
CAttendanceRS rs_attendance(&db); // 构造考勤记录表
rs_attendance.Open(); // 打开考勤记录表
rs_attendance.AddNew(); // 追加考勤记录
rs_attendance.m_ID=counter;
rs_attendance.m_PERSON=strPersonID;
rs_attendance.m_IN_OUT=strIO;
rs_attendance.m_IO_TIME=IO_time;
rs_attendance.Update();
rs_attendance.Close(); // 关闭考勤记录表
UpdateList(rs_attendance); // 更新列表框
}
3.考勤统计对话框源代码清单
当输入员工号时,检索员工姓名,用于确认输入。
void CStatDlg::OnChangeStatEdtSeekpersonid()
{
UpdateData(); // 更新数据
CPersonRS rs(&db); // 构造记录集
rs.m_strFilter = "ID='" + m_strPersonID + "'"; // 设置过滤条件
rs.Open(); // 打开记录集
if(rs.GetRecordCount()==1) // 判断员工记录是否存在
{
m_strPersonName=rs.m_NAME; // 得到员工姓名
}
else m_strPersonName.Empty(); // 清除员工姓名的显示
rs.Close(); // 关闭记录集
UpdateData(FALSE); // 更新界面数据
}
在以上代码中用到了StrToTime函数,这是一个全局函数,代码如下:
Ctime StrToTime(Cstring str)
{ //时间串格式“%Y-%m-%d %H:%M:%S”,如“1999-01-01 11:11:11”
int nYear,nMonth,nDay,nHour,nMinute,nSecond;
sscanf(str.Left(4),”%d”,&nYear); //得到年
sscanf(str.Mid(5,2),”%d”,&nMonth); //得到月
sscanf(str.Mid(8,2),”%d”,&nDay); //得到日
sscanf(str.Mid(11,2),”%d”,&nHour); //得到时
sscanf(str.Mid(14,2),”%d”,&nMinute); //得到分
sscanf(str.Mid(17,2),”%d”,&nSecond); //得到秒
//构造Ctime变量
Ctime result(nYear,nMonth,nDay,nHour,nMinute,nSecond);
Return result;
}
4.参考文献:
1、陈建春.Visual C++开发GIS系统,开发实例剖析,2000年.
2、陈建春.Visual C++高级编程技术,开发实例剖析,1999年.
3、李于剑.Visual C++实践与提高,图形图象编程篇, 2001年.
4、同志工作室.Visual C++6.0开发技巧与实例教程, 2000年.
5、赵仕健. Visual C++6.0编程与实例解析, 2000年.
6、钱 能. C++程序设计教程, 1999年.