员工管理系统
1.创建数据库:employeemanage.mdb
库中包含三个表:employee(员工登录系统的账号密码)
employeeinfor(公司所有职工的信息)
hr(领导的账号密码)
2.MFC ODBC向导过程
Windows中的ODBC组件是出现在系统的“控制面板”→“管理工具”→“数据源(ODBC)”(注意是32位还是64位)
双击“数据源(ODBC)”,进入ODBC数据源管理器。在这里,用户可以设置ODBC数据源的一些信息。其中,“用户DSN”页面是用来定义用户自己在本地计算机使用的数据源名(DSN),不会数据库的直接选第二个excel files 即可
单击 添加 按钮,弹出有一驱动程序列表的“创建新数据源”对话框,在该对话框中选择要添加用户数据源的驱动程序,下图选择“Microsoft Access Driver”,高版本里面使用ACCess创建的数据库后缀名是accdb,所以选择驱动器时也要选择Microsoft Access Driver(.mdb,.accdb)
单击 完成 按钮,进入指定驱动程序的安装对话框,单击 选择 按钮将前面创建的数据库调入,然后在数据源名输入“Database Example For VC++”(这个名称按实际需要命名,此处可以直接学成:员工管理系统)
③ 单击 确定 按钮,刚才创建的用户数据源被添加在“ODBC数据源管理器”的“用户数据源”列表中
3.创建MFC项目
创建一个单文档
我选择单文档应用程序类型。在数据库支持页面选择提供文件支持的数据库,客户端类型选择ODBC,点击数据源,选择机器数据源,选择我们之前加入的数据库,然后在数据源导入我们主要需要使用的表。因为我在主对话框主要使用图书信息这张表,所以我选择BOOKSinfor,其它默认
4.详细操作
1.利用类向导将其余两个表导进去
MFC ODBC使用者->数据源->机器数据源->自己需要的数据库下的表
2.登录页面
2.1新建dialog作为登录页面
2.2页面如下
2.3双击页面,添加一个新对话框类
2.4为编辑控件创建变量
2.5为了让登录页面在一开始时就出来执行以下操作
在CCEmployeemanaApp的InitInstance()中添加代码
2.6为按键添加事件处理函数
对于高版本,手动在void CDenglu::DoDataExchange(CDataExchange* pDX)添加
注: CDenglu是根据实际情况,但都在DoDataExchange
DDX_Text(pDX, IDC_EDIT_USERNAME, m_username);
DDX_Text(pDX, IDC_EDIT_PASSWORD, m_password);
消息响应函数代码
void CDenglu::OnBnClickedButtonBoss()
{
UpdateData(TRUE);
//m_username.TrimLeft();
//m_password.TrimLeft();
if (m_username.IsEmpty() || m_password.IsEmpty())
{
MessageBox(L"用户名或密码不能为空!");
return;
}
CString strSQ;
strSQ.Format(L"select*from hr where mnumber='%s'and mpassword ='%s'", m_username, m_password);
Chr ss;
if (!ss.Open(AFX_DB_USE_DEFAULT_TYPE, strSQ))//未获得有效查询记录集
{
MessageBox(L"数据库操作错误", L"错误", MB_OK);
return;
}
if (ss.GetRecordCount() == 0)
{
ss.Close();
MessageBox(L"密码错误,请重新输入!");
m_password = "";
UpdateData(FALSE);
}
else
{
MessageBox(L"登陆成功");
CDenglu::OnCancel();
}
// TODO: 在此添加控件通知处理程序代码
}
void CDenglu::OnBnClickedButtonStaff()
{
UpdateData(TRUE);
m_username.TrimLeft();//没有参数的版本用来将字符串最前面的空格修整掉
m_password.TrimLeft();
if (m_username.IsEmpty() || m_password.IsEmpty())
{
MessageBox(L"用户名或密码不能为空!");
return;
}
CString strSQL;
strSQL.Format(L"select*from employee where number='%s'and passwod ='%s'", m_username, m_password);
CEmployeeSet ss;
if (!ss.Open(AFX_DB_USE_DEFAULT_TYPE, strSQL))//未获得有效查询记录集
{
MessageBox(L"数据库操作错误", L"错误", MB_OK);
return;
}
else if (ss.GetRecordCount() == 0)
{
ss.Close();
MessageBox(L"密码错误,请重新输入!");
m_password = "";
UpdateData(FALSE);
}
else
{
MessageBox(L"登陆成功");
CDenglu::OnCancel();
}
// TODO: 在此添加控件通知处理程序代码
}
3.主页面设计
3.1 显示所有员工信息
添加一个dialog命名为ALLSTAFF
加list control,并将查看属性改为报告report
加一个按钮,命名为显示
为dialog双击添加类,自己命名。
给列表控件添加变量名m_listctrl
在列表控件所在的类中,
需使用OnInitDialog()(该函数在需要在类向导的虚函数里添加)对列表控件进行初始化,为列表控件添加表头,以及设置我们想要的格式。
并添加下列代码
BOOL AllStaff::OnInitDialog()
{
CDialogEx::OnInitDialog();
// TODO: 在此添加额外的初始化
DWORD dwStyle;
dwStyle = m_listctrl.GetExtendedStyle();
dwStyle |= LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_ONECLICKACTIVATE;
m_listctrl.SetExtendedStyle(dwStyle);
CString strHeader[] =
{ L"员工编号",L"姓名",L"性别",L"出生时间",L"学历",L"职位",L"联系方式",L"住址" };
int nLong[] = { 150, 150, 150, 150, 150, 150,150,150 };
for (int nCol = 0; nCol < sizeof(strHeader) / sizeof(CString); nCol++)
{
m_listctrl.InsertColumn(nCol, strHeader[nCol], LVCFMT_LEFT, nLong[nCol]);
}
return TRUE; // return TRUE unless you set the focus to a control
// 异常: OCX 属性页应返回 FALSE
}
给查看按钮添加消息响应函数,并添加下列代码
void AllStaff::OnBnClickedButtonShow()
{
// TODO: 在此添加控件通知处理程序代码
m_listctrl.DeleteAllItems();
CCEmployeemanaSet m_student;
try
{
if (m_student.IsOpen())
{
m_student.Close();
}
CString str;
str.Format(TEXT("select * from employeeinfor order by numbe"));
if (!m_student.Open(CRecordset::snapshot, str))
{
MessageBox(TEXT("打开数据库失败"));
return;
}
}
catch (CMemoryException* e)
{
e->ReportError();
}
int i = 0;
m_student.MoveFirst();
while (!m_student.IsEOF())
{
m_listctrl.InsertItem(i, m_student.m_numbe);//strtitle
m_listctrl.SetItemText(i, 1, m_student.m_name);
m_listctrl.SetItemText(i, 2, m_student.m_sex);
m_listctrl.SetItemText(i, 3, m_student.m_dateofbirth);
m_listctrl.SetItemText(i, 4, m_student.m_education);
m_listctrl.SetItemText(i, 5, m_student.m_job);
m_listctrl.SetItemText(i, 6, m_student.m_phonecode);
m_listctrl.SetItemText(i, 7, m_student.m_address);
/* m_listCtrl.InsertItem(index, m_student.m_Sname);
m_studentList.SetItemText(index, 1, m_student.m_Sage);*/
m_student.MoveNext();
i++;
}
m_student.Close();
}
返回主页面,给显示按钮添加事件处理函数
3.2实现查询功能
高版本的VS中先在C…View类的DoDataExchange函数添加以下语句
DDX_FieldText(pDX, IDC_EDIT_NUMBER, m_pSet->m_number, m_pSet);
DDX_FieldText(pDX, IDC_EDIT_NAME, m_pSet->m_name, m_pSet);
DDX_FieldText(pDX, IDC_EDIT_SEX, m_pSet->m_sex, m_pSet);
DDX_FieldText(pDX, IDC_EDIT_DATE, m_pSet->m_dateofbirth, m_pSet);
DDX_FieldText(pDX, IDC_EDIT_EDUCATION, m_pSet->m_education, m_pSet);
DDX_FieldText(pDX, IDC_EDIT_JOB, m_pSet->m_job, m_pSet);
DDX_FieldText(pDX, IDC_EDIT_PHONE, m_pSet->m_phonecode, m_pSet);
DDX_FieldText(pDX, IDC_EDIT_ADDRESS, m_pSet->m_address, m_pSet);
DDX_Text(pDX, IDC_EDIT_RESULT, m_query);//查询控件的
页面设计如下
右键,给查询编辑控件设置变量,名字自己喜好来
同样右键为查询按钮填加事件处理函数
代码如下:
void CCEmployeemanaView::OnBnClickedButtonQuery()
{
// TODO: 在此添加控件通知处理程序代码
UpdateData(TRUE);
m_query.TrimLeft();
if (m_query.IsEmpty())
{
MessageBox(L"要查询的编号或姓名不能为空!");
return;
}
if (m_pSet->IsOpen())
m_pSet->Close();//如果记录集打开,则先关闭
m_pSet->m_strFilter.Format(L"employeeinfor.name='%s'", m_query);
// m_pSet->m_strSort = "job";
m_pSet->Open();
if (!m_pSet->IsEOF())//如果打开的记录集有要找的记录
{
UpdateData(FALSE);//自动更新表单中控件显示的内容
}
else
MessageBox(L"没有查到你要找员工");
}
3.3实现添加功能
在主页面添加添加按钮并为其添加事件处理函数
添加一个对话框(内容可以直接从主页面拷贝)并为它添加类和所需成员变量
不要忘记为变量添加以下代码
void CAdd::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Text(pDX, IDC_EDIT_NUMBER,m_numberr);
DDX_Text(pDX, IDC_EDIT_NAME,m_namee);
DDX_Text(pDX, IDC_EDIT_SEX, m_sexx);
DDX_Text(pDX, IDC_EDIT_DATE,m_date);
DDX_Text(pDX, IDC_EDIT_EDUCATION, m_educa);
DDX_Text(pDX, IDC_EDIT_JOB, m_jo);
DDX_Text(pDX, IDC_EDIT_PHONE,m_phonn);
DDX_Text(pDX, IDC_EDIT_ADDRESS,m_address);
}
事件处理函数的代码如下:
void CCEmployeemanaView::OnBnClickedButtonAddd()
{
// TODO: 在此添加控件通知处理程序代码
CAdd dlg;
if (dlg.DoModal() == IDOK)
{
if (dlg.m_numberr.IsEmpty() || dlg.m_namee.IsEmpty() || dlg.m_sexx.IsEmpty() || dlg.m_date.IsEmpty() ||
dlg.m_educa.IsEmpty() || dlg.m_jo.IsEmpty() || dlg.m_phonn.IsEmpty() || dlg.m_address.IsEmpty())
{
MessageBox(L"添加失败,有信息没有填写完,请仔细检查!");
}
else{
m_pSet->AddNew();//在表的末尾添加记录
// m_pSet->SetFieldNull(&(m_pSet->m_numbe), FALSE);
m_pSet->m_numbe = dlg.m_numberr;
m_pSet->m_name = dlg.m_namee;
m_pSet->m_sex = dlg.m_sexx;
m_pSet->m_dateofbirth = dlg.m_date;
m_pSet->m_education = dlg.m_educa;
m_pSet->m_job = dlg.m_jo;
m_pSet->m_phonecode = dlg.m_phonn;
m_pSet ->m_address = dlg.m_address;
m_pSet->Update();//将新记录存入数据库
m_pSet->Requery();//刷新记录集
MessageBox(L"添加成功");
}
}
}
3.4实现删除功能
添加删除按钮,并添加事件处理函数
代码如下
void CCEmployeemanaView::OnBnClickedButtonDelete()
{
int a = AfxMessageBox(_T("确认删除?"), MB_OKCANCEL | MB_ICONQUESTION);
if (a == 2)
{
return;
}//防止错误删除
else
{
CRecordsetStatus Dss;
m_pSet->GetStatus(Dss);//获取当前记录集
m_pSet->Delete();
if (Dss.m_lCurrentRecord == 0)
{
m_pSet->MoveNext();
}
else
m_pSet->MoveFirst();
UpdateData(FALSE);
}
}
int a =AfxMessageBox(_T(“继续吗?”),MB_OKCANCEL|MB_ICONQUESTION);
点击确定,函数返回值为1
点击取消,函数返回值为2
3.5实现修改功能
添加事件处理函数
void CCEmployeemanaView::OnBnClickedButtonEdiit()
{
// TODO: 在此添加控件通知处理程序代码
CAdd dl;
dl.m_numberr =m_pSet->m_numbe;
dl.m_namee =m_pSet->m_name ;
dl.m_sexx =m_pSet->m_sex ;
dl.m_date =m_pSet->m_dateofbirth ;
dl.m_educa = m_pSet->m_education;
dl.m_jo = m_pSet->m_job;
dl.m_phonn = m_pSet->m_phonecode;
dl.m_address = m_pSet->m_address;
if (dl.DoModal() == IDOK)
{
m_pSet->Edit();//修改
m_pSet->m_numbe = dl.m_numberr;
m_pSet->m_name = dl.m_namee;
m_pSet->m_sex = dl.m_sexx;
m_pSet->m_dateofbirth = dl.m_date;
m_pSet->m_education = dl.m_educa;
m_pSet->m_job = dl.m_jo;
m_pSet->m_phonecode = dl.m_phonn;
m_pSet->m_address = dl.m_address;
m_pSet->Update();
UpdateData(FALSE);
MessageBox(L"修改成功");
}
}
3.6 完善一下,在主页面实现上一个下一个功能
void CCEmployeemanaView::OnBnClickedButtonLast()
{
// TODO: 在此添加控件通知处理程序代码
CRecordsetStatus ss;
m_pSet->GetStatus(ss);//获取当前记录集 /*if (ss.m_lCurrentRecord == 0)*/
m_pSet->MovePrev();
UpdateData(FALSE);
}
下一个
void CCEmployeemanaView::OnBnClickedButtonNext()
{
// TODO: 在此添加控件通知处理程序代码
CRecordsetStatus ss;
m_pSet->GetStatus(ss);//获取当前记录集
/*if (ss.m_lCurrentRecord == 0)*/
m_pSet->MoveNext();
UpdateData(FALSE);
}
好了,一个粗略的员工管理系统就完成了
整体
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ls6DxIOu-1655026874845)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20220520131459669.png)]
4.添加背景音乐
加头文件
include “windows.h”
include “mmsystem.h”
pragma comment( lib, “Winmm.lib” )
在res文件夹中添加WAV格式的音乐
在添加资源自定义WAVA然后导入WAV格式音乐,可能会比较诡异,文件夹变为WAVE,然后命名该文件ID
右键对话框属性,类向导,消息,添加WM_CREATE,添加处理程序,
int CCEmployeemanaView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CRecordView::OnCreate(lpCreateStruct) == -1)
return -1;
PlaySound((LPCTSTR)IDR_WAVAM, AfxGetResourceHandle(), SND_RESOURCE | SND_ASYNC);
// TODO: 在此添加您专用的创建代码
return 0;
}