MFC DAO 数据库 学习

1. 初始化程序 - - 这是在 初始化代码那添加[ xxx:OnInitDialog() ]
// 连接数据库
this->db.Open ( L"book.mdb", FALSE, FALSE, NULL ) ;

2. 添加数据代码块

void CDAOSampleDlg::OnBnClickedAdd()
{
// 检测数据库是否已连接
if ( this->db.IsOpen () == FALSE )
{
   this->MessageBox ( L"未连接数据库!" ) ;
   return ;
}

// 定义记录集对象,打开记录集
CDaoRecordset Record ( &this->db ) ;
Record.Open ( dbOpenDynaset, L"SELECT * FROM BOOK" ) ;

// 定义对话框对象,并设置为“添加”模式
CMyDlg AddBookDlg ;
AddBookDlg.SetMode ( TRUE ) ;

if ( AddBookDlg.DoModal() == IDOK )
{
   // 使用CDaoRecordset::AddNew函数表明要开始添加新记录
   Record.AddNew () ;
   // 设置新记录
   Record.SetFieldValue ( 1, AddBookDlg.GetName().GetBuffer() ) ;
   Record.SetFieldValue ( 2, AddBookDlg.Getsex().GetBuffer() ) ;
   Record.SetFieldValue ( 3, AddBookDlg.GetDiscipline ().GetBuffer() ) ;
   Record.SetFieldValue ( 4, AddBookDlg.GetQuarters ().GetBuffer() ) ;
   Record.SetFieldValue ( 5, AddBookDlg.GetYQQ().GetBuffer() ) ;
   Record.SetFieldValue ( 6, AddBookDlg.Getsection ().GetBuffer() ) ;
   Record.SetFieldValue ( 7, AddBookDlg.GetNotes ().GetBuffer() ) ;
   Record.SetFieldValue ( 8, AddBookDlg.GetMobile ().GetBuffer() ) ;
   Record.SetFieldValue ( 9, AddBookDlg.GetBranches ().GetBuffer() ) ;
   Record.SetFieldValue ( 10, AddBookDlg.GetIDcard ().GetBuffer() ) ;
   CString szTempStr ;
   szTempStr.Format ( L"%d", AddBookDlg.GetVIP() ) ;
   Record.SetFieldValue ( 11, szTempStr.GetBuffer() ) ;
   CString szTempStr1 ;
   szTempStr1.Format ( L"%d", AddBookDlg.GetNID() ) ;
   Record.SetFieldValue ( 12, szTempStr1.GetBuffer() ) ;

  
   // 只有在执行CDaoRecordset::Update函数后才会写入到数据库
   Record.Update () ;
   // 关闭记录集
   Record.Close () ;
   // 刷新界面列表控件数据显示
   this->OnBnClickedFlush () ;
   // 重新返回到添加代码框
   this->OnBnClickedAdd() ;
}
}

这其中可以看出.. 程序先打开了 数据库的记录集并且又打开了另一个对话框
AddBookDlg 将填写好的内容 使用 Record.SetFieldValue 函数将其保存进数据库中。

3.删除功能的代码块

void CDAOSampleDlg::OnBnClickedDel()
{
// 检测数据库是否已连接
if ( this->db.IsOpen () == FALSE )
{
   this->MessageBox ( L"未连接数据库!" ) ;
   return ;
}

// 检查是否已选择书目
int nCurSel = this->BookList.GetNextItem(-1,LVNI_SELECTED);
if ( nCurSel == -1 )
{
   this->MessageBox ( L"请选择一个会员!" ) ;
   return ;
}

// 定义记录集对象,并移动指针到指定位置
CDaoRecordset Record ( &this->db ) ;

Record.Open ( dbOpenDynaset, L"SELECT * FROM BOOK" ) ;
Record.Move (nCurSel) ;
// 删除当前记录
Record.Delete () ;
// 关闭记录集
Record.Close () ;
this->MessageBox ( L"删除成功!" ) ;

// 刷新界面列表控件数据显示
    this->OnBnClickedFlush () ;

}

