VS2015 MFC对access2010数据库的增删改查,子对话框修改,双击修改,combobox查询。

VS2015 MFC对access2010数据库的增删改查
特点:1,把access内容导入list control后,可以实现双击修改list control的同时,修改数据库,也可以通过子弹窗修改数据库
2,查询可以通过combo—box实现便捷查询
3,删除可以通过单击listcontrol中的任意一行实现删除,如果单击到空白处,会提示

首先准备vs2015与access2010;
先连接数据库:网上方法有很多,我的office是64位的,所以debug,x64。!!!!!!否则连不上,如果你的机子上是32位的office,那就x86。

下面展示 连接数据库的代码。

try {

		CoInitialize(NULL);
		m_pConnection = _ConnectionPtr(__uuidof(Connection));
		m_pConnection->ConnectionTimeout = 5; //设置超时时间为5秒
		m_pConnection->ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=access.accdb;";
		m_pConnection->Open("", "", "", adConnectUnspecified);
		
		/*_variant_t   RecordsAffected;
		CString strSql;
		BSTR bstrSQL;
		strSql = _T("CREATE TABLE acces(ID INTEGER,图书编码 REAL,图书名称 REAL,图书作者 REAL,出版社名 REAL )");//INTEGER
		bstrSQL = strSql.AllocSysString();
		m_pConnection->Execute(bstrSQL, &RecordsAffected, adCmdText);*/
	
		AfxMessageBox(_T("数据库连接成功"));
	}
	catch (_com_error e) {
		//m_pConnection->ConnectionTimeout = 5; //设置超时时间为5秒
		AfxMessageBox(_T("数据库连接失败!"));
		return FALSE;
	}

一定要分清数据库和表,我这里在工程目录下放置数据库,我的数据库名字是access,数据库可以有很多表,我这次操作的表名是acces,(少一个s)。当然你可以任意名字
一定要分清数据库和表,我这里在工程目录下放置数据库,我的数据库名字是access,数据库可以有很多表,我这次操作的表名是acces,(少一个s)。当然你可以任意名字。
下面展示 创建list control表头的代码

CoUninitialize();
	// TODO:  在此添加额外的初始化代码
	CRect rect;

	// 获取编程语言列表视图控件的位置和大小
	m_list.GetClientRect(rect);

	// 为列表视图控件添加全行选中和栅格风格   
	m_list.SetExtendedStyle(m_list.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);

	// 为列表视图控件添加三列   
	m_list.InsertColumn(0, _T("ID"), LVCFMT_CENTER, rect.Width() / 5, 0);
	m_list.InsertColumn(1, _T("图书编码"), LVCFMT_CENTER, rect.Width() / 5, 0);
	m_list.InsertColumn(2, _T("图书名称"), LVCFMT_CENTER, rect.Width() / 5, 1);
	m_list.InsertColumn(3, _T("图书作者"), LVCFMT_CENTER, rect.Width() / 5, 2);
	m_list.InsertColumn(4, _T("出版社名"), LVCFMT_CENTER, rect.Width() / 5, 3);

下面展示把access内容导入list control的代码

izengjia=1;//每次导入都置1,这个变量也是为了减少bug
	m_list.DeleteAllItems();//清空列表
	_variant_t RecordsAffected;
	CString  ha;
	try {
		ha = "select * from acces";    //查询ZRN表里的数据
		m_pRecordset = m_pConnection->Execute(ha.AllocSysString(), &RecordsAffected, adCmdText);   //获取记录集
		int i = 0;
		while (!m_pRecordset->adoEOF)
		{
			id = (char*)(_bstr_t)m_pRecordset->GetCollect("ID");
			bm = (char*)(_bstr_t)m_pRecordset->GetCollect("图书编码");    //xm,dz,yb 分别为你自己数据库的列名
			mc = (char*)(_bstr_t)m_pRecordset->GetCollect("图书名称");     //把这一记录中数据库里dz列下的值给字符串dz
			zz = (char*)(_bstr_t)m_pRecordset->GetCollect("图书作者");
			cb = (char*)(_bstr_t)m_pRecordset->GetCollect("出版社名");
			m_list.InsertItem(i, _T(""));
			m_list.SetItemText(i, 0, id);     //添加到list Control 中的第i行的第一列下
			m_list.SetItemText(i, 1, bm);     //添加到list Control 中的第i行的第二列下
			m_list.SetItemText(i, 2, mc);     //添加到list Control 中的第i行的第三列下
			m_list.SetItemText(i, 3, zz);     //添加到list Control 中的第i行的第四列下
			m_list.SetItemText(i, 4, cb);     //添加到list Control 中的第i行的第五列下
			i += 1;   //下次循环指向第2行
			m_pRecordset->MoveNext();   //移动到下一个记录
		}
		return;
	}

	catch (_com_error e)
	{
		CString a;
		a.Format(_T("%s"), (LPCTSTR)e.Description());
		//MessageBox(a);
		return;
	}

