文章編號: 257819 - 上次校閱: 2005年8月12日 - 版次: 4.3 如何從 Visual Basic 或 VBA 搭配使用 ADO 與 Excel 資料
本文曾發行於 CHT257819 在此頁中結論 本文說明將 ActiveX Data Objects (ADO) 與 Microsoft Excel
試算表搭配使用,以做為資料來源。本文也會強調 Excel 特有的語法問題和限制。本文不會說明 OLAP、PivotTable 技術或 Excel
資料的其他特殊用法。 如需詳細資訊,請按一下下面的文件編號,檢視「Microsoft 知識庫」中的文件: 303814?
(http://support.microsoft.com/kb/303814/
)
How To Use ADOX with Excel Data from Visual Basic or VBA 其他相關資訊簡介Microsoft Excel 試算表的列和欄與資料庫表格的資料列和資料欄非常相似。使用者只要記得 Microsoft Excel 並非關聯式資料庫管理系統,並且瞭解其所帶來的限制,就可以善加利用 Excel 及其工具來儲存並分析資料。Microsoft ActiveX Data Objects 可以將 Excel 活頁簿視同資料庫使用。本文將在下列章節說明如何達到這個目的: 注意:本文的測試是在具有 Visual Basic 6.0 Service Pack 3 和 Excel 2000 的 Microsoft Windows 2000 上使用 Microsoft Data Access Components (MDAC) 2.5。本文不認可或討論使用者在不同版本的 MDAC、Microsoft Windows、Visual Basic 或 Excel 當中,觀察所得的行為差異。 使用 ADO 連線至 ExcelADO 可以使用 MDAC 中包含的兩種 OLE DB 提供者其中之一,來連線至 Excel 資料檔案:
如何使用 Microsoft Jet OLE DB Provider此 Jet 提供者只需要兩種資訊,就能連接至 Excel 資料來源:路徑,包含檔案名稱和 Excel 檔案版本。使用連接字串的 Jet 提供者 Couldn't
find installable ISAM. (找不到可安裝的 ISAM) 使用資料連結屬性對話方塊的 Jet 提供者 如果您在應用程式中使用「ADO 資料控制」或「資料環境」,會顯示 [資料連結屬性] 對話方塊來搜集必要的連線設定。
欄位標題:依預設,會假設 Excel 資料來源的第一欄包含欄位標題,這個標題可以用來做為欄位名稱。如果沒有,則必須關閉這項設定,否則第一列的資料將會「消失」,而變成欄位名稱。方法是將選擇性的 HDR= 設定,加入至連接字串的 [擴充屬性]。如果不指定這個設定,其預設值為 HDR=Yes。如果沒有欄位標題,您必須指定 HDR=No。提供者會將您的欄位命名為 F1、F2 等等。因為 [擴充屬性] 字串目前包含數個值,必須使用雙引號括住這個字串,雙引號外還要加上另一對額外的雙引號,用以告知 Visual Basic 將第一組雙引號視為常值,如下列範例所示 (額外加上空格是為了視覺上的清楚)。 使用 Microsoft OLE DB Provider for ODBC DriversODBC 驅動程式的提供者 (在本文中簡稱為「ODBC 提供者」) 也需要兩種資訊,來連線至 Excel 資料來源:驅動程式名稱,以及活頁簿路徑和檔案名稱。重要:依預設,ODBC 與 Excel 的連線是唯讀的。您的 ADO 資料錄集 LockType 屬性設定不會覆寫這個連線層級的設定。如果您要編輯資料,必須在連接字串或 DSN 設定中將 ReadOnly 設定為 False。否則,您會收到下列錯誤訊息: Operation must use an
updateable query. (操作必須使用可更新的查詢) 如果您在應用程式中使用「ADO 資料控制」或「資料環境」,會顯示 [資料連結屬性] 對話方塊來搜集必要的連線設定。
欄位標題:依預設,會假設 Excel 資料來源的第一欄包含欄位標題,這個標題可以用來做為欄位名稱。如果沒有,則必須關閉這項設定,否則第一列的資料將會「消失」,而變成欄位名稱。方法是將選擇性的 FirstRowHasNames= 設定加入至連接字串。如果不指定這個設定,其預設值為 FirstRowHasNames=1,其中 1 = True。如果沒有欄位標題,您必須指定 FirstRowHasNames=0,其中 0 = False。驅動程式會將您的欄位命名為 F1、F2 等等。DSN 設定對話方塊中無法使用此選項。 但是,由於 ODBC 驅動程式中有一個錯誤,目前指定 FirstRowHasNames 設定不會有任何效果。也就是說,Excel ODBC 驅動程式 (MDAC 2.1 和更新版本) 一律會將指定資料來源的第一列視為欄位名稱。 如需有關「欄位標題」錯誤的詳細資訊,請按一下下面的文件編號,檢視「Microsoft 知識庫」中的文件: 288343?
(http://support.microsoft.com/kb/288343/
)
BUG:Excel ODBC Driver Disregards the FirstRowHasNames or Header Setting 掃描列數:Excel 不會將本身包含資料的詳細架構資訊提供給
ADO,但是關聯式資料庫會提供。因此,驅動程式至少必須掃描數列的現有資料,才能合理推測每一欄的資料類型。「掃描列數」預設值為 8 列。您可以指定從 1 至
16 列的整數值,或指定零 (0) 來掃描所有現有列。方法是將選擇性的 MaxScanRows= 設定加入至連接字串,或在 DSN 設定對話方塊中變更 [掃描列數] 設定。但是,由於 ODBC 驅動程式中有一個錯誤,目前指定「掃描列數」(MaxScanRows) 設定不會有任何效果。也就是說,Excel ODBC 驅動程式 (MDAC 2.1 和更新版本) 一律會在指定資料來源中掃描前 8 列,以判斷每一欄的資料類型。 如需有關「掃描列數」錯誤的詳細資訊,包括簡單的解決方法,請按一下下面的文件編號,檢視「Microsoft 知識庫」中的文件: 189897?
(http://support.microsoft.com/kb/189897/
)
XL97:Data Truncated to 255 Characters with Excel ODBC Driver 其他設定:如果您使用 [資料連結屬性] 對話方塊來建構連接字串,可能會注意到加入至連線字串中的某些其他 [擴充屬性] 設定,並不是絕對必要的,例如:在具有特定版本 MDAC 的 Visual Basic 設計環境中,當程式在設計階段第一次連線至 Excel 資料來源時,您可能會看到下列錯誤訊息: Selected collating sequence not
supported by the operating system. (作業系統不支援選取的核對順序) 246167?
(http://support.microsoft.com/kb/246167/
)
PRB:Collating Sequence Error Opening ADODB Recordset the First Time Against an Excel XLS 兩個 OLE DB 提供者都適用的考量有關混合資料類型的警告如前所述,ADO 必須推測 Excel 工作表或範圍中每一欄的資料類型 (這不會受 Excel 儲存格格式設定所影響)。如果您在同一欄中混合使用數值和文字值,會發生嚴重的問題。Jet 和 ODBC 提供者都會傳回主要類型的資料,但是次要資料類型則會傳回 NULL (空) 值。如果同一欄中兩種類型混合使用的比例相同,提供者會選擇數值而非文字值。 例如:
如果要解決唯讀資料的這個問題,請使用連接字串「擴充屬性」區段中的設定 IMEX=1,來啟用 [匯入模式]。這會強制 ImportMixedTypes=Text 登錄設定。但是,請注意更新可能會在這個模式產生非預期的結果。 如需有關這個設定的詳細資訊,請按一下下面的文件編號,檢視「Microsoft 知識庫」中的文件: 194124?
(http://support.microsoft.com/kb/194124/
)
PRB:Excel Values Returned as NULL Using DAO OpenRecordset 您無法開啟具有密碼保護的活頁簿如果 Excel 活頁簿具有密碼保護,您就無法開啟它進行資料存取,即使隨著連線設定提供正確的密碼也無法存取,除非 Microsoft Excel 應用程式已開啟該活頁簿檔案。如果執行這項操作,您會收到下列錯誤訊息: Could not decrypt
file. (無法解密檔案) 211378?
(http://support.microsoft.com/kb/211378/
)
XL2000:"Could Not Decrypt File" Error with Password Protected File 使用 ADO 擷取和編輯 Excel 資料本節說明使用 Excel 資料的兩個層面:
如何選取資料選取資料的方式有幾種。您可以:
使用程式碼選取 Excel 資料您的 Excel 資料可能包含在下列活頁簿中的其中一項:
如果要將工作表指定為記錄來源,請使用工作表名稱,後面加上錢幣符號 ($),然後用中括弧將它們括住。例如: 如果您省略錢幣符號和中括弧,或只省略錢幣符號,都會收到下列錯誤訊息: ... the Jet database
engine could not find the specified object (Jet 資料庫引擎無法找到指定的物件) Syntax error in FROM clause.
(From 子句中的語法錯誤) Syntax
error in query.Incomplete query clause. (查詢中的語法錯誤,查詢子句不完整) 如果要將儲存格的已命名範圍指定為記錄來源,請使用已定義的名稱。例如: 如果要將儲存格的未命名範圍指定為記錄來源,請將標準 Excel 列/欄表示法,附加至中括弧內的工作表名稱結尾。例如: 有關指定範圍的警告:當您將工作表指定為記錄來源時,如果空間足夠的話,提供者會將新的記錄加入工作表的現有記錄下方。當您指定範圍 (無論是已命名還是未命名) 時,如果空間足夠的話,Jet 也會將新的記錄加入範圍中的現有記錄下方。但是,如果您重新查詢原來的範圍,所得出的資料錄集不會包含範圍以外的新增記錄。 如果您所用的是 2.5 版以前的 MDAC,那麼在指定已命名範圍時,不能在定義的範圍限制之外加入新記錄,否則會收到下列錯誤訊息:
Cannot expand named range. (無法展開已命名範圍) 使用 ADO 資料控制選取 Excel 資料在 ADODC [內容] 對話方塊的 [一般] 索引標籤上指定 Excel 資料來源的連線設定之後,請按一下 [記錄來源] 索引標籤。如果選擇 adCmdText 的 CommandType,您可以使用前面說明的語法,在 [命令文字] 對話方塊中輸入 SELECT 查詢。如果選擇 adCmdTable 的 CommandType,而且您使用的是 Jet 提供者,下拉清單會顯示已選取活頁簿中可用的已命名範圍和工作表名稱,並且會將已命名範圍列在前面。這個對話方塊會適當地將錢幣符號附加至工作表名稱後面,但不會加入必要的中括弧。因此,如果只選取工作表名稱然後按一下 [確定],您就會在稍後收到下列錯誤訊息: Syntax error in FROM
clause. (From 子句中的語法錯誤) 使用資料環境命令選取 Excel 資料設定 Excel 資料來源的「資料環境連線」之後,請建立新的 Command 物件。如果選擇 SQL 陳述式的資料來源,您可以使用前面說明的語法,在文字方塊中輸入查詢。如果選擇資料庫物件的資料來源,並在第一個下拉清單中選取 [表格],而且如果您使用的是 Jet 提供者,下拉清單會顯示已選取活頁簿中可用的已命名範圍和工作表名稱,並且將已命名範圍列在前面 (如果您在這個位置選擇工作表名稱,就不需要手動將中括弧加在工作表名稱兩旁,而這個動作在 ADO 資料控制是必要的)。如果您使用的是 ODBC 提供者,您只會看到此下拉清單中列出已命名範圍。但是,您可以手動輸入工作表名稱。如何變更 Excel 資料:編輯、新增和刪除編輯您可以使用一般 ADO 方法編輯 Excel 資料。對應於包含 Excel 公式 (以 = 開頭) 之 Excel 工作表儲存格的資料錄集欄位,都是唯讀欄位,不可以編輯。請記住,除非您在連線設定中另外指定,否則在預設的情況下,與 Excel 的 ODBC 連線是唯讀的。請參閱本文前面的<使用 Microsoft OLE DB Provider for ODBC Drivers>一節。 新增 如果空間足夠的話,您可以將記錄加入至 Excel 記錄來源。但是,如果您所加入的新記錄是在原先指定的範圍之外,那麼當您在原始範圍規格上重新查詢時,這些記錄是不會出現的。請參閱本文前面的<有關指定範圍的警告>一節。 在某些特定情況中,當您使用 ADO Recordset 物件的 AddNew 和 Update 方法,將新列資料插入 Excel 表格時,ADO 可能會將這些資料值插入 Excel 中錯誤的欄。 如需詳細資訊,請按一下下面的文件編號,檢視「Microsoft 知識庫」中的文件: 314763?
(http://support.microsoft.com/kb/314763/ZH-TW/
)
FIX:ADO Inserts Data into Wrong Columns in Excel 刪除刪除 Excel 資料時,會比從關聯式資料來源刪除資料受到更多的限制。在關聯式資料庫中,「列」除了「記錄」之外,並沒有任何意義可言,或者根本就不存在,但在 Excel 工作表就不一樣了。您可以刪除欄位 (儲存格) 中的值。但是,您無法:
從 Excel 擷取資料來源結構 (中繼資料)您可以使用 ADO 擷取有關 Excel 資料來源 (表格和欄位) 結構的資料。雖然這兩種 OLE DB 提供者的結果不太一樣,但至少都會傳回同樣少量而有用的欄位資訊。這個中繼資料可以使用 ADO Connection 物件的 OpenSchema 方法進行擷取,這個方法會傳回 ADO Recordset 物件。您也可以使用功能更強的 Microsoft ActiveX Data Objects Extensions for Data Definition Language and Security (ADOX) 程式庫來達到這個目的。但是,在使用 Excel 資料來源時 (其中「表格」代表工作表或已命名範圍,而「欄位」則是其中一種數量有限的一般資料類型),這個額外的功能並不是很有用。查詢表格資訊在關聯式資料庫中可用的各種物件中 (表格、檢視、預存程序等等),Excel 資料來源只會顯示相當於表格的東西,它們是由指定活頁簿所定義的工作表和已命名範圍所組成。已命名範圍被視為「表格」,而工作表則被視為「系統表格」,在這個 table_type 屬性之外,並沒有多少有用的表格資訊可以擷取。您可以使用下列程式碼要求列出活頁簿中的可用表格清單:
ODBC 提供者也會傳回一個具有 9 個欄位的資料錄集,其中它只會填入 3 個欄位:
查詢欄位資訊Excel 資料來源中的每個欄位 (欄) 都是下列其中一種資料類型:
列舉表格和欄位及其屬性Visual Basic 程式碼 (如下列範例) 可以用來列舉 Excel 資料來源中的表格和欄位,以及每個表格和欄位的可用欄位資訊。本範例會將結果輸出至相同表單上的清單方塊 List1。使用資料檢視視窗如果您將資料連結建立至「Visual Basic 資料檢視」視窗中的 Excel 資料來源,「資料檢視」視窗會顯示您可以使用程式擷取的相同資訊,如前所述。特別是,請注意 Jet 提供者會在「表格」下面列出工作表和已命名範圍,而 ODBC 提供者只會在「表格」下面列出已命名範圍。如果您使用的是 ODBC 提供者,但未定義任何已命名範圍,則「表格」清單會是空白。Excel 的限制使用 Excel 做為資料來源會受到 Excel 活頁簿和工作表的內部限制。這些限制包括 (但不限於):
?考 如需有關如何將 ADO.NET 與 Visual Basic .NET 搭配使用來擷取與修改 Excel
活頁簿中之記錄的詳細資訊,請按一下下面的文件編號,檢視「Microsoft 知識庫」中的文件: 316934?
(http://support.microsoft.com/kb/316934/
)
HOW TO:使用 ADO.NET 擷取與修改利用 Visual Basic .NET 之 Excel 活頁簿中的記錄 如需詳細資訊,請按一下下面的文件編號,檢視「Microsoft 知識庫」中的文件:295646?
(http://support.microsoft.com/kb/295646/
)
How To Transfer Data from ADO Data Source to Excel with ADO 246335?
(http://support.microsoft.com/kb/246335/
)
HOWTO:將 ADO 資料錄集的資料自動傳送到 Excel 247412?
(http://support.microsoft.com/kb/247412/
)
INFO:將資料從 Visual Basic 傳送至 Excel 的方法 278973?
(http://support.microsoft.com/kb/278973/
)
SAMPLE:ExcelADO 示範使用 ADO 在 Excel 活頁簿讀取和寫入資料的方法 318373?
(http://support.microsoft.com/kb/318373/
)
How To Retrieve Metadata from Excel by Using the GetOleDbSchemaTable Method in Visual Basic .NET 如需詳細資訊,請參閱下列 Microsoft Training & Certification
課程:Microsoft Corporation 1301 Mastering Office 2000 Solution Development
(http://www.microsoft.com/traincert/syllabi/1301Afinal.asp)
這篇文章中的資訊適用於:
Microsoft及(或)其供應商不就任何在本伺服器上發表的文字資料及其相關圖表資訊的恰當性作任何承諾。所有文字資料及其相關圖表均以「現狀」供應,不負任何擔保責任。Microsoft及(或)其供應商謹此聲明,不負任何對與此資訊有關之擔保責任,包括關於適售性、適用於某一特定用途、權利或不侵權的明示或默示擔保責任。Microsoft及(或)其供應商無論如何不對因或與使用本伺服器上資訊或與資訊的實行有關而引起的契約、過失或其他侵權行為之訴訟中的特別的、間接的、衍生性的損害或任何因使用而喪失所導致的之損害、資料或利潤負任何責任。 | 其他資源 其他支援網站社群立即取得協助文章翻譯
|






Windows Live
Facebook
Twitter
Linkedin
Digg it
Yahoo
Delicious
StumbleUpon
Yammer
Reddit
Technorati
FriendFeed
Email
回此頁最上方
