vc6.0實現操作excle之下篇

2,        通過ODBC服務

2.1,類和方法使用說明

爲使用CDatabase,構造一個CDatabase對象並調用它的OpenEx成員函數。這打開了一個連接。在接着構造CRecordset對象以操縱連接的數據源時,向CDatabase對象傳遞記錄集構造程序指針。完成使用連接時調用Close成員函數並銷燬CDatabase對象。Close關閉以前沒有關閉的任何記錄集。

#include<afxdb.h>

1.建立連接:

要建立與數據源的連接,首先應構造一個CDatabase對象,然後再調用CDatabase的Open成員函數Open函數負責建立連接,其聲明爲:

virtual BOOL Open(LPCTSTR lpszDSN, BOOL bExclusive = FALSE, BOOL bReadOnly = FALSE, LPCTSTRlpszConnect ="ODBC;", BOOLbUseCursorLib = TRUE ); throw( CDBException, CMemoryException );

說明:

1)參數lpszDSN指定了數據源名(構造數據源的方法將在後面介紹),在lpszConnect參數中也可包括數據源名,此時lpszDSN必需爲NULL,若在函數中未提供數據源名且使lpszDSN爲NULL,則會顯示一個數據源對話框,用戶可以在該對話框中選擇一個數據源。

2)參數bExclusive說明是否獨佔數據源,由於目前版本的類庫還不支持獨佔方式,故該參數的值應該是FALSE,這說明數據源是被共享的。

3)參數bReadOnly若爲TRUE則對數據源的連接是隻讀的。

4)參數lpszConnect指定了一個連接字符串,連接字符串中可以包括數據源名、用戶帳號(ID)和口令等信息,字符串中的“ODBC”表示要連接到一個ODBC數據源上。

5)參數bUseCursorLib若爲TRUE,則會裝載光標庫,否則不裝載,快照需要光標庫,動態集不需要光標庫。

6)若連接成功,函數返回TRUE,若返回FALSE,則說明用戶在數據源對話框中按了Cancel按鈕。若函數內部出現錯誤,則框架會產生一個異常。

例子:

1)CDatabase m_db; //在文檔類中嵌入一個CDatabase對象

2)//連接到一個名爲"StudentRegistration"的數據源

m_db.Open("Student Registration");

3)//在連接數據源的同時指定了用戶帳號和口令

m_db.Open(NULL,FALSE,FALSE,"ODBC;DSN=Student Registration;UID=ZYF;PWD=1234");

4)m_db.Open(NULL); //將彈出一個數據源對話框

2.要從一個數據源中脫離,可調用函數Close。在脫離後,可以再次調用Open函數來建立一個新的連接。

3.調用IsOpen可判斷當前是否有一個連接。

4.調用GetConnect可返回當前的連接字符串。

5.相關函數聲明:

virtual void Close( );

BOOL IsOpen( ) const; //返回TRUE則表明當前有一個連接

const CString& GetConnect( ) const;

6.CDatabase的析構函數會調用Close,所以只要刪除了CDatabase對象就可以與數據源脫離。

7. CDatabase類成員

數據成員

m_hdbc

對數據源的開放數據庫連接(ODBC)連接句柄。類型HDBC

構造函數

CDatabase

構造一個CDatabase對象。必須通過調用OpenExOpen初始化這個對象

Open

建立到數據源的一個連接(通過ODBC驅動程序)

OpenEx

建立到數據源的一個連接(通過ODBC驅動程序)

Close

關閉數據源連接

數據庫屬性

GetConnect

返回用於連接CDatabase對象和數據源的ODBC連接字符串

IsOpen

如果CDatabase對象當前與數據源連接,則返回非零

GetDatabaseName

返回當前使用的數據庫名字

CanUpdate

如果CDatabase可更新(不是隻讀的),則返回非零

CanTransact

如果數據源支持事務,則返回非零

SetLoginTimeout

設置數據源連接試圖超時的秒數

SetQueryTimeout

設置數據庫查詢操作超時的秒數。影響以後的所有記錄集調用:OpenAddNewEditDelete

GetBookmarkPersistence

標識記錄集對象上書籤持久化操作

GetCursorCommitBehavior

標識在打開的記錄集對象上提交事務的效果

GetCursorRollbackBehavior

標識在打開的記錄集對象上回滾事務的效果

數據庫操作

BeginTrans

在連接的數據源上開始事務”──CRecordset的一系列可回滾的AddNewEditDeleteUpdate成員函數調用。數據源必須支持事務才能使BeginTrans有效

BindParameters