下面是增加数据,需要说明一下的就是,这里是对list control和access数据库同时操作,其实两者没什么关系,我是为了方便观察,才这样写;
下面展示 增加数据
这是增加数据的页面展示
增加数据

try
		{
			CString strCmd;
			GetDlgItemText(IDC_EDIT2, m_fu_bm);//对输入编辑框的内容进行获取
			GetDlgItemText(IDC_EDIT3, m_fu_mc);
			GetDlgItemText(IDC_EDIT5, m_fu_zz);
			GetDlgItemText(IDC_EDIT6, m_fu_sm);
			int nNowRow = m_list.GetItemCount();
			CString str;
			str.Format(_T("%d"), _ttoi(id) + izengjia);
			int nRow = m_list.InsertItem(nNowRow, str);//插入的是某行的首列位置,返回的是该行的位置。
			m_list.SetItemText(nRow, 1, m_fu_bm);//写入某行第二列内容信息
			m_list.SetItemText(nRow, 2, m_fu_mc);//写入某行第二列内容信息
			m_list.SetItemText(nRow, 3, m_fu_zz);//写入某行第二列内容信息
			m_list.SetItemText(nRow, 4, m_fu_sm);//写入某行第二列内容信息
			//strCmd="INSERT INTO [acces](ID,图书编码,图书名称,图书作者,出版社名) VALUES(10,'1003','传记','赵峰','人民')";//这里很容易把逗号写成中文的,在这里看不出来,要在sql中运行。
			strCmd.Format(_T("INSERT INTO [acces](图书编码,图书名称,图书作者,出版社名) VALUES('%s','%s','%s','%s')"), m_fu_bm, m_fu_mc, m_fu_zz, m_fu_sm);
				m_pConnection->Execute(strCmd.AllocSysString(), &RecordsAffected, adCmdText);
		}
		catch (_com_error &e)
		{
			CString a;
			a.Format(_T("fail \r\n错误信息: %s"), (LPCTSTR)e.Description());//正确的提示错误
			MessageBox(a);
			return;
			}
		MessageBox(_T("添加成功!"),_T("消息"));
		izengjia ++ ;//这是个全局变量,为了减少bug,如果调试成功了可以体会一下。

下面展示 修改数据
修改数据在父界面就一个按钮,我就不放在这里了,下面是修改数据的子界面。
在这里插入图片描述

这个是父页面修改按钮下的函数
_variant_t RecordsAffected;		
		POSITION ps = m_list.GetFirstSelectedItemPosition();
		int nowRow = m_list.GetNextSelectedItem(ps);//选中的哪行的索引)
		if (nowRow == -1)                   //nItem 没有选中列表数据时 返回值位-1
		{
			AfxMessageBox(_T("选中一行再更改"));
			return;
		}
		int i = m_list.GetSelectionMark();
		CString   m;
		m = m_list.GetItemText(i, 0);//第i行第0列
		CString   s;
		int dm;
		s = m_list.GetItemText(nowRow, 0);//第i行第0列
		dm = _ttoi(s);
		CString id = _T(""), bm = _T(""), mc = _T(""), zz = _T(""), sm = _T("");//初始化为空
		id = m_list.GetItemText(nowRow, 0);
		bm = m_list.GetItemText(nowRow, 1);
		mc = m_list.GetItemText(nowRow, 2);
		zz = m_list.GetItemText(nowRow, 3);
		sm = m_list.GetItemText(nowRow, 4);
		zibianjikuang_ok* dlg = new zibianjikuang_ok();//非模态对话框
		dlg->m_zi_id = id;
		dlg->m_zi_bm = bm;
		dlg->m_zi_mc = mc;
		dlg->m_zi_zz = zz;
		dlg->m_zi_sm = sm;//传递到子编辑框过去了
        dlg->Create(IDD_DIALOG1, this);
		dlg->ShowWindow(SW_SHOW);
		
		UpdateData(TRUE);