使用 CListCtrl 控件中的 GetNextItem 函数 返回.. 被选中的项目 ID
然后 打开记录集... 移到(Move ())指定的 项目集上.. 使用Delete () 函数操作。
最后在 调用 刷新。

4.刷新数据内容

void CDAOSampleDlg::OnBnClickedFlush()
{
// 检测数据库是否已连接
if ( this->db.IsOpen () == FALSE )
{
   this->MessageBox ( L"未连接数据库!" ) ;
   return ;
}

// 删除列表控件所有记录
this->BookList.DeleteAllItems () ;

// 定义记录集对象,并打开记录集
CDaoRecordset Record ( &this->db ) ;
Record.Open ( dbOpenDynaset, L"SELECT * FROM BOOK" ) ;

UINT   nIndex = 0 ;
CString   TempStr ;
COleVariant OleVariant ;

// 移动到第一条记录
Record.MoveFirst () ;
while( !Record.IsEOF() )
{
   // 在列表控件添加记录
   TempStr.Format ( L"%d", nIndex+1 ) ;
   this->BookList.InsertItem ( nIndex, TempStr ) ;

   for ( int i = 1; i <= 10; i++ )
   {
    Record.GetFieldValue ( i, OleVariant ) ;
    this->BookList.SetItemText ( nIndex, i, OleVariant.bstrVal) ;
   }

   Record.GetFieldValue ( 11, OleVariant ) ;
   TempStr.Format ( L"%d", OleVariant.uintVal ) ;
   this->BookList.SetItemText ( nIndex, 11, TempStr ) ;

   Record.GetFieldValue ( 12, OleVariant ) ;
   TempStr.Format ( L"%d", OleVariant.uintVal ) ;
   this->BookList.SetItemText ( nIndex, 12, TempStr ) ;

   // 移到下一条记录
   Record.MoveNext () ;
   nIndex++ ;
}

CString num;  
num.Format(_T("%d"),nIndex);  
SetDlgItemText(IDC_TJ_STATIC,_T("人数统计:")+num);

// 关闭记录集
Record.Close () ;
}

开口记录集... 然后 使用 While 循环中使用Record.GetFieldValue函数对数据库内的内容进行穷举列出..
值得关注的是... 1 -10 的项目类型必须是 Cstring 而 11 和 12 的内容 位 UINT 类型。
   另外根据 nIndex 变量获得 相关 人数统计... 过程中 需要使用 Format 函数转化 位Cstring类型。
  
5. 查找数据模块