允許在調用CDatabase::ExecuteSQL前綁定參數

CommitTrans

完成由從BeginTrans開始的事務。執行這個事務中改變數據源的命令

Rollback

回滾當前事務期間所做變化,數據源返回到BeginTrans調用時定義的未改變的以前狀況

Cancel

取消第二個線程的異步操作或處理

ExecuteSQL

執行一條SQL語句。不返回數據記錄

數據庫覆蓋

OnSetOptions

框架調用以設置標準連接選項。缺省實現設置查詢超時值。可以通過調用SetQueryTimeout提前建立這些選項

 

想要通過ODBC直接讀、寫Excel表格文件,首先,應確保ODBC中已安裝有Excel表格文件的驅動"MICROSOFTEXCEL DRIVER (*.XLS)"。

2.2. 在StdAfx.h文件中加入:
#include <afxdb.h>
#include <odbcinst.h>

//通過ODBC直接創建Excel文件(暫定文件名:Demo.xls)
//創建並寫入Excel文件
void CRWExcel::WriteToExcel()
{
CDatabase database;
CString sDriver = "MICROSOFT EXCEL DRIVER (*.XLS)"; // Excel安裝驅動
CString sExcelFile = "c:\\demo.xls"; // 要建立的Excel文件
CString sSql;

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

// 創建數據庫(既Excel表格文件)
if( database.OpenEx(sSql,CDatabase::noOdbcDialog) )
{
// 創建表結構(姓名、年齡)
sSql = "CREATE TABLE demo (Name TEXT,Age NUMBER)";
database.ExecuteSQL(sSql);

// 插入數值
sSql = "INSERT INTO demo (Name,Age) VALUES ('徐景周',26)";
database.ExecuteSQL(sSql);

sSql = "INSERT INTO demo (Name,Age) VALUES ('徐志慧',22)";
database.ExecuteSQL(sSql);

sSql = "INSERT INTO demo (Name,Age) VALUES ('郭徽',27)";
database.ExecuteSQL(sSql);
}

// 關閉數據庫
database.Close();
}
CATCH_ALL(e)
{
TRACE1("Excel驅動沒有安裝:%s",sDriver);
}
END_CATCH_ALL;
}

3. 通過ODBC直接讀取Excel文件(暫定文件名:Demo.xls)
// 讀取Excel文件
void CRWExcel::ReadFromExcel()
{
CDatabase database;
CString sSql;
CString sItem1, sItem2;
CString sDriver;
CString sDsn;
CString sFile = "Demo.xls"; // 將被讀取的Excel文件名

// 檢索是否安裝有Excel驅動"Microsoft Excel Driver (*.xls)"
sDriver = GetExcelDriver();
if (sDriver.IsEmpty())
{
// 沒有發現Excel驅動
AfxMessageBox("沒有安裝Excel驅動!");
return;
}

// 創建進行存取的字符串
sDsn.Format("ODBC;DRIVER={%s};DSN='';DBQ=%s", sDriver, sFile);

TRY
{
// 打開數據庫(既Excel文件)
database.Open(NULL, false, false, sDsn);

CRecordset recset(&database);

// 設置讀取的查詢語句.
sSql = "SELECT Name, Age "
"FROM demo "
"ORDER BY Name ";

// 執行查詢語句
recset.Open(CRecordset::forwardOnly, sSql, CRecordset::readOnly);

// 獲取查詢結果
while (!recset.IsEOF())
{
//讀取Excel內部數值
recset.GetFieldValue("Name", sItem1);
recset.GetFieldValue("Age", sItem2);

// 移到下一行
recset.MoveNext();
}

// 關閉數據庫
database.Close();

}
CATCH(CDBException, e)
{
// 數據庫操作產生異常時...
AfxMessageBox("數據庫錯誤:" + e->m_strError);
}
END_CATCH;
}


// 獲取ODBC中Excel驅動
CString CRWExcel::GetExcelDriver()
{
char szBuf[2001];
WORD cbBufMax = 2000;
WORD cbBufOut;
char *pszBuf = szBuf;
CString sDriver;

// 獲取已安裝驅動的名稱(涵數在odbcinst.h裏)
if (!SQLGetInstalledDrivers(szBuf, cbBufMax, &cbBufOut))
return "";

// 檢索已安裝的驅動是否有Excel...
do
{
if (strstr(pszBuf, "Excel") != 0)
{
//發現!
sDriver = CString(pszBuf);
break;
}
pszBuf = strchr(pszBuf, '\0') + 1;
}
while (pszBuf[1] != '\0');

return sDriver;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章