资源描述
人事考勤管理系统c++课程设计文档
91
2020年4月19日
资料内容仅供参考,如有不当或者侵权,请联系本人改正或者删除。
课程设计
人事考勤管理系统
目录
第一部分: 开发背景……………………………………………………………..3
第二部分: 系统分析………………………………………………………………3
第三部分: 系统设计………………………………………………………… …..9
第四部分: 公共类设计………………………………………………………….15
第五部分: 主题窗设计………………………………………………………….16
第六部分: 用户登录模块设计……………………………………………...17
第七部分: 用户管理模块设计………………………………………………20
第八部分: 部门管理模块设计………………………………………………23
第九部分: 人员信息管理模块设计……………………………………...32
第十部分: 考勤模块设计………………………………………………………40
第十一部分: 考勤汇总模块设计……………………………………………45
第十二部分: 后续补充部分: 一些过程的具体实现方法总结及图片解释: …………………………………………………………………....51
第十三部分: 心得…………………………………………………………………..51
人事考勤管理系统
Ø 开发背景
某公司业务不断发展, 员工数量不断增加, 人事考勤方面的管理已成为公司管理中的重要部分, 但传统的人事考勤制度已不能有效地管理员工的出勤状况, 急需一套人事考勤管理的有效工具——人事考勤管理系统。
Ø 二、 系统分析
1) 需求分析
经过对人事考勤管理过程的研究和分析, 要求本系统应该具有以下功能。
a) 用户登录。
b) 部门信息录入
c) 人员信息管理
d) 考勤信息录入
e) 考勤信息汇总。
2) 系统功能描述
用户需要输入用户名和密码进入人事考勤管理系统, 对各部门、 员工的基本信息进行维护和管理。在考勤管理模块中录入员工当天的考勤信息, 同时可对年、 月、 员工进行查询。另外, 还能够经过考勤汇总查询模块对员工某月的考勤记录进行汇总, 计算出员工月工作天数、 早退、 迟到的天数。
Ø 三、 系统设计
1) 系统目标
人事考勤管理系统以实现员工日常出勤信息管理为设计目标, 加以强大的数据库管理功能, 能够极大地提高人事部门的日常工作效率。本系统在设计时满足以下几点:
a) 采用人机对话的操作方式, 信息查询灵活、 方便、 快捷、 准确, 数据存储安全可靠。
b) 对考勤信息的操作简单, 能够方便地进行添加、 修改、 和删除。
c) 能够录入员工信息、 部门信息。
d) 对员工的考勤信息按月汇总计算。
e) 对用户输入的数据, 系统进行严格的数据检验, 尽可能排除人为错误。
f) 系统最大限度地实现了易维护性和易操作性。
g) 系统运行稳定、 安全可靠。
2) 系统功能结构
人事考勤管理系统的功能结构如图所示:
人事考勤管理系统
考勤数据录入
考勤信息汇总
用户管理
部门信息管理
员工信息管理
3) 业务流图
人事考勤管理系统业务流程图如图:
用户登录
部门、 员工信息
维 护
考 勤 信 息 汇 总 查 询
考 勤 信 息 录 入
4) 系统预览:
人事考勤管理系统由多个功能模块组成, 下面仅列出一些典型的功能模块, 其它模块以后陆续列出:
a) 部门管理模块如图:
主要管理各部门之间的结构信息
b) 用户管理模块如图:
用于用户的一些操作管理
c) 人员信息管理如图:
主要用于维护员工的基本信息
d) 考勤管理模块如图:
用于记录人事考勤的信息
e) 考勤汇总查询如图:
对员工的考勤信息进行汇总统计
5) 数据库设计
A. 数据库分析
人事考勤系统采用SQL Server 数据库, 数据库名称为 tb_person 在数据库中建立四个表存储不同的信息, 如图:
B. 数据库逻辑设计
a) 管理员信息表( tab_user) , 用于保存管理员的信息, 如图:
b) 部门信息表( tab_Dept) 用于记录部门的信息, 如图:
C) 考勤信息表( tab_check) 用于记录考勤信息
c) 员工信息表( tab_Employees) 保存公司员工信息, 如图:
Ø 四、 公共类设计
本系统采用ADO连接数据库。为了能够方便的使用ADO建立数据库连接并进行相应的数据操作, 在公共类中对系统中是使用的ADO操作进行了封装。在系统中建立了ADO的两个公共类CADOConnection和CADODataSet,这两个类定义在ADO.h头文件中, 实现在ADO.cpp文件中。
A.CADOConnection类
CADOConnection类是用来连接数据库的, 实现了对_Connection接口的封装。CADOConnection类在头文件中的定义如下:
#import "C:\Program Files\Common Files\System\ado\msado15.dll" no_namespace rename("EOF","adoEOF")
class CADOConnection
{
private:
static void InitADO();//初始化ADO
static void UnInitADO();
protected:
_ConnectionPtr m_Connection;//指针接口
public:
BOOL IsOpen();//判断是否与数据库连接
_ConnectionPtr GetConnection();//获取连接接口
CString GetSQLConStr();//获取SQL连接字符串
BOOL Open(CString ConStr);//建立数据库连接
CADOConnection();
virtual ~CADOConnection();
};
CADOConnection类的实现代码如下:
CADOConnection * GetConnection()//GetConnection函数是一个全局函数, 用于返回全局数据库连接对象的的指针
{
return &g_Connection;
}
CADOConnection::CADOConnection()//CADOConnection方法是构造方法, 用于初始化OLE和创立_Connection接口指针
{
InitADO();
m_Connection.CreateInstance("ADODB.Connection");
}
CADOConnection::~CADOConnection()//~CADOConnection方法是构造方法, 用于取消OLE 的初始化和释放_Connection接口指针
{
if (IsOpen())
m_Connection->Close();
m_Connection = NULL;
UnInitADO();
}
void CADOConnection::InitADO()//InitADO是一个静态方法, 用于初始化OLE
{
if (ConCount++ == 0)
CoInitialize(NULL);
};
void CADOConnection::UnInitADO()//UnInitADO是一个静态方法, 用于取消初始化OLE
{
if (--ConCount == 0)
CoUninitialize();
};
BOOL CADOConnection::Open(CString ConStr)//经过指定的数据库连接字符串于SQL数据库建立连接
{
if (IsOpen())
m_Connection->Close();
m_Connection->Open((_bstr_t)ConStr,"","",adModeUnknown);
return IsOpen();
}
CString CADOConnection::GetSQLConStr()//生成数据库连接需要的字符串
{
CString Str;
Str.Format("Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=tb_person;Data Source=LONGFEI-PC\\SQLEXPRESS");
return Str;
}
_ConnectionPtr CADOConnection::GetConnection()//该方法用于返回_Connection接口指针
{
return m_Connection;
}
BOOL CADOConnection::IsOpen()//判断当前数据库连接对象与数据库的连接状态
{
long State;
m_Connection->get_State(&State);
if (State == adStateOpen)
return true;
return false;}
CADODataSet类的定义如下:
class CADODataSet
{
protected:
_RecordsetPtr m_DataSet;//数据集接口指针
CADOConnection *m_Connection;//数据库连接对象
public:
BOOL Open(CString SQLStr,int LockType);//打开记录集
void Delete();//记录删除
int GetRecordNo();//获取记录集行号
void move(int nIndex);//移动记录指针
void Save();//保存对记录集的修改
void SetFieldValue(CString FieldName,_variant_t Value);//设置字段的值
void AddNew();//添加新纪录
BOOL Next();//记录集指针指向下一个记录
FieldsPtr GetFields();//获取记录集字段集合
int GetRecordCount();//获取记录集中记录数量
void SetConnection(CADOConnection *pCon);//设置记录集的数据库连接对象
BOOL Open(CString SQLStr);//打开记录集
CADODataSet();
virtual ~CADODataSet();
private:
BOOL IsOpen();
};
CADODataSet类的实现如下:
CADODataSet::CADODataSet()//该方法为记录集实现类的构造方法, 在该方法中实现记录集接口对象的创立
{
m_DataSet.CreateInstance("ADODB.Recordset");
}
CADODataSet::~CADODataSet()//实现记录集的关闭与接口的释放
{
if (IsOpen())
m_DataSet->Close();
m_DataSet = NULL;
m_Connection = NULL;
}
void CADODataSet::SetConnection(CADOConnection *pCon)//设置记录集所连接的数据库连接类的对象
{
m_Connection = pCon;
}
int CADODataSet::GetRecordCount()//获取记录集中数据的数量
{
if (IsOpen())
return m_DataSet->GetRecordCount();
else
return 0;
}
BOOL CADODataSet::Open(CString SQLStr)//打开数据集
{
if (IsOpen())
m_DataSet->Close();
//*/
m_DataSet->Open(_bstr_t(SQLStr),
_variant_t((IDispatch*)g_Connection.GetConnection(), true),
adOpenKeyset, adLockOptimistic, adCmdText);
return IsOpen();
//*/
}
BOOL CADODataSet::IsOpen()//判断数据集是否处于打开状态
{
long State;
m_DataSet->get_State(&State);
if (State == adStateOpen)
return true;
return false;
}
FieldsPtr CADODataSet::GetFields()//用来获取记录集中字段的集合
{
return m_DataSet->GetFields();
}
BOOL CADODataSet::Next()//记录集指针下移一位
{
if (m_DataSet->adoEOF)
return false;
m_DataSet->MoveNext();
return true;
}
void CADODataSet::AddNew()
{
m_DataSet->AddNew();
}
void CADODataSet::SetFieldValue(CString FieldName, _variant_t Value)//想记录集中指定的字段赋值
{
m_DataSet->PutCollect((_bstr_t)FieldName,Value);
}
void CADODataSet::Save()//保存记录集数据所做的修改
{
m_DataSet->Update();
}
void CADODataSet::move(int nIndex)//将记录集的当前指针移动到指定的索引位置
{
m_DataSet->MoveFirst();
m_DataSet->Move(nIndex);
}
int CADODataSet::GetRecordNo()//获取记录集中的当前行号
{
return m_DataSet->AbsolutePosition;
}
void CADODataSet::Delete()//删除记录集中的当前行
{
m_DataSet->Delete(adAffectCurrent);
}
BOOL CADODataSet::Open(CString SQLStr, int LockType)
{
if (IsOpen())
m_DataSet->Close();
//*/
m_DataSet->Open(_bstr_t(SQLStr),
_variant_t((IDispatch*)g_Connection.GetConnection(), true),
adOpenKeyset,(LockTypeEnum) LockType, adCmdText);
return IsOpen();
}
Ø 五、 主题窗设计
A.主题窗由菜单和图片组成, 如图:
B.主题窗设计步骤:
a.启动visual c++, 选择File/New命令, 打开New对话框
b.在左侧选择MFC AppWizard( exe) 选项, 在Project name编辑框中输入工程名称, 在location编辑框中设置保存工程的路径, 然后单击OK按钮, 打开MFC AppWizard对话框, 选择对话框编程, 打击fish
c.像工程中导入位图, 菜单资源( 具体操作在最后有补充)
Ø 六、 用户登录模块设计
A. 概述, 登录界面是每个管理系统应该具备的, 本系统的登录模块如图:
B . 技术分析
窗体应在主题窗创立之前并显示, 在登录窗体创立的同时应该建立数据库连接, 具体操作如下:
BOOL bCon = 、 GetConnection()->Open(GetConnection()->GetSQLConStr());
CLoginDialog logindlg;
if (logindlg.DoModal() != IDOK)
return false;
::CoInitialize(NULL);
CPersonDlg dlg;
C. 实现过程
a. 创立一个对话框
b. 向对话框中添加两个静态文本控件、 一个编辑框控件、 和两个按钮控件。分别设置两个静态文本控件的Caption属性为”用户名”和”密码”设置编辑框控件类型为password;
分别设置连个按钮为”确定”和”取消”。
C. 在窗体初始化方法中创立用户表的数据, 并将用户添加到列表框控件中。代码如下:
BOOL CLoginDialog::OnInitDialog()
{
CDialog::OnInitDialog();
m_DataSet.SetConnection(GetConnection());
m_DataSet.Open("Select * From Tab_User");
int count = m_DataSet.GetRecordCount();
for (int i = 0; i< count;i++)
{
m_UserList.AddString((_bstr_t)m_DataSet.GetFields()->Item[L"UserName"]->Value);
m_DataSet.Next();
}
m_UserList.SetCurSel(0);
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
d. 确定按钮事件代码如下:
void CLoginDialog::OnLogin()
{
CString sql,user,pass;
m_UserList.GetWindowText(user);
m_PassWord.GetWindowText(pass);
sql.Format("Select * From tab_user Where UserName = '%s' and PassWord = '%s'",
user,pass);
m_DataSet.Open(sql);
if (m_DataSet.GetRecordCount() == 1)
{
::SetUserName(user);
this->OnOK();
}
else
AfxMessageBox("用户名或密码不正确! ");
}
Ø 七、 用户管理模块
A. 概况: 能实现添加, 修改, 删除等操作如图:
B. 实现过程:
a. 创立一个对话框
b. 向对话框中添加相应的控件
c. 给对话框添加对话框类
d. 给类添加函数及成员变量
e. 给控件关联变量
f. 编写函数
C.实现代码:
a.定义UpdateGrid方法用来更新列表视图中的信息代码如下:
void CUserManage::UpdateGrid()
{
m_DataSet.Open("Select * From tab_User");
m_grid.DeleteAllItems();
for (int i = 0 ; i < m_DataSet.GetRecordCount();i++)
{
m_grid.InsertItem(i,(_bstr_t)m_DataSet.GetFields()->Item[L"UserName"]->Value);
int no = m_DataSet.GetRecordNo();
m_grid.SetItemData(i,no);
m_DataSet.Next();
}
}
b.添加按钮代码如下:
void CUserManage::OnAppend()
{
CUserEdit useredit;
if (useredit.DoModal() == IDOK)
{
m_DataSet.AddNew(); m_DataSet.SetFieldValue("UserName",(_bstr_t)useredit.name);
m_DataSet.Save();
UpdateGrid();
}
}
c. 删除按钮代码:
void CUserManage::OnDelete()
{
if (MessageBox("是否删除此记录! ","提示",
MB_YESNO|MB_ICONWARNING) == IDYES)
{
int no = m_grid.GetItemData(m_grid.GetSelectionMark());
m_DataSet.move(no-1);
m_DataSet.Delete();
m_DataSet.Save();
UpdateGrid();
}
}
d. 修改按钮代码:
void CUserManage::OnEdit()
{
CUserEdit useredit;
int no = m_grid.GetItemData(m_grid.GetSelectionMark());
m_DataSet.move(no-1);
useredit.name = (char *)(_bstr_t)m_DataSet.GetFields()->Item[L"UserName"]->Value;
if (useredit.DoModal() == IDOK)
{
m_DataSet.SetFieldValue("UserName",(_bstr_t)useredit.name);
m_DataSet.Save();
UpdateGrid();
}
}
Ø 八、 部门管理模块设计
A. 概述: 该模块记录了部门间的的层次结构和部门信息, 一般使用树控件实现, 如图:
B. 实现过程:
a. 创立一个对话框
b. 向对话框中添加相应的控件
c. 给对话框添加对话框类
d. 给类添加函数及成员变量
e. 给控件关联变量
f. 编写函数
C. 相关代码如下:
BOOL CDeptManage::OnInitDialog() //初始化函数
{
CDialog::OnInitDialog();
m_DataSet.SetConnection(::GetConnection());
UpdateDept();
return TRUE; }
将部门信息一次性读入树控件中。代码如下:
void CDeptManage::GetNode(HTREEITEM pNode, int nPid)
{
HTREEITEM node;
CADODataSet DataSet;
DataSet.SetConnection(::GetConnection());
CString str;
str.Format("Select * From tab_Dept where pid = %d",nPid);
DataSet.Open(str);
int count = DataSet.GetRecordCount();
int ID;
_variant_t value;
for (int i = 0;i<count;i++)
{
node = m_tree.InsertItem((_bstr_t)DataSet.GetFields()->Item["DeptName"]->Value,pNode);
value = (_variant_t)DataSet.GetFields()->Item["ID"]->Value;
ID = value.intVal;
m_tree.SetItemData(node,ID);
GetNode(node,ID);
DataSet.Next();
}
}
定义GetNode方法, 用于按成次级关系获取部门表中的所有数据, 并添加树控件, 该方法由UpdateDept方法进行调用, 代码如下;
void CDeptManage::UpdateDept()
{ m_tree.DeleteAllItems();
GetNode(TVI_ROOT,0);
}
void CDeptManage::OnAdd()
{
CDeptEdit deptedit;
if (deptedit.DoModal() == IDOK)
{
HTREEITEM pNode = m_tree.GetSelectedItem();
int pID;
if (deptedit.isroot)
pID = 0;
else
pID = m_tree.GetItemData(pNode);
CADODataSet dataset;
dataset.SetConnection(::GetConnection());
dataset.Open("Select top 1 * From tab_Dept");
dataset.AddNew();
dataset.SetFieldValue("DeptName",(_variant_t)deptedit.name);
dataset.SetFieldValue("memo",(_variant_t)deptedit.memo);
dataset.SetFieldValue("PID",(long)pID);
dataset.Save();
UpdateDept();
}
}
单击”修改”按钮时将弹出部门编辑窗体, 输入部门信息后单击”确定”按钮, 实现部门信息的修改。代码如下
void CDeptManage::OnEdit()
{
CDeptEdit deptedit;
deptedit.visible = false;
HTREEITEM pNode = m_tree.GetSelectedItem();
if (pNode == 0)
return;
int pID = m_tree.GetItemData(pNode);
CADODataSet dataset;
dataset.SetConnection(::GetConnection());
CString str;
str.Format("Select * From tab_Dept where id = %d",pID);
dataset.Open(str);
deptedit.name = (char *)(_bstr_t)dataset.GetFields()->Item[L"DeptName"]->Value;
deptedit.memo = (char *)(_bstr_t)dataset.GetFields()->Item["memo"]->Value;
if (deptedit.DoModal() == IDOK)
{
dataset.SetFieldValue("DeptName",(_variant_t)deptedit.name);
dataset.SetFieldValue("memo",(_variant_t)deptedit.memo);
dataset.Save();
UpdateDept();
}
}
当单击”删除”按钮时, 将删除当前选中的节点, 代码如下:
void CDeptManage::OnDelete()
{
HTREEITEM pNode = m_tree.GetSelectedItem();
if (pNode == 0)
return;
if (MessageBox("是否删除此记录! ","提示",
MB_YESNO|MB_ICONWARNING) == IDYES)
{
int pID = m_tree.GetItemData(pNode);
CADODataSet dataset;
dataset.SetConnection(::GetConnection());
CString str;
str.Format("Select * From tab_Dept where id = %d",pID);
dataset.Open(str);
dataset.Delete();
dataset.Save();
UpdateDept();}}
Ø 九、 人员信息管理模块设计
A. 概述: 人员信息管理模块根据部门分类显示人员, 同时可对人员信息进行维护, 界面如下:
B. 实现过程:
a. 创立对话框
b. 向对话框中添加相应的控件
c. 给对话框添加对话框类
d. 给类添加函数及成员变量
e. 给控件关联变量
C. 相关代码:
GetNode方法, 获取部门信息, 并添加到树控件中。该方法由UpdateDept调用, 代码如下:
void CPersonManage::GetNode(HTREEITEM pNode, int nPid)
{
HTREEITEM node;
CADODataSet DataSet;
DataSet.SetConnection(::GetConnection());
CString str;
str.Format("Select * From tab_Dept where pid = %d",nPid);
DataSet.Open(str);
int count = DataSet.GetRecordCount();
int ID;
_variant_t value;
for (int i = 0;i<count;i++)
{ node = m_tree.InsertItem((_bstr_t)DataSet.GetFields()->Item["DeptName"]->Value,pNode);
value = (_variant_t)DataSet.GetFields()->Item["ID"]->Value;
ID = value.intVal;
m_tree.SetItemData(node,ID);
GetNode(node,ID);
DataSet.Next();
}
}
UpdateDpt调用GetNode, 实现信息更新, 代码如下:
void CPersonManage::UpdateDept()
{
m_tree.DeleteAllItems();
HTREEITEM node;
node = m_tree.InsertItem("全部",TVI_ROOT);
m_tree.SetItemData(node,-1);
GetNode(node,0);
}
UpdatePerson更新人员信息, 并将其显示在列表控件中。代码如下:
void CPersonManage::UpdatePerson()
{
m_list.DeleteAllItems();
CADODataSet DataSet;
DataSet.SetConnection(::GetConnection());
CString str;
if (m_DeptID == -1)
str.Format("Select * From tab_Employees");
else
str.Format("Select * From tab_Employees where Dept = %d",m_DeptID);
DataSet.Open(str);
int count = DataSet.GetRecordCount();
int n = 0;
_varia
展开阅读全文