利用ADO操作Excel檔案
今天花時間研究了一下ADO操作Excel檔案的問題,跟大家分享一下:
首先利用Excel2003建立了一個名為Demo.xls的檔案,內容如下:
Name Age
TY
12
TZL15
然後開啟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語句的方法完成資料插入與更新操作,需要注意所有的欄位,包括數字,都要按文字來處理,否則會報型別不正確的錯誤。