使用 ADO 檢索和編輯 Excel 數(shù)據(jù)
- 如何選擇數(shù)據(jù) — 和 —
- 如何更改數(shù)據(jù)
如何選擇數(shù)據(jù)
- 使用代碼選擇 Excel 數(shù)據(jù)。
- 使用 ADO 數(shù)據(jù)控件選擇 Excel 數(shù)據(jù)。
- 使用數(shù)據(jù)環(huán)境命令選擇 Excel 數(shù)據(jù)。
使用代碼選擇 Excel 數(shù)據(jù)
- 整張工作表。
- 工作表上的命名單元格區(qū)域。
- 工作表上的未命名單元格區(qū)域。
指定工作表若要指定一張工作表作為記錄源,請使用該工作表的名稱,后面帶有一個美元字符,并用方括號將其括起。例如:
strQuery = "SELECT * FROM [Sheet1$]"
也可以使用鍵盤上波形符 (~) 下的斜單引號字符 (`) 來分隔工作表名稱。例如:
strQuery = "SELECT * FROM `Sheet1$`"
Microsoft 建議使用方括號,這是用于表示未知數(shù)據(jù)庫對象名的標準約定。
如果將美元符號和方括號全部省略,或只省略美元符號,將出現(xiàn)以下錯誤信息:
... the Jet databaseengine could not find the specified object
如果使用美元符號而忽略了方括號,將會看到以下錯誤信息:
Syntax error in FROMclause.
如果您嘗試使用普通單引號,將出現(xiàn)以下錯誤信息:
Syntax error inquery.Incomplete query clause.
指定命名區(qū)域若要指定命名的單元格區(qū)域作為記錄源,只需使用定義的名稱。例如:
strQuery = "SELECT * FROM MyRange"
指定未命名區(qū)域若要指定未命名的單元格區(qū)域作為記錄源,請在工作表名的后面加上用標準 Excel 行/列表示法表示的區(qū)域,并用方括號將其括起。例如:
strQuery = "SELECT * FROM [Sheet1$A1:B10]"
指定工作表時應(yīng)注意的事項:提供程序認為數(shù)據(jù)表從指定工作表上最左上方的非空單元格開始。換句話說,數(shù)據(jù)表可以從第3 行,C 列開始,這沒有問題。但在這種情況下,舉個例子來說,就不能在數(shù)據(jù)左上方的 A1 單元格中鍵入工作表標題。
指定區(qū)域時應(yīng)注意的事項:指定工作表作為記錄源時,提供程序?qū)⑿掠涗浱砑拥焦ぷ鞅碇鞋F(xiàn)有記錄的下面(如果有可用空間)。指定區(qū)域(命名區(qū)域或未命名區(qū)域)時,Jet也將新記錄添加到區(qū)域中現(xiàn)有記錄的下面(如果有可用空間)。但是,如果對原區(qū)域重新執(zhí)行查詢,則得到的記錄集不包含新添加到該區(qū)域外的記錄。
使用 2.5 版之前的 MDAC 時,如果指定了命名區(qū)域,則無法將新記錄添加到該區(qū)域定義的界限之外,否則將出現(xiàn)以下錯誤信息:
Cannot expand namedrange.
使用 ADO 數(shù)據(jù)控件選擇 Excel 數(shù)據(jù)
屬性對話框的
常規(guī)選項卡上指定 Excel數(shù)據(jù)源的連接設(shè)置后,單擊
記錄源選項卡。如果選擇的 CommandType 為adCmdText,則可以使用上文介紹的語法在
命令文本對話框中輸入一個 SELECT 查詢。如果選擇的CommandType 為 adCmdTable,而且使用的是 Jet提供程序,所選工作簿中的可用命名區(qū)域和工作表的名稱都會顯示在下拉列表中,命名區(qū)域排在前面。
此對話框會正確地在工作表名稱后面加上美元符號,但不會添加必要的方括號。結(jié)果,如果只選擇工作表名稱并單擊
確定,則稍后可能會收到以下錯誤信息:
Syntax error in FROMclause.
您必需手動在工作表名稱的前后加上方括號。(此組合框允許進行編輯。)如果使用的是 ODBC提供程序,則在此下拉列表中只能看到命名區(qū)域。但是,可以手動輸入帶有正確分隔符的工作表名稱。
使用數(shù)據(jù)環(huán)境命令選擇 Excel 數(shù)據(jù)
Command對象。如果選擇的
數(shù)據(jù)源為
SQL語句,則可以使用前面介紹的語法在文本框中輸入一個查詢。如果選擇的
數(shù)據(jù)源為
數(shù)據(jù)庫對象,請在第一個下拉列表中選擇
表,如果您使用的是Jet提供程序,所選工作簿中的可用命名區(qū)域和工作表名稱都會顯示在該下拉列表中,命名區(qū)域排在前面。(從該位置選擇工作表名稱時,不需要像在使用ADO 數(shù)據(jù)控件時那樣在工作表名稱的前后加上方括號。)如果使用的是 ODBC提供程序,則在此下拉列表中只能看到命名區(qū)域。但是,可以手動輸入工作表名稱。
如何更改 Excel 數(shù)據(jù):編輯、添加和刪除
編輯可以使用普通 ADO 方法來編輯 Excel 數(shù)據(jù)。對應(yīng)于 Excel 工作表中包含 Excel公式(以“=”開始)的單元格的記錄集字段是只讀的,不能對其進行編輯。記住 Excel 的 ODBC連接默認是只讀的,除非在連接設(shè)置中另行指定。請參見上文中的“使用 Microsoft OLE DB Provider for ODBCDrivers”一節(jié)。
添加如果有可用空間,可以將記錄添加到 Excel記錄源中。但是,如果將新記錄添加到了原來指定的區(qū)域之外,那么在對原來指定的區(qū)域重新進行查詢時,將看不到這些記錄。請參見上文中“指定區(qū)域時應(yīng)注意的事項”一節(jié)。
在某些情形中,使用 ADO
Recordset 對象的
AddNew 和
Update方法向 Excel 表插入新數(shù)據(jù)行時,ADO 可能會將數(shù)據(jù)值插入錯誤的列。 有關(guān)其他信息,請單擊下面的文章編號,以查看Microsoft 知識庫中相應(yīng)的文章:
314763 (http://support.microsoft.com/kb/314763/ ) FIX:ADO將數(shù)據(jù)插入 Excel 中錯誤的列 刪除刪除 Excel 數(shù)據(jù)時,受到的限制要比從關(guān)系數(shù)據(jù)源中刪除數(shù)據(jù)時更多。在關(guān)系數(shù)據(jù)庫中,“行”除了表示一條“記錄”外沒有其他意義;但在Excel 工作表中卻不同。可以刪除字段(單元格)中的值。但不能:
- 一次刪除一整條記錄,否則將出現(xiàn)以下錯誤信息:
Deleting data in alinked table is not supported by this ISAM.
只能通過分別清空各個字段的內(nèi)容來刪除一條記錄。 - 刪除包含 Excel 公式的單元格中的值,否則將出現(xiàn)以下錯誤信息:
Operation is notallowed in this context.
- 雖然電子表格中已被刪除的數(shù)據(jù)原來所在的行現(xiàn)在是空行,但無法將其刪除,而且記錄集將繼續(xù)顯示對應(yīng)于這些空行的空記錄。
使用 ADO 編輯 Excel 數(shù)據(jù)時應(yīng)注意的事項:使用 ADO 在 Excel中插入文本數(shù)據(jù)時,文本值前面帶有一個單引號。這在后面處理新數(shù)據(jù)時可能會導致問題。
從 Excel 檢索數(shù)據(jù)源結(jié)構(gòu)(元數(shù)據(jù))
Connection對象的
OpenSchema 方法可檢索此元數(shù)據(jù),該方法返回一個 ADO
Recordset對象。也可以使用更強大的 Microsoft ActiveX Data Objects Extensions for DataDefinition Language and Security (ADOX) 庫來檢索元數(shù)據(jù)。然而,對于 Excel數(shù)據(jù)源,“表”既可以是工作表也可以是命名區(qū)域,而“字段”則是幾種有限的一般數(shù)據(jù)類型之一,所以這一附加的功能沒有什么用處。
查詢表信息
Set rs = cn.OpenSchema(adSchemaTables)
Jet 提供程序返回的記錄集包含九 (9) 個字段,但其中只有四 (4) 個字段有數(shù)據(jù):
- table_name
- table_type(“表”或“系統(tǒng)表”)
- date_created
- date_modified
對于一個給定的表,兩個日期字段始終顯示相同的值,該值為“最后修改日期”。換句話說,“date_created”不可靠。
ODBC 提供程序返回的記錄集也包含九 (9) 個字段,但其中只有三 (3) 個字段有數(shù)據(jù):
- table_catalog,該工作簿所在的文件夾。
- table_name。
- table_type,如上文所述。
根據(jù) ADO 文檔,只檢索工作表列表是可以做到的 — 例如通過向
OpenSchema 方法指定以下附加標準:
Set rs = cn.OpenSchema(adSchemaTables, Array(Empty, Empty, Empty, "System Table"))
但遺憾的是,對于 Excel 數(shù)據(jù)源,如果使用的 MDAC 版本高于 2.0,無論使用哪種提供程序此方法都不行。
查詢字段信息
- 數(shù)字(ADO 數(shù)據(jù)類型 5,adDouble)
- 貨幣(ADO 數(shù)據(jù)類型 6,adCurrency)
- 邏輯或布爾值(ADO 數(shù)據(jù)類型 11,adBoolean)
- 日期(使用 Jet 時,為 ADO 數(shù)據(jù)類型 7,adDate;使用 ODBC 時為數(shù)據(jù)類型135,adDBTimestamp)
- 文本(一種 ADO ad...Char類型,例如,202,adVarChar;200,adVarWChar,或相似類型)
對于數(shù)字列,返回的 numeric_precision 始終為 15(是 Excel 中的最大精度);對于文本列,返回的character_maximum_length 始終為 255(是 Excel 列中文本的最大顯示寬度,但不是最大長度)。除了
data_type 屬性之外,得不到多少有用的字段信息。使用以下代碼可以檢索表中可用字段的列表:
Set rs = cn.OpenSchema(adSchemaTables, Array(Empty, Empty, "TableName", Empty))
Jet 提供程序返回的記錄集包含 28 個字段。對于數(shù)字字段,其中八 (8) 個有數(shù)據(jù);對于文本字段,其中九 (9)個有數(shù)據(jù)。有用的字段很可能是:
- table_name
- column_name
- ordinal_position
- data_type
ODBC 提供程序返回的記錄集包含 29 個字段。對于數(shù)字字段,其中十 (10) 個有數(shù)據(jù);對于文本字段,其中 11個有數(shù)據(jù)。有用的字段與上文所述相同。
枚舉表和字段及其屬性
Dim cn As ADODB.ConnectionDim rsT As ADODB.RecordsetDim intTblCnt As Integer, intTblFlds As IntegerDim strTbl As StringDim rsC As ADODB.RecordsetDim intColCnt As Integer, intColFlds As IntegerDim strCol As StringDim t As Integer, c As Integer, f As IntegerSet cn = New ADODB.ConnectionWith cn .Provider = "Microsoft.Jet.OLEDB.4.0" .ConnectionString = "Data Source=" & App.Path & _"\ExcelSrc.xls;Extended Properties=Excel 8.0;" '.Provider = "MSDASQL" '.ConnectionString = "Driver={Microsoft Excel Driver (*.xls)};" & _"DBQ=" & App.Path & "\ExcelSrc.xls; " .CursorLocation = adUseClient .OpenEnd WithSet rsT = cn.OpenSchema(adSchemaTables)intTblCnt = rsT.RecordCountintTblFlds = rsT.Fields.CountList1.AddItem "Tables: " & intTblCntList1.AddItem "--------------------"For t = 1 To intTblCnt strTbl = rsT.Fields("TABLE_NAME").Value List1.AddItem vbTab & "Table #" & t & ": " & strTbl List1.AddItem vbTab & "--------------------" For f = 0 To intTblFlds - 1 List1.AddItem vbTab & rsT.Fields(f).Name & _vbTab & rsT.Fields(f).Value Next List1.AddItem "--------------------" Set rsC = cn.OpenSchema(adSchemaColumns, Array(Empty, Empty, strTbl, Empty)) intColCnt = rsC.RecordCount intColFlds = rsC.Fields.Count For c = 1 To intColCnt strCol = rsC.Fields("COLUMN_NAME").Value List1.AddItem vbTab & vbTab & "Column #" & c & ": " & strCol List1.AddItem vbTab & vbTab & "--------------------" For f = 0 To intColFlds - 1 List1.AddItem vbTab & vbTab & rsC.Fields(f).Name & _vbTab & rsC.Fields(f).Value Next List1.AddItem vbTab & vbTab & "--------------------" rsC.MoveNext Next rsC.Close List1.AddItem "--------------------" rsT.MoveNextNextrsT.Closecn.Close
使用數(shù)據(jù)視圖窗口
Excel 的限制
- 工作表大小:65,536 行,256 列
- 單元格內(nèi)容(文本):32,767 個字符
- 工作簿中的工作表數(shù):受可用內(nèi)存限制
- 工作簿中的名稱數(shù):受可用內(nèi)存限制