void CDAOSampleDlg::OnBnClickedQuery()
{
// TODO: 在此添加控件通知处理程序代码
//测试
//CListCtrl& list;    // 需要查找的LIST

// 检测数据库是否已连接
if ( this->db.IsOpen () == FALSE )
{
   this->MessageBox ( L"未连接数据库!" ) ;
   return ;
}

// 删除列表控件所有记录
this->BookList.DeleteAllItems () ;


// 定义记录集对象,并打开记录集


CString str1,str2;
int nLineNum;
nLineNum=0;
  
   // 根据从.. 类型表上获取相关 搜索关键此来确定应该对哪一个类别进行搜索
this->GetDlgItem(IDC_CONDITIONS_COMBO)->GetWindowTextW(str2);

if (str2 ==_T("姓名"))
{
   str2 = _T("Name");
}
else if (str2 ==_T("性别"))
{
   str2 = _T("sex");
    }
else if (str2 ==_T("性别"))
{
   str2 = _T("sex");
}
else if (str2 ==_T("专业班级"))
{
   str2 = _T("Discipline");
}
else if (str2 ==_T("住宿信息"))
{
   str2 = _T("Quarters");
}
else if (str2 ==_T("部门"))
{
   str2 = _T("section");
}
else if (str2 ==_T("系别"))
{
   str2 = _T("Branches");
}
else if (str2 ==_T("学号"))
{
   str2 = _T("NID");
}

// 从文本框上获取相关数据
NameEdit.GetLine(nLineNum,str1.GetBufferSetLength(NameEdit.LineLength(NameEdit.LineIndex(nLineNum))),20);
str1.ReleaseBuffer();

CString sql;  

// 最后根据条件列出所需要的数据。
sql.Format(_T("SELECT * FROM BOOK WHERE %s LIKE '*%s*'"), str2,str1);

CDaoRecordset Record ( &this->db ) ;
Record.Open ( dbOpenDynaset,sql ); // L"SELECT * FROM BOOK WHERE Name LIKE '*TempStr*'"

UINT   nIndex = 0 ;
CString   TempStr ;
COleVariant OleVariant ;

// 移动到第一条记录
Record.MoveFirst () ;
while( !Record.IsEOF() )
{
   // 在列表控件添加记录
   TempStr.Format ( L"%d", nIndex+1 ) ;
   this->BookList.InsertItem ( nIndex, TempStr ) ;

   for ( int i = 1; i <= 10; i++ )
   {
    Record.GetFieldValue ( i, OleVariant ) ;
    this->BookList.SetItemText ( nIndex, i, OleVariant.bstrVal) ;
   }

   Record.GetFieldValue ( 11, OleVariant ) ;
   TempStr.Format ( L"%d", OleVariant.uintVal ) ;
   this->BookList.SetItemText ( nIndex, 11, TempStr ) ;

   Record.GetFieldValue ( 12, OleVariant ) ;
   TempStr.Format ( L"%d", OleVariant.uintVal ) ;
   this->BookList.SetItemText ( nIndex, 12, TempStr ) ;

   // 移到下一条记录
   Record.MoveNext () ;
   nIndex++ ;
}

CString num;  

num.Format(_T("%d"),nIndex);  

SetDlgItemText(IDC_TJ_STATIC,_T("人数统计:")+num);

// 关闭记录集
Record.Close () ;

}

程序提供 了两个可选项进行搜索.. 首先设置好 条件,然后根据if判断条件
来确定.. 要搜索 数据库的类型字段... 接着截取.. 文本输入框的搜索条件
根据条件str1 代入数据记录集中进行查找... 然后使用 while 语句将 所要查找
内容列举出来。

 

6.修改数据库内容。

void CDAOSampleDlg::OnNMDblclkBookList(NMHDR *pNMHDR, LRESULT *pResult)
{

// 检测数据库是否已连接
if ( this->db.IsOpen () == FALSE )
{
   this->MessageBox ( L"未连接数据库!" ) ;
   return ;
}

// 检测是否选择书目
int nCurSel = this->BookList.GetNextItem ( -1,LVNI_SELECTED) ;
if ( nCurSel == -1 )
{
   this->MessageBox ( L"请选择一个会员!" ) ;
   return ;
}

// 定义记录集对象,并移动指针到指定位置
CDaoRecordset Record ( &this->db ) ;
Record.Open ( dbOpenDynaset, L"SELECT * FROM BOOK" ) ;
Record.Move ( nCurSel ) ;

// 定义对话框对象,并设置为“修改”模式
CMyDlg ModBookDlg ;
ModBookDlg.SetMode ( FALSE ) ;

// 把当前记录信息设置到对话框
COleVariant OleVariant ;
Record.GetFieldValue ( 1, OleVariant ) ;
ModBookDlg.SetName ( OleVariant.bstrVal ) ;
Record.GetFieldValue ( 2, OleVariant ) ;
ModBookDlg.Setsex ( OleVariant.bstrVal ) ;
Record.GetFieldValue ( 3, OleVariant ) ;
ModBookDlg.SetDiscipline ( OleVariant.bstrVal ) ;
Record.GetFieldValue ( 4, OleVariant ) ;
ModBookDlg.SetQuarters ( OleVariant.bstrVal ) ;
Record.GetFieldValue ( 5, OleVariant ) ;
ModBookDlg.SetYQQ ( OleVariant.bstrVal ) ;
Record.GetFieldValue ( 6, OleVariant ) ;
ModBookDlg.Setsection ( OleVariant.bstrVal ) ;
Record.GetFieldValue ( 7, OleVariant ) ;
ModBookDlg.SetNotes ( OleVariant.bstrVal ) ;
Record.GetFieldValue ( 8, OleVariant ) ;
ModBookDlg.SetMobile ( OleVariant.bstrVal ) ;
Record.GetFieldValue ( 9, OleVariant ) ;
ModBookDlg.SetBranches ( OleVariant.bstrVal ) ;
Record.GetFieldValue ( 10, OleVariant ) ;
ModBookDlg.SetIDcard ( OleVariant.bstrVal ) ;

Record.GetFieldValue ( 11, OleVariant ) ;
ModBookDlg.SetVIP ( OleVariant.uintVal ) ;
Record.GetFieldValue ( 12, OleVariant ) ;
ModBookDlg.SetNID ( OleVariant.uintVal ) ;


if ( ModBookDlg.DoModal () == IDOK )
{
   // 使用CDaoRecordset::Edit函数表明要开始修改当前记录
   Record.Edit () ;
   // 修改当前记录成员
   Record.SetFieldValue ( 1, ModBookDlg.GetName().GetBuffer() ) ;
   Record.SetFieldValue ( 2, ModBookDlg.Getsex().GetBuffer() ) ;
   Record.SetFieldValue ( 3, ModBookDlg.GetDiscipline ().GetBuffer() ) ;
   Record.SetFieldValue ( 4, ModBookDlg.GetQuarters ().GetBuffer() ) ;
   Record.SetFieldValue ( 5, ModBookDlg.GetYQQ().GetBuffer() ) ;
   Record.SetFieldValue ( 6, ModBookDlg.Getsection ().GetBuffer() ) ;
   Record.SetFieldValue ( 7, ModBookDlg.GetNotes ().GetBuffer() ) ;
   Record.SetFieldValue ( 8, ModBookDlg.GetMobile ().GetBuffer() ) ;
   Record.SetFieldValue ( 9, ModBookDlg.GetBranches ().GetBuffer() ) ;
   Record.SetFieldValue ( 10, ModBookDlg.GetIDcard ().GetBuffer() ) ;

   CString szTempStr ;
   szTempStr.Format ( L"%d", ModBookDlg.GetVIP() ) ;
   Record.SetFieldValue ( 11, szTempStr.GetBuffer() ) ;
   CString szTempStr1 ;
   szTempStr1.Format ( L"%d", ModBookDlg.GetNID() ) ;
   Record.SetFieldValue ( 12, szTempStr1.GetBuffer() ) ;

   // 只有在执行CDaoRecordset::Update函数后才会修改数据库记录
   Record.Update () ;
   // 关于记录集
   Record.Close () ;
   // 刷新界面列表控件数据显示
   this->OnBnClickedFlush () ;
}

}

程序,先通过 使用 CListCtrl 控件中的 GetNextItem 函数 返回.. 被选中的项目 ID
然后 打开记录集... 移到(Move ())指定的 项目集上.. 这时 调用 ModBookDlg ; 对话框
对内容 选定的数据内容进行读取,当对话框中的确定按钮被执行后在使用Record.SetFieldValue 函数成员
将内容保存进数据库中,最后在 调用 刷新。

7.转化为 Excel 文档的模块

首先先在 .cpp(非对话框) 文件中添加如下封装好的函数

//////////////////////////////////////////////////////////////////////////////
//名称:GetExcelDriver
//功能:获取ODBC中Excel驱动
//作者:徐景周(
[email protected])
//组织:未来工作室(Future Studio)
//日期:2002.9.1
/////////////////////////////////////////////////////////////////////////////
CString GetExcelDriver()
{
TCHAR szBuf[2001];
WORD cbBufMax = 2000;
WORD cbBufOut;
PTCHAR pszBuf = szBuf;
CString sDriver;

// 获取已安装驱动的名称(涵数在odbcinst.h里)
if (!SQLGetInstalledDrivers(szBuf, cbBufMax, &cbBufOut))
   return _T("");

// 检索已安装的驱动是否有Excel...
do
{
   if (_tcsstr(pszBuf, _T("Excel")) != 0)
   {
    //发现 !
    sDriver = CString(pszBuf);
    break;
   }
   pszBuf = wcschr(pszBuf,'/0') + 1;
}
while (pszBuf[1] != '/0');

return sDriver;
}

///////////////////////////////////////////////////////////////////////////////
// BOOL MakeSurePathExists( CString &Path,bool FilenameIncluded)
// 参数:
//   Path     路径
//   FilenameIncluded 路径是否包含文件名
// 返回值:
//   文件是否存在
// 说明:
//   判断Path文件(FilenameIncluded=true)是否存在,存在返回TURE,不存在返回FALSE
//   自动创建目录
//
///////////////////////////////////////////////////////////////////////////////


BOOL UnstrToAnstr (CString pWideCharStr, PSTR pMultiByteStr) {

int nLenOfMultiByteStr;
BOOL fOk = FALSE;  

nLenOfMultiByteStr = WideCharToMultiByte(CP_ACP, 0, pWideCharStr, -1,pMultiByteStr, (int)strlen(pMultiByteStr), NULL, NULL);  
pMultiByteStr = (PSTR)HeapAlloc(GetProcessHeap(), 0, nLenOfMultiByteStr * sizeof(char));
if (pMultiByteStr == NULL)  
   return(fOk);
WideCharToMultiByte(CP_ACP, 0, pWideCharStr, -1,pMultiByteStr,nLenOfMultiByteStr, NULL, NULL);  

HeapFree(GetProcessHeap(), 0, pMultiByteStr);  
return(fOk);  
}

 

BOOL MakeSurePathExists( CString &Path,
       bool FilenameIncluded)
{
int Pos=0;
while((Pos=Path.Find('//',Pos+1))!=-1)
   CreateDirectory(Path.Left(Pos),NULL);
if(!FilenameIncluded)
   CreateDirectory(Path,NULL);
// return ((!FilenameIncluded)?!_access(Path,0):
// !_access(Path.Left(Path.ReverseFind('//')),0));

char* ustf;

DWORD dwFileLen;
dwFileLen=Path.GetLength();
ustf=new char[dwFileLen+1];

UnstrToAnstr (Path,ustf) ;

return !_access(ustf,0);
}