下面展示 子界面的代码。主要是对确定按钮的修改,细节可以自行调通

CMFCaccessDlg * parent = (CMFCaccessDlg*)GetParent();
		POSITION ps = parent->m_list.GetFirstSelectedItemPosition();
		int nNowRow = parent->m_list.GetNextSelectedItem(ps);//选中的哪行的索引)
		GetDlgItemText(IDC_EDIT1, zsm);//获取用户输入的内容
		GetDlgItemText(IDC_EDIT2, zmc);
		GetDlgItemText(IDC_EDIT3, zbm);//获取用户输入的内容
		GetDlgItemText(IDC_EDIT4, zid);
		GetDlgItemText(IDC_EDIT5, zzz);//获取用户输入的内容
		parent->m_list.SetItemText(nNowRow, 0, zid);//插入的是某行的首列位置,返回的是该行的位置。
		parent->m_list.SetItemText(nNowRow, 1, zbm);//写入某行第二列内容信息
		parent->m_list.SetItemText(nNowRow, 2, zmc);//写入行第二列内容信息
		parent->m_list.SetItemText(nNowRow, 3, zzz);//写入某行第二列内容信息
		parent->m_list.SetItemText(nNowRow, 4, zsm);//写入某行第二列内容信息
		CMFCaccessDlg *parent_dlg = (CMFCaccessDlg *)GetParent();// m_MFCaccessDlg;  //强制转换为父窗口类型
		parent_dlg->xiugaishujuku();  //调用父窗口函数,xiugaishujuku()是父cpp中的函数,在子窗口对其进行调用。
	

下面展示 CMFXCaccessDlg中xiugaishujuku()函数的代码

_variant_t RecordsAffected;
	POSITION ps = m_list.GetFirstSelectedItemPosition();
	int nowRow = m_list.GetNextSelectedItem(ps);//选中的哪行的索引)
	if (nowRow == -1)                   //nItem 没有选中列表数据时 返回值位-1
	{
		AfxMessageBox(_T("选中一行再更改"));
		return;
	}
	int i = m_list.GetSelectionMark();
	CString   s;
	int dm;
	s = m_list.GetItemText(nowRow, 0);//第i行第0列
	dm = _ttoi(s);
	try
	{
	CString strCmd;
	CString   n;
	n = m_list.GetItemText(i, 1);//第i行第0列
	CString   x;
	x = m_list.GetItemText(i, 2);//第i行第0列
	CString   y;
	y = m_list.GetItemText(i, 3);//第i行第0列
	CString   z;
	z = m_list.GetItemText(i, 4);//第i行第0列
	strCmd.Format(_T("UPDATE acces SET [图书编码]='%s',[图书名称]='%s',[图书作者]='%s',[出版社名]='%s' WHERE [ID]=%d"),  n, x, y, z,dm);
	m_pConnection->Execute(strCmd.AllocSysString(), &RecordsAffected, adCmdText);
	}
	catch (_com_error &e)
	{
	MessageBox(e.Description(),_T("修改失败"), MB_ICONEXCLAMATION);
	return;
	}
	MessageBox(_T("修改成功!"),_T("消息"));

下面展示 双击list control一行修改list control和数据库。具体细节以后会更,或者下载我的工程

