1. 程式人生 > >利用ADO操作Excel檔案

利用ADO操作Excel檔案

今天花時間研究了一下ADO操作Excel檔案的問題,跟大家分享一下:

首先利用Excel2003建立了一個名為Demo.xls的檔案,內容如下:

Name Age

TY

12

TZL

15

然後開啟VC,建立一個命令列應用程式。然後如一般的ADO程式一樣編寫相應程式碼,只是注意開啟資料庫的程式碼如下寫:

m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Demo.xls;Extended Properties=/"Excel 8.0;HDR=No;IMEX=1/"","","",adModeUnknown);


  

注意一下HDR,如果後面是No的話,表示ADO將不把你Excel檔案的第一行作為欄位名(此時使用預設欄位名:F1,F2。。以此類推,當然也可以用(LPCTSTR)m_pRecordset->GetFields()->GetItem((_variant_t)zz)->Name之類的程式碼來獲得相應的欄位名)。否則如上Excel檔案的欄位名將是Name與Age。另外是IMEX,如果設定了"IMEX=1;" 則通知驅動程式始終將“互混”(數字,日期,字串等)資料列作為文字讀取,同時這個選項有可能影響到excel表格拒絕寫操作,也就是說,如果我們要求寫入excel的話,這個選項不能被設定

接下來是開啟記錄集,程式碼如下(注意一下表名的寫法):

m_pRecordset->Open("select * from [Sheet1$]",_variant_t((IDispatch*)m_pConnection,true),adOpenDynamic,adLockOptimistic,adCmdUnknown);

知道了欄位名,打開了資料庫跟記錄集,隨後的操作就跟普通ADO的操作一樣了:

讀取操作:

while(!m_pRecordset->adoEOF)
{
 _variant_t var = m_pRecordset->GetCollect("Name");
 if(var.vt != VT_NULL)
  _bstr_t strName = (LPCSTR)_bstr_t(var);
 var = m_pRecordset->GetCollect("Age");
 if(var.vt != VT_NULL)
  _bstr_t strAge = (LPCSTR)_bstr_t(var);

 string strMid = strName + "--> " + strAge;
 cout<<strMid.c_str()<<endl;

 m_pRecordset->MoveNext();
}

插入操作:

m_pRecordset->AddNew();
m_pRecordset->PutCollect("Name",_variant_t("zz"));
m_pRecordset->PutCollect("Age",_variant_t("23"));
m_pRecordset->Update();

更新操作:

m_pRecordset->MoveFirst();
m_pRecordset->PutCollect("Name",_variant_t("zz"));
m_pRecordset->Update();

刪除操作:

不支援!這也是感到很遺憾的地方。好在我們可以通過執行 update [Sheet1$] set Name=NULL, Age=NULL where Name='zz'  之類的SQL語句來實現類似功能。當然,你要知道的是,這一行並沒有真正刪除掉,所以通常在select的時候要進行一定的篩選,例如:select * from [Sheet1$] where Name is not NULL;

其它注意事項:

如果通過執行SQL語句的方法完成資料插入與更新操作,需要注意所有的欄位,包括數字,都要按文字來處理,否則會報型別不正確的錯誤。