//获得默认的文件名
BOOL GetDefaultXlsFileName(CString& sExcelFile)
{
///默认文件名:yyyymmddhhmmss.xls
CString timeStr;
CTime day;
day=CTime::GetCurrentTime();
int filenameday,filenamemonth,filenameyear,filehour,filemin,filesec;
filenameday=day.GetDay();//dd
filenamemonth=day.GetMonth();//mm月份
filenameyear=day.GetYear();//yyyy
filehour=day.GetHour();//hh
filemin=day.GetMinute();//mm分钟
filesec=day.GetSecond();//ss
timeStr.Format(_T("%04d%02d%02d%02d%02d%02d"),filenameyear,filenamemonth,filenameday,filehour,filemin,filesec);

sExcelFile = timeStr + _T(".xls");
// prompt the user (with all document templates)
CFileDialog dlgFile(FALSE,_T(".xls"),sExcelFile);
CString title;
CString strFilter;

title = "导出";
strFilter = "Excel文件(*.xls)";
strFilter += (TCHAR)'/0';   // next string please
strFilter += _T("*.xls");
strFilter += (TCHAR)'/0';   // last string
dlgFile.m_ofn.nMaxCustFilter++;
dlgFile.m_ofn.nFilterIndex = 1;
// append the "*.*" all files filter
CString allFilter;
VERIFY(allFilter.LoadString(AFX_IDS_ALLFILTER));
strFilter += allFilter;
strFilter += (TCHAR)'/0';   // next string please
strFilter += _T("*.*");
strFilter += (TCHAR)'/0';   // last string
dlgFile.m_ofn.nMaxCustFilter++;

dlgFile.m_ofn.lpstrFilter = strFilter;
dlgFile.m_ofn.lpstrTitle = title;

if (dlgFile.DoModal()==IDCANCEL)
   return FALSE; // open cancelled
sExcelFile.ReleaseBuffer();
if (MakeSurePathExists(sExcelFile,true)) {
   if(!DeleteFile(sExcelFile)) {    // delete the file
    AfxMessageBox(_T("覆盖文件时出错!"));
    return FALSE;
   }
}
return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
// void GetExcelDriver(CListCtrl* pList, CString strTitle)
// 参数:
//   pList   需要导出的List控件指针
//   strTitle 导出的数据表标题
// 说明:
//   导出CListCtrl控件的全部数据到Excel文件。Excel文件名由用户通过“另存为”
//   对话框输入指定。创建名为strTitle的工作表,将List控件内的所有数据(包括
//   列名和数据项)以文本的形式保存到Excel工作表中。保持行列关系。
//
// edit by [r]@dotlive.cnblogs.com
///////////////////////////////////////////////////////////////////////////////
void ExportListToExcel(CListCtrl* pList, CString strTitle)
{
CString warningStr;
if (pList->GetItemCount ()>0) {
   CDatabase database;
   CString sDriver;
   CString sExcelFile;
   CString sSql;
   CString tableName = strTitle;

   // 检索是否安装有Excel驱动 "Microsoft Excel Driver (*.xls)"
   sDriver = GetExcelDriver();
   if (sDriver.IsEmpty())
   {
    // 没有发现Excel驱动
    AfxMessageBox(_T("没有安装Excel!/n请先安装Excel软件才能使用导出功能!"));
    return;
   }

   ///默认文件名
   if (!GetDefaultXlsFileName(sExcelFile))
    return;

   // 创建进行存取的字符串
   sSql.Format(_T("DRIVER={%s};DSN='';FIRSTROWHASNAMES=1;READONLY=FALSE;CREATE_DB=/"%s/";DBQ=%s"),sDriver, sExcelFile, sExcelFile);

   // 创建数据库 (既Excel表格文件)
   if( database.OpenEx(sSql,CDatabase::noOdbcDialog) )
   {
    // 创建表结构
    int i;
    LVCOLUMN columnData;
    CString columnName;
    int columnNum = 0;
    CString strH;
    CString strV;

    sSql = "";
    strH = "";
    columnData.mask = LVCF_TEXT;
    columnData.cchTextMax =100;
    columnData.pszText = columnName.GetBuffer (100);
    for(i=0;pList->GetColumn(i,&columnData);i++)
    {
     if (i!=0)
     {
      sSql = sSql + _T(", ");
      strH = strH + _T(", ") ;
     }
     sSql = sSql + _T(" ") + columnData.pszText +_T(" TEXT");
     strH = strH + _T(" ") + columnData.pszText +_T(" ");
    }
    columnName.ReleaseBuffer ();
    columnNum = i;

    sSql = _T("CREATE TABLE ") + tableName + _T(" ( ") + sSql + _T(" ) ");
    database.ExecuteSQL(sSql);

    // 插入数据项
    int nItemIndex;
    for (nItemIndex=0;nItemIndex<pList->GetItemCount ();nItemIndex++){
     strV = "";
     for(i=0;i<columnNum;i++)
     {
      if (i!=0)
      {
       strV = strV + _T(", ") ;
      }
      strV = strV + _T(" '") + pList->GetItemText(nItemIndex,i) +_T("' ");
     }

     sSql = _T("INSERT INTO ")+ tableName
      +_T(" (")+ strH + _T(")")
      +_T(" VALUES(")+ strV + _T(")");
     database.ExecuteSQL(sSql);
    }

   }     

   // 关闭数据库
   database.Close();

   warningStr.Format(_T("导出文件保存于%s!"),sExcelFile);
   AfxMessageBox(warningStr);
}
}

然后在对话框源码文件中添加 代码如下:
ExportListToExcel(&BookList,_T("九九乘法口诀表"));

其中 BookList 标示 CListCtrl控件...
封装函数的内容不细说了。

 

本文转自:http://hi.baidu.com/csw8923/blog/item/75f912f0fea9b7c97831aa04.html

 

你可能感兴趣的:(DAO,数据库,Excel,null,mfc,Path)