void CMFCaccessDlg::OnNMDblclkList1(NMHDR *pNMHDR, LRESULT *pResult)//双击的函数
{
	LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
	// TODO: 在此添加控件通知处理程序代码
	POSITION ps = m_list.GetFirstSelectedItemPosition();
	int nItem = m_list.GetNextSelectedItem(ps);//选中的哪行的索引)

	if (nItem == -1)                   //nItem 没有选中列表数据时 返回值位-1
	{
		AfxMessageBox(_T("这里没有数据,不能执行修改操作"));
		return;
	}
	NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
	CRect rc;
	m_Row = pNMListView->iItem;//获得选中的行,全局变量
	m_Col = pNMListView->iSubItem;//获得选中列,全局变量
	if (m_Col == 0)
	{
		MessageBox(_T("ID不能修改"));
		return;
	}
	int n = m_list.GetItemCount();//获取当前一共多少行
	if (pNMListView->iSubItem != 0) //如果选择的是子项;
	{
		m_list.GetSubItemRect(m_Row, m_Col, LVIR_LABEL, rc);//获得子项的RECT;
		m_edit_yincang.SetParent(&m_list);//转换坐标为列表框中的坐标
		m_edit_yincang.MoveWindow(rc);//移动Edit到RECT坐在的位置;
		m_edit_yincang.SetWindowText(m_list.GetItemText(m_Row, m_Col));//将该子项中的值放在Edit控件中;
		m_edit_yincang.ShowWindow(SW_SHOW);//显示Edit控件;
		m_edit_yincang.SetFocus();//设置Edit焦点,双击的数字变没
		m_edit_yincang.ShowCaret();//显示光标,显示数字
		m_edit_yincang.SetSel(-1);//将光标移动到最后
		if (m_Row == n - 1)
		{
			m_list.InsertItem(m_Row + 1, _T(""));
		}
	}
	
	*pResult = 0;
}
void CMFCaccessDlg::OnEnKillfocusEdit7()//这是修改的edit
{
	// TODO: 在此添加控件通知处理程序代码
	CString str;
	m_edit_yincang.GetWindowTextW(str);//将指定窗口的标题拷贝到缓存区
	m_list.SetItemText(m_Row, m_Col, str);//insertitem只操作第一列,set也是插入
	_variant_t RecordsAffected;	
	CString   s;
	int dm;
	s = m_list.GetItemText(m_Row, 0);//第i行第0列
	dm = _ttoi(s);
	
		if (m_Col == 1)
		{
			try
			{
				CString a;
				a.Format(_T("update  acces set [图书编码]='%s'where [ID]=%d "), str, dm);
				m_pConnection->Execute(a.AllocSysString(), &RecordsAffected, adCmdText);

				return;
			}
			catch (_com_error e)
			{
					CString a;
					a.Format(_T("%s"), (LPCTSTR)e.Description());
					MessageBox(a);
					return;
			}
		}
		if (m_Col == 2)
		{
			try
			{
				CString a;
				a.Format(_T("update  acces set [图书名称]='%s'where [ID]=%d "), str, dm);
				m_pConnection->Execute(a.AllocSysString(), &RecordsAffected, adCmdText);
				return;
			}
			catch (_com_error e)
			{
				CString a;
				a.Format(_T("%s"), (LPCTSTR)e.Description());
				MessageBox(a);
				return;
			}
		}
		if (m_Col == 3)
		{
			try
			{
				CString a;
				a.Format(_T("update  acces set [图书作者]='%s'where [ID]=%d "), str, dm);
				m_pConnection->Execute(a.AllocSysString(), &RecordsAffected, adCmdText);

				return;
			}
			catch (_com_error e)
			{
				CString a;
				a.Format(_T("%s"), (LPCTSTR)e.Description());
				MessageBox(a);
				return;
			}
		}
		if (m_Col == 4)
		{
			try
			{
				CString a;
				a.Format(_T("update  acces set [出版社名]='%s'where [ID]=%d "), str, dm);
				m_pConnection->Execute(a.AllocSysString(), &RecordsAffected, adCmdText);

				return;
			}
			catch (_com_error e)
			{
				CString a;
				a.Format(_T("%s"), (LPCTSTR)e.Description());
				MessageBox(a);
				return;
			}
		}
	m_edit_yincang.ShowWindow(SW_HIDE);
}

下面展示查询
这是查询的界面,关键字是当你在查询类别中选中了查询的一列后,数据的具体的查询内容
查询

m_list.DeleteAllItems();//清空列表
	UpdateData(TRUE);
	try {
		UpdateData(TRUE);
		CString m_tablefield, m_searchsql;
		UpdateData(TRUE);
		GetDlgItemText(IDC_COMBO1, m_fu_ccombo);
		m_tablefield = m_fu_ccombo;
		GetDlgItemText(IDC_EDIT1, m_fu_id);
		if (m_fu_ccombo == "ID")//如果是整数类型
		{
			try
			{
				m_tablefield = "ID";
				int m;
			m = _ttoi(m_fu_id);
			m_searchsql.Format(_T("select* from acces where %s=%d"), m_tablefield, m);
			m_pRecordset.CreateInstance("ADODB.Recordset");
			m_pRecordset->Open(m_searchsql.GetBuffer(),
				_variant_t((IDispatch*)m_pConnection, true),
				adOpenStatic,
				adLockOptimistic,
				adCmdText);

			//处理数据,并显示
			_variant_t varbuffer;
			long index = 0;//注意:必须是long类型
			int countItem = 0;
			CString str;
			while (!m_pRecordset->adoEOF)
			{
				index = 0;
				//读ID号
				varbuffer = m_pRecordset->GetCollect(_variant_t(index));
				if (varbuffer.vt != VT_NULL)
				{
					str.Format(_T("%d"), varbuffer.lVal);
					m_list.InsertItem(countItem, str.GetBuffer());
				}
				//读其它的信息
				while (index < 4)//显示出4列数据
				{
					index++;
					varbuffer = m_pRecordset->GetCollect(_variant_t(index));
					if (varbuffer.vt != VT_NULL)
					{
						str = (LPCTSTR)(_bstr_t)varbuffer;
						m_list.SetItemText(countItem, index, str.GetBuffer());
					}
				}
				m_pRecordset->MoveNext();
				countItem++;
			}
			return;
		}
		catch (_com_error &e)
		{
			MessageBox(e.Description(), _T("数据库操作失败."), MB_ICONEXCLAMATION);
			return;
		}	
		}
		m_searchsql.Format(_T("select* from acces where %s='%s'"), m_tablefield, m_fu_id);
		m_pRecordset.CreateInstance("ADODB.Recordset");
		m_pRecordset->Open(m_searchsql.GetBuffer(),
			_variant_t((IDispatch*)m_pConnection, true),
			adOpenStatic,
			adLockOptimistic,
			adCmdText);

		//处理数据,并显示
		_variant_t varbuffer;
		long index = 0;//注意:必须是long类型
		int countItem = 0;
		CString str;

		while (!m_pRecordset->adoEOF)
		{
			index = 0;
			//读ID号
			varbuffer = m_pRecordset->GetCollect(_variant_t(index));
			if (varbuffer.vt != VT_NULL)
			{
				str.Format(_T("%d"), varbuffer.lVal);
				m_list.InsertItem(countItem, str.GetBuffer());
			}
			while (index < 4)//显示出4列数据,可以根据实际情况修改
			{
				index++;
				varbuffer = m_pRecordset->GetCollect(_variant_t(index));
				if (varbuffer.vt != VT_NULL)
				{
					str = (LPCTSTR)(_bstr_t)varbuffer;
					m_list.SetItemText(countItem, index, str.GetBuffer());
				}
			}

			m_pRecordset->MoveNext();
			countItem++;
		}
	}
		catch (_com_error &e)
		{
			//AfxMessageBox(e.Description());
			MessageBox(e.Description(), _T("数据库操作失败."), MB_ICONEXCLAMATION);
			//if (m_pRecordset->State)
			//	m_pRecordset->Close();
			return;
		}

下面展示 combo box。这个代码是在父cpp也就是CMFCaccessDlg的OnInitDialog()函数下写的。
而combo box不需要写。


	m_fu_combo.AddString(_T("ID"));   //添加字符串  
	m_fu_combo.AddString(_T("图书编码"));
	m_fu_combo.AddString(_T("图书名称"));
	m_fu_combo.AddString(_T("图书作者"));
	m_fu_combo.AddString(_T("出版社名"));
	m_fu_combo.SetCurSel(0);   //默认选择第一个  
	

下面展示 删除
删除在主界面就一个按钮,就不多说了。

	int i = m_list.GetSelectionMark();
  CString   s;
	s = m_list.GetItemText(i,0);//第i行第0列
	CString strCmd;
	try
	{
		CString strCmd;
		int m;
		m = _ttoi(s);
		strCmd.Format(_T("delete *from acces where ID=%d"),m);
		m_pConnection->Execute(strCmd.AllocSysString(), &RecordsAffected, adCmdText);//execute,执行
	}
	catch (_com_error &e)
	{
		CString a;
		a.Format(_T("fail \r\n错误信息: %s"), (LPCTSTR)e.Description());//正确的提示错误
		MessageBox(a);
		return;
	}
	MessageBox(_T("删除成功!"),_T("完成"));
	POSITION ps = m_list.GetFirstSelectedItemPosition();
	int nItem = m_list.GetNextSelectedItem(ps);//选中的哪行的索引)
	if (nItem == -1)                   //nItem 没有选中列表数据时 返回值位-1
	{
		AfxMessageBox(_T("这里没有数据,不能执行删除操作"));
		return;
	}
	m_list.DeleteItem(nItem);
	UnlockWindowUpdate();//点完删除就刷新

如果你对里面的变量看不懂,可以下载。也可以问我,我看见会回复。

链接: https://download.csdn.net/download/Zoffan/12427743.

  • 1
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值