如何在 Visual Basic 或 VBA 中使用 ADO 来处理 Excel 数据

如何在 Visual Basic 或 VBA 中使用 ADO 来处理 Excel 数据

<script type="text/javascript">function loadTOCNode(){}</script>
文章编号:257819
最后修改:2005年3月17日
修订:4.3
<script type="text/javascript"> var sectionFilter = "type != 'notice' && type != 'securedata' && type != 'querywords'"; var tocArrow = "/library/images/support/kbgraphics/public/en-us/downarrow.gif"; var depthLimit = 10; var depth3Limit = 10; var depth4Limit = 5; var depth5Limit = 3; var tocEntryMinimum = 1; </script> <script src="/common/script/gsfx/kbtoc.js?11" type="text/javascript"></script>

概要

<script type="text/javascript">loadTOCNode(1, 'summary');</script>
本文介绍如何使用 ActiveX Data Objects (ADO) 来处理数据源为 Microsoft Excel 电子表格的数据。本文还着重讨论特定于 Excel 的语法问题和限制。本文不讨论 OLAP 或 PivotTable 技术,或 Excel 数据的其他特殊用法。

有关其他信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
303814 (http://support.microsoft.com/kb/303814/) 如何在 Visual Basic 或 VBA 中使用 ADOX 来处理 Excel 数据

回到顶端

更多信息

<script type="text/javascript">loadTOCNode(1, 'moreinformation');</script>

简介

<script type="text/javascript">loadTOCNode(2, 'moreinformation');</script> Microsoft Excel 工作表中的行和列与数据库中的行和列非常相似。只要用户记住 Microsoft Excel 不是关系型数据库管理系统,并认识到这一事实所带来的限制,在许多情况下都可以利用 Excel 及其工具来存储和分析数据。

Microsoft ActiveX Data Objects 让我们可以将 Excel 工作簿看做和数据库一样。本文通过以下几节来讨论如何实现这一点:
使用 ADO 连接到 Excel
使用 ADO 检索和编辑 Excel 数据
从 Excel 检索数据源结构(元数据)
注意:本文中的测试是使用 Microsoft Data Access Components (MDAC) 2.5 在装有 Visual Basic 6.0 Service Pack 3 和 Excel 2000 的 Microsoft Windows 2000 上执行的。对用户在使用不同版本的 MDAC、Microsoft Windows、Visual Basic 或 Excel 时可能会观察到的不同现象,本文可能未确认或讨论。

回到顶端

使用 ADO 连接到 Excel

<script type="text/javascript">loadTOCNode(2, 'moreinformation');</script> ADO 使用 MDAC 中以下两个 OLE DB 提供程序中的任何一个都可以连接到 Excel 数据文件。
Microsoft Jet OLE DB Provider — 或 —

Microsoft OLE DB Provider for ODBC Drivers
如何使用 Microsoft Jet OLE DB Provider
<script type="text/javascript">loadTOCNode(3, 'moreinformation');</script> Jet 提供程序只需要两条信息就可以连接到 Excel 数据源:路径(包括文件名),和 Excel 文件版本。

Jet 提供程序使用连接字符串
Dim cn as ADODB.Connection
Set cn = New ADODB.Connection
With cn
	.Provider = "Microsoft.Jet.OLEDB.4.0"
	.ConnectionString = "Data Source=C:/MyFolder/MyWorkbook.xls;" & _
"Extended Properties=Excel 8.0;"
	.Open
End With
				
提供程序版本:必须使用 Jet 4.0 提供程序;Jet 3.51 提供程序不支持 Jet ISAM 驱动程序。如果指定了 Jet 3.51 提供程序,在运行时会出现以下错误信息:
Couldn't find installable ISAM.
Excel 版本:对于 Excel 95 工作簿(Excel 版本 7.0),应指定 Excel 5.0;对于 Excel 97、Excel 2000 或 Excel 2002 (XP) 工作簿(Excel 版本 8.0、9.0 和 10.0),应指定 Excel 8.0 版本。

使用“数据链接属性”对话框的 Jet 提供程序

如果在应用程序中使用“ADO 数据控件”或“数据环境”,就会出现 数据链接属性对话框来收集必要的连接设置。
1.提供程序选项卡上,选择 Jet 4.0 提供程序;Jet 3.51 提供程序不支持 Jet ISAM 驱动程序。如果指定了 Jet 3.51 提供程序,在运行时会出现以下错误信息:
Couldn't find installable ISAM.
2.连接选项卡上,浏览到您的工作簿文件。忽略“用户 ID”和“密码”项,因为这些不适用于 Excel 连接。(无法打开受密码保护的 Excel 文件作为数据源。本文后面有关于此主题的详细信息。)
3.所有选项卡上,从列表中选择扩展属性,然后单击编辑值。输入 Excel 8.0;,用分号 (;) 将其与任何其他已有的项分隔。如果忽略此步骤,测试连接时将出现一条错误信息。这是因为,如果不另行指定,Jet 提供程序期望 Microsoft Access 数据库。
4.返回到连接选项卡,并单击 测试连接。将出现一个消息框,通知您测试已成功完成。
其他 Jet 提供程序连接设置

列标题:默认情况下,系统认为 Excel 数据源的第一行包含可用作字段名的列标题。如果不是这种情况,则必须将该设置关闭,否则,第一行数据将会“消失”,而被用作字段名称。这可通过向连接字符串的 扩展属性添加可选的 HDR= 设置来完成。默认情况下(无需指定)是 HDR=Yes。如果没有列标题,则需要指定 HDR=No;提供程序将字段命名为 F1、F2 等等。因为 扩展属性字符串现在包含了多个值,所以各值必须用双引号括起来,再加一对双引号,让 Visual Basic 将第一层引号中的内容当作字面值,如下例所示(为便于看清楚,添加了额外的空格)。
.ConnectionString = "Data Source=C:/MyFolder/MyWorkbook.xls;" & _
"Extended Properties=" " Excel 8.0; HDR=No;" " "
				
使用 Microsoft OLE DB Provider for ODBC Drivers
<script type="text/javascript">loadTOCNode(3, 'moreinformation');</script> ODBC 驱动程序的提供程序(本文为简便起见将其称为“ODBC 提供程序”)也只需要两条信息就可以连接到 Excel 数据源:驱动程序名,以及工作簿的路径和文件名。

重要说明:Excel 的 ODBC 连接默认为只读。ADO 记录集 LockType 属性设置不会覆盖此连接级别的设置。如果想编辑数据,则必须将连接字符串或 DSN 配置中的 ReadOnly 设置为 False。否则,将出现以下错误信息:
Operation must use an updateable query.
使用没有 DSN 的连接字符串的 ODBC 提供程序
Dim cn as ADODB.Connection
Set cn = New ADODB.Connection
With cn
	.Provider = "MSDASQL"
	.ConnectionString = "Driver={Microsoft Excel Driver (*.xls)};" & _
"DBQ=C:/MyFolder/MyWorkbook.xls; ReadOnly=False;"
	.Open
End With
				
使用带有 DSN 的连接字符串的 ODBC 提供程序
Dim cn as ADODB.Connection
Set cn = New ADODB.Connection
With cn
	.Provider = "MSDASQL"
	.ConnectionString = "DSN=MyExcelDSN;"
	.Open
End With
				
使用“数据链接属性”对话框的 ODBC 提供程序

如果在应用程序中使用“ADO 数据控件”或“数据环境”,就会出现数据链接属性对话框来收集必要的连接设置。
1.提供程序选项卡上,选择 Microsoft OLE DB Provider for ODBC Drivers
2.连接选项卡上,选择想使用的现有 DSN,或选择使用连接字符串。这将打开标准 DSN 配置对话框,收集必需的连接设置。如果需要,请不要忘记取消选择默认只读设置,如上文所述。
3.返回连接选项卡,然后单击测试连接。将出现一个消息框,通知您测试已成功完成。
其他 ODBC 提供程序连接设置

列标题:默认情况下,系统认为 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 驱动程序忽略 FirstRowHasNames 或 Header 设置
要扫描的行数: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:使用 Excel ODBC 驱动程序数据截短到 255 个字符
其他设置:如果是通过使用 数据链接属性对话框来构造连接字符串的,那么您可能会注意到一些其他的 扩展属性设置添加到了连接字符串中,而这些设置不一定有用,如:
... DefaultDir=C:/WorkbookPath;DriverId=790;FIL=excel 8.0;MaxBufferSize=2048;PageTimeout=5;
				
Visual Basic 编辑器中的“Collating Sequence”(排序顺序)错误信息

使用某些版本的 MDAC 时,当您的程序在设计时第一次连接到 Excel 数据源时,Visual Basic 设计环境中将出现以下错误信息:
Selected collating sequence not supported by the operating system.
此信息仅出现在 IDE 中,而不会出现在编译好的程序中。 有关其他信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
246167 (http://support.microsoft.com/kb/246167/) PRB:首次在 Excel XLS 中打开 ADODB 记录集时出现排序顺序错误
使用这两种 OLE DB 提供程序时都应考虑的问题
<script type="text/javascript">loadTOCNode(3, 'moreinformation');</script> 混用数据类型时应注意的事项

如上文所述,ADO 必须猜测 Excel 工作表或范围中各列的数据类型。(这不受 Excel 单元格格式设置的影响。)如果同一列中既有数字值,也有文本值,会出现严重的问题。Jet 和 ODBC 提供程序将返回占多数的类型的数据,但对于占少数的数据类型,则会返回 NULL(空)值。如果该列中两种类型数据的数量相等,提供程序将优先选择数字型数据,放弃文本型数据。

例如:
在被扫描的八 (8) 行中,如果该列包含五 (5) 个数字值和三 (3) 个文本值,则提供程序将返回五 (5) 个数字和三 (3) 个空值。
在被扫描的八 (8) 行中,如果该列包含三 (3) 个数字值和五 (5) 个文本值,则提供程序将返回三 (3) 个空值和五 (5) 个文本值。
在被扫描的八 (8) 行中,如果该列包含四 (4) 个数字值和四 (4) 个文本值,则提供程序将返回四 (4) 个数字和四 (4) 个空值。
因此,如果列中包含不同类型的值,唯一的解决方法是将该列中的数字值存储为文本,然后在需要时使用 Visual Basic VAL 函数或同等功能的函数将其还原为数字。

作为解决只读数据问题的一种替代方法,可在连接字符串的“扩展属性”部分中使用“IMEX=1”这一设置来启用 导入模式。这可强制执行 ImportMixedTypes=Text 注册表设置。但在此模式下,执行更新操作时可能会出现意外的结果。 有关此设置的其他信息,请单击下面的文章编号,查看 Microsoft 知识库中相应的文章:
194124 (http://support.microsoft.com/kb/194124/) PRB:使用 DAO OpenRecordset 时 Excel 返回值为 NULL
无法打开受密码保护的工作簿

如果您的 Excel 工作簿受密码保护,即使在连接设置中提供了正确的密码,也无法打开它以访问其数据,除非已在 Microsoft Excel 应用程序中打开了该工作簿文件。如果您尝试这样做,将出现以下错误信息:
Could not decrypt file.
有关其他信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
211378 (http://support.microsoft.com/kb/211378/) XL2000:访问受密码保护的文件时,出现“Could Not Decrypt File”(无法解密文件)错误

回到顶端

使用 ADO 检索和编辑 Excel 数据

<script type="text/javascript">loadTOCNode(2, 'moreinformation');</script> 本节讨论两种处理 Excel 数据的方式:
如何选择数据 — 和 —

如何更改数据
如何选择数据
<script type="text/javascript">loadTOCNode(3, 'moreinformation');</script> 有几种选择数据的方法。您可以进行以下操作:

使用代码选择 Excel 数据。
使用 ADO 数据控件选择 Excel 数据。
使用数据环境命令选择 Excel 数据。
使用代码选择 Excel 数据
<script type="text/javascript">loadTOCNode(3, 'moreinformation');</script> Excel 数据可能包含在工作簿中的以下一种对象内:

整张工作表。
工作表上的命名单元格区域。
工作表上的未命名单元格区域。
指定工作表

若要指定一张工作表作为记录源,请使用该工作表的名称,后面带有一个美元字符,并用方括号将其括起。例如:
	strQuery = "SELECT * FROM [Sheet1$]"
				
也可以使用键盘上波形符 (~) 下的斜单引号字符 (`) 来分隔工作表名称。例如:
	strQuery = "SELECT * FROM `Sheet1

如何在 Visual Basic 或 VBA 中使用 ADO 来处理 Excel 数据

<script type="text/javascript">___FCKsi___0</script>
文章编号:257819
最后修改:2005年3月17日
修订:4.3
<script type="text/javascript">___FCKsi___1</script> <script src="/common/script/gsfx/kbtoc.js?11" type="text/javascript">___FCKsi___2</script>

概要

<script type="text/javascript">___FCKsi___3</script>
本文介绍如何使用 ActiveX Data Objects (ADO) 来处理数据源为 Microsoft Excel 电子表格的数据。本文还着重讨论特定于 Excel 的语法问题和限制。本文不讨论 OLAP 或 PivotTable 技术,或 Excel 数据的其他特殊用法。

有关其他信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
303814 (http://support.microsoft.com/kb/303814/) 如何在 Visual Basic 或 VBA 中使用 ADOX 来处理 Excel 数据

回到顶端

更多信息

<script type="text/javascript">___FCKsi___4</script>

简介

<script type="text/javascript">___FCKsi___5</script> Microsoft Excel 工作表中的行和列与数据库中的行和列非常相似。只要用户记住 Microsoft Excel 不是关系型数据库管理系统,并认识到这一事实所带来的限制,在许多情况下都可以利用 Excel 及其工具来存储和分析数据。

Microsoft ActiveX Data Objects 让我们可以将 Excel 工作簿看做和数据库一样。本文通过以下几节来讨论如何实现这一点:
使用 ADO 连接到 Excel
使用 ADO 检索和编辑 Excel 数据
从 Excel 检索数据源结构(元数据)
注意:本文中的测试是使用 Microsoft Data Access Components (MDAC) 2.5 在装有 Visual Basic 6.0 Service Pack 3 和 Excel 2000 的 Microsoft Windows 2000 上执行的。对用户在使用不同版本的 MDAC、Microsoft Windows、Visual Basic 或 Excel 时可能会观察到的不同现象,本文可能未确认或讨论。

回到顶端

使用 ADO 连接到 Excel

<script type="text/javascript">___FCKsi___6</script> ADO 使用 MDAC 中以下两个 OLE DB 提供程序中的任何一个都可以连接到 Excel 数据文件。
Microsoft Jet OLE DB Provider — 或 —

Microsoft OLE DB Provider for ODBC Drivers
如何使用 Microsoft Jet OLE DB Provider
<script type="text/javascript">___FCKsi___7</script> Jet 提供程序只需要两条信息就可以连接到 Excel 数据源:路径(包括文件名),和 Excel 文件版本。

Jet 提供程序使用连接字符串
Dim cn as ADODB.Connection
Set cn = New ADODB.Connection
With cn
	.Provider = "Microsoft.Jet.OLEDB.4.0"
	.ConnectionString = "Data Source=C:/MyFolder/MyWorkbook.xls;" & _
"Extended Properties=Excel 8.0;"
	.Open
End With
				
提供程序版本:必须使用 Jet 4.0 提供程序;Jet 3.51 提供程序不支持 Jet ISAM 驱动程序。如果指定了 Jet 3.51 提供程序,在运行时会出现以下错误信息:
Couldn't find installable ISAM.
Excel 版本:对于 Excel 95 工作簿(Excel 版本 7.0),应指定 Excel 5.0;对于 Excel 97、Excel 2000 或 Excel 2002 (XP) 工作簿(Excel 版本 8.0、9.0 和 10.0),应指定 Excel 8.0 版本。

使用“数据链接属性”对话框的 Jet 提供程序

如果在应用程序中使用“ADO 数据控件”或“数据环境”,就会出现 数据链接属性对话框来收集必要的连接设置。
1.提供程序选项卡上,选择 Jet 4.0 提供程序;Jet 3.51 提供程序不支持 Jet ISAM 驱动程序。如果指定了 Jet 3.51 提供程序,在运行时会出现以下错误信息:
Couldn't find installable ISAM.
2.连接选项卡上,浏览到您的工作簿文件。忽略“用户 ID”和“密码”项,因为这些不适用于 Excel 连接。(无法打开受密码保护的 Excel 文件作为数据源。本文后面有关于此主题的详细信息。)
3.所有选项卡上,从列表中选择扩展属性,然后单击编辑值。输入 Excel 8.0;,用分号 (;) 将其与任何其他已有的项分隔。如果忽略此步骤,测试连接时将出现一条错误信息。这是因为,如果不另行指定,Jet 提供程序期望 Microsoft Access 数据库。
4.返回到连接选项卡,并单击 测试连接。将出现一个消息框,通知您测试已成功完成。
其他 Jet 提供程序连接设置

列标题:默认情况下,系统认为 Excel 数据源的第一行包含可用作字段名的列标题。如果不是这种情况,则必须将该设置关闭,否则,第一行数据将会“消失”,而被用作字段名称。这可通过向连接字符串的 扩展属性添加可选的 HDR= 设置来完成。默认情况下(无需指定)是 HDR=Yes。如果没有列标题,则需要指定 HDR=No;提供程序将字段命名为 F1、F2 等等。因为 扩展属性字符串现在包含了多个值,所以各值必须用双引号括起来,再加一对双引号,让 Visual Basic 将第一层引号中的内容当作字面值,如下例所示(为便于看清楚,添加了额外的空格)。
.ConnectionString = "Data Source=C:/MyFolder/MyWorkbook.xls;" & _
"Extended Properties=" " Excel 8.0; HDR=No;" " "
				
使用 Microsoft OLE DB Provider for ODBC Drivers
<script type="text/javascript">___FCKsi___8</script> ODBC 驱动程序的提供程序(本文为简便起见将其称为“ODBC 提供程序”)也只需要两条信息就可以连接到 Excel 数据源:驱动程序名,以及工作簿的路径和文件名。

重要说明:Excel 的 ODBC 连接默认为只读。ADO 记录集 LockType 属性设置不会覆盖此连接级别的设置。如果想编辑数据,则必须将连接字符串或 DSN 配置中的 ReadOnly 设置为 False。否则,将出现以下错误信息:
Operation must use an updateable query.
使用没有 DSN 的连接字符串的 ODBC 提供程序
Dim cn as ADODB.Connection
Set cn = New ADODB.Connection
With cn
	.Provider = "MSDASQL"
	.ConnectionString = "Driver={Microsoft Excel Driver (*.xls)};" & _
"DBQ=C:/MyFolder/MyWorkbook.xls; ReadOnly=False;"
	.Open
End With
				
使用带有 DSN 的连接字符串的 ODBC 提供程序
Dim cn as ADODB.Connection
Set cn = New ADODB.Connection
With cn
	.Provider = "MSDASQL"
	.ConnectionString = "DSN=MyExcelDSN;"
	.Open
End With
				
使用“数据链接属性”对话框的 ODBC 提供程序

如果在应用程序中使用“ADO 数据控件”或“数据环境”,就会出现数据链接属性对话框来收集必要的连接设置。
1.提供程序选项卡上,选择 Microsoft OLE DB Provider for ODBC Drivers
2.连接选项卡上,选择想使用的现有 DSN,或选择使用连接字符串。这将打开标准 DSN 配置对话框,收集必需的连接设置。如果需要,请不要忘记取消选择默认只读设置,如上文所述。
3.返回连接选项卡,然后单击测试连接。将出现一个消息框,通知您测试已成功完成。
其他 ODBC 提供程序连接设置

列标题:默认情况下,系统认为 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 驱动程序忽略 FirstRowHasNames 或 Header 设置
要扫描的行数: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:使用 Excel ODBC 驱动程序数据截短到 255 个字符
其他设置:如果是通过使用 数据链接属性对话框来构造连接字符串的,那么您可能会注意到一些其他的 扩展属性设置添加到了连接字符串中,而这些设置不一定有用,如:
... DefaultDir=C:/WorkbookPath;DriverId=790;FIL=excel 8.0;MaxBufferSize=2048;PageTimeout=5;
				
Visual Basic 编辑器中的“Collating Sequence”(排序顺序)错误信息

使用某些版本的 MDAC 时,当您的程序在设计时第一次连接到 Excel 数据源时,Visual Basic 设计环境中将出现以下错误信息:
Selected collating sequence not supported by the operating system.
此信息仅出现在 IDE 中,而不会出现在编译好的程序中。 有关其他信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
246167 (http://support.microsoft.com/kb/246167/) PRB:首次在 Excel XLS 中打开 ADODB 记录集时出现排序顺序错误
使用这两种 OLE DB 提供程序时都应考虑的问题
<script type="text/javascript">___FCKsi___9</script> 混用数据类型时应注意的事项

如上文所述,ADO 必须猜测 Excel 工作表或范围中各列的数据类型。(这不受 Excel 单元格格式设置的影响。)如果同一列中既有数字值,也有文本值,会出现严重的问题。Jet 和 ODBC 提供程序将返回占多数的类型的数据,但对于占少数的数据类型,则会返回 NULL(空)值。如果该列中两种类型数据的数量相等,提供程序将优先选择数字型数据,放弃文本型数据。

例如:
在被扫描的八 (8) 行中,如果该列包含五 (5) 个数字值和三 (3) 个文本值,则提供程序将返回五 (5) 个数字和三 (3) 个空值。
在被扫描的八 (8) 行中,如果该列包含三 (3) 个数字值和五 (5) 个文本值,则提供程序将返回三 (3) 个空值和五 (5) 个文本值。
在被扫描的八 (8) 行中,如果该列包含四 (4) 个数字值和四 (4) 个文本值,则提供程序将返回四 (4) 个数字和四 (4) 个空值。
因此,如果列中包含不同类型的值,唯一的解决方法是将该列中的数字值存储为文本,然后在需要时使用 Visual Basic VAL 函数或同等功能的函数将其还原为数字。

作为解决只读数据问题的一种替代方法,可在连接字符串的“扩展属性”部分中使用“IMEX=1”这一设置来启用 导入模式。这可强制执行 ImportMixedTypes=Text 注册表设置。但在此模式下,执行更新操作时可能会出现意外的结果。 有关此设置的其他信息,请单击下面的文章编号,查看 Microsoft 知识库中相应的文章:
194124 (http://support.microsoft.com/kb/194124/) PRB:使用 DAO OpenRecordset 时 Excel 返回值为 NULL
无法打开受密码保护的工作簿

如果您的 Excel 工作簿受密码保护,即使在连接设置中提供了正确的密码,也无法打开它以访问其数据,除非已在 Microsoft Excel 应用程序中打开了该工作簿文件。如果您尝试这样做,将出现以下错误信息:
Could not decrypt file.
有关其他信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
211378 (http://support.microsoft.com/kb/211378/) XL2000:访问受密码保护的文件时,出现“Could Not Decrypt File”(无法解密文件)错误

回到顶端

使用 ADO 检索和编辑 Excel 数据

<script type="text/javascript">___FCKsi___10</script> 本节讨论两种处理 Excel 数据的方式:
如何选择数据 — 和 —

如何更改数据
如何选择数据
<script type="text/javascript">___FCKsi___11</script> 有几种选择数据的方法。您可以进行以下操作:

使用代码选择 Excel 数据。
使用 ADO 数据控件选择 Excel 数据。
使用数据环境命令选择 Excel 数据。
使用代码选择 Excel 数据
<script type="text/javascript">___FCKsi___12</script> Excel 数据可能包含在工作簿中的以下一种对象内:

整张工作表。
工作表上的命名单元格区域。
工作表上的未命名单元格区域。
指定工作表

若要指定一张工作表作为记录源,请使用该工作表的名称,后面带有一个美元字符,并用方括号将其括起。例如:
	strQuery = "SELECT * FROM [Sheet1$]"
				
也可以使用键盘上波形符 (~) 下的斜单引号字符 (`) 来分隔工作表名称。例如:
"
				
Microsoft 建议使用方括号,这是用于表示未知数据库对象名的标准约定。

如果将美元符号和方括号全部省略,或只省略美元符号,将出现以下错误信息:
... the Jet database engine could not find the specified object
如果使用美元符号而忽略了方括号,将会看到以下错误信息:
Syntax error in FROM clause.
如果您尝试使用普通单引号,将出现以下错误信息:
Syntax error in query.Incomplete query clause.
指定命名区域

若要指定命名的单元格区域作为记录源,只需使用定义的名称。例如:
	strQuery = "SELECT * FROM MyRange"
				
指定未命名区域

若要指定未命名的单元格区域作为记录源,请在工作表名的后面加上用标准 Excel 行/列表示法表示的区域,并用方括号将其括起。例如:
	strQuery = "SELECT * FROM [Sheet1$A1:B10]"
				
指定工作表时应注意的事项:提供程序认为数据表从指定工作表上最左上方的非空单元格开始。换句话说,数据表可以从第 3 行,C 列开始,这没有问题。但在这种情况下,举个例子来说,就不能在数据左上方的 A1 单元格中键入工作表标题。

指定区域时应注意的事项:指定工作表作为记录源时,提供程序将新记录添加到工作表中现有记录的下面(如果有可用空间)。指定区域(命名区域或未命名区域)时,Jet 也将新记录添加到区域中现有记录的下面(如果有可用空间)。但是,如果对原区域重新执行查询,则得到的记录集不包含新添加到该区域外的记录。

使用 2.5 版之前的 MDAC 时,如果指定了命名区域,则无法将新记录添加到该区域定义的界限之外,否则将出现以下错误信息:
Cannot expand named range.
使用 ADO 数据控件选择 Excel 数据
<script type="text/javascript">loadTOCNode(3, 'moreinformation');</script> 在 ADODC 属性对话框的 常规选项卡上指定 Excel 数据源的连接设置后,单击 记录源选项卡。如果选择的 CommandType 为 adCmdText,则可以使用上文介绍的语法在 命令文本对话框中输入一个 SELECT 查询。如果选择的 CommandType 为 adCmdTable,而且使用的是 Jet 提供程序,所选工作簿中的可用命名区域和工作表的名称都会显示在下拉列表中,命名区域排在前面。

此对话框会正确地在工作表名称后面加上美元符号,但不会添加必要的方括号。结果,如果只选择工作表名称并单击 确定,则稍后可能会收到以下错误信息:
Syntax error in FROM clause.
您必需手动在工作表名称的前后加上方括号。(此组合框允许进行编辑。)如果使用的是 ODBC 提供程序,则在此下拉列表中只能看到命名区域。但是,可以手动输入带有正确分隔符的工作表名称。
使用数据环境命令选择 Excel 数据
<script type="text/javascript">loadTOCNode(3, 'moreinformation');</script> 设置完 Excel 数据源的数据环境连接后,创建一个新的 Command 对象。如果选择的 数据源SQL 语句,则可以使用前面介绍的语法在文本框中输入一个查询。如果选择的 数据源数据库对象,请在第一个下拉列表中选择 ,如果您使用的是 Jet 提供程序,所选工作簿中的可用命名区域和工作表名称都会显示在该下拉列表中,命名区域排在前面。(从该位置选择工作表名称时,不需要像在使用 ADO 数据控件时那样在工作表名称的前后加上方括号。)如果使用的是 ODBC 提供程序,则在此下拉列表中只能看到命名区域。但是,可以手动输入工作表名称。
如何更改 Excel 数据:编辑、添加和删除
<script type="text/javascript">loadTOCNode(3, 'moreinformation');</script> 编辑

可以使用普通 ADO 方法来编辑 Excel 数据。对应于 Excel 工作表中包含 Excel 公式(以“=”开始)的单元格的记录集字段是只读的,不能对其进行编辑。记住 Excel 的 ODBC 连接默认是只读的,除非在连接设置中另行指定。请参见上文中的“使用 Microsoft OLE DB Provider for ODBC Drivers”一节。

添加

如果有可用空间,可以将记录添加到 Excel 记录源中。但是,如果将新记录添加到了原来指定的区域之外,那么在对原来指定的区域重新进行查询时,将看不到这些记录。请参见上文中“指定区域时应注意的事项”一节。

在某些情形中,使用 ADO Recordset 对象的 AddNewUpdate 方法向 Excel 表插入新数据行时,ADO 可能会将数据值插入错误的列。 有关其他信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
314763 (http://support.microsoft.com/kb/314763/) FIX:ADO 将数据插入 Excel 中错误的列
删除

删除 Excel 数据时,受到的限制要比从关系数据源中删除数据时更多。在关系数据库中,“行”除了表示一条“记录”外没有其他意义;但在 Excel 工作表中却不同。可以删除字段(单元格)中的值。但不能:
1.一次删除一整条记录,否则将出现以下错误信息:
Deleting data in a linked table is not supported by this ISAM.
只能通过分别清空各个字段的内容来删除一条记录。
2.删除包含 Excel 公式的单元格中的值,否则将出现以下错误信息:
Operation is not allowed in this context.
3.虽然电子表格中已被删除的数据原来所在的行现在是空行,但无法将其删除,而且记录集将继续显示对应于这些空行的空记录。
使用 ADO 编辑 Excel 数据时应注意的事项:使用 ADO 在 Excel 中插入文本数据时,文本值前面带有一个单引号。这在后面处理新数据时可能会导致问题。

回到顶端

从 Excel 检索数据源结构(元数据)

<script type="text/javascript">loadTOCNode(2, 'moreinformation');</script> 使用 ADO 可以检索有关 Excel 数据源(表和字段)的结构的数据。虽然使用两种 OLE DB 提供程序时至少都返回相同数量(很少)字段的有用信息,但结果在两者之间仍有细微差别。使用 ADO Connection 对象的 OpenSchema 方法可检索此元数据,该方法返回一个 ADO Recordset 对象。也可以使用更强大的 Microsoft ActiveX Data Objects Extensions for Data Definition Language and Security (ADOX) 库来检索元数据。然而,对于 Excel 数据源,“表”既可以是工作表也可以是命名区域,而“字段”则是几种有限的一般数据类型之一,所以这一附加的功能没有什么用处。
查询表信息
<script type="text/javascript">loadTOCNode(3, 'moreinformation');</script> 在关系数据库提供的各种对象中(表、视图、存储过程,等等),Excel 数据源仅提供相当于表的对象,它由指定工作簿中的工作表和定义的命名区域组成。命名区域被视为“表”,而工作表被视为“系统表”。除“table_type”属性外,检索不到太多有用的表信息。使用以下代码可以检索工作簿中可用表的列表:
Set rs = cn.OpenSchema(adSchemaTables)
				
Jet 提供程序返回的记录集包含九 (9) 个字段,但其中只有四 (4) 个字段有数据:

table_name
table_type(“表”或“系统表”)
date_created
date_modified
对于一个给定的表,两个日期字段始终显示相同的值,该值为“最后修改日期”。换句话说,“date_created”不可靠。

ODBC 提供程序返回的记录集也包含九 (9) 个字段,但其中只有三 (3) 个字段有数据:

table_catalog,该工作簿所在的文件夹。
table_name。
table_type,如上文所述。
根据 ADO 文档,只检索工作表列表是可以做到的 — 例如通过向 OpenSchema 方法指定以下附加标准:
Set rs = cn.OpenSchema(adSchemaTables, Array(Empty, Empty, Empty, "System Table"))
				
但遗憾的是,对于 Excel 数据源,如果使用的 MDAC 版本高于 2.0,无论使用哪种提供程序此方法都不行。
查询字段信息
<script type="text/javascript">loadTOCNode(3, 'moreinformation');</script> Excel 数据源中的每个字段(列)都属于以下数据类型之一:

数字(ADO 数据类型 5,adDouble)
货币(ADO 数据类型 6,adCurrency)
逻辑或布尔值(ADO 数据类型 11,adBoolean)
日期(使用 Jet 时,为 ADO 数据类型 7,adDate;使用 ODBC 时为数据类型 135,adDBTimestamp)
文本(一种 ADO ad...Char 类型,例如,202,adVarChar;200,adVarWChar,或相似类型)
对于数字列,返回的 numeric_precision 始终为 15(是 Excel 中的最大精度);对于文本列,返回的 character_maximum_length 始终为 255(是 Excel 列中文本的最大显示宽度,但不是最大长度)。除了 data_type 属性之外,得不到多少有用的字段信息。使用以下代码可以检索表中可用字段的列表:
Set rs = cn.OpenSchema(adSchemaTables, Array(Empty, Empty, "TableName", Empty))
				
Jet 提供程序返回的记录集包含 28 个字段。对于数字字段,其中八 (8) 个有数据;对于文本字段,其中九 (9) 个有数据。有用的字段很可能是:

table_name
column_name
ordinal_position
data_type
ODBC 提供程序返回的记录集包含 29 个字段。对于数字字段,其中十 (10) 个有数据;对于文本字段,其中 11 个有数据。有用的字段与上文所述相同。
枚举表和字段及其属性
<script type="text/javascript">loadTOCNode(3, 'moreinformation');</script> 可以使用 Visual Basic 代码(如下例所示)来枚举 Excel 数据源中的表和列,以及有关各个表和列的可用信息。本示例将其结果输出到同一窗体上的一个列表框 List1。
Dim cn As ADODB.Connection
Dim rsT As ADODB.Recordset
Dim intTblCnt As Integer, intTblFlds As Integer
Dim strTbl As String
Dim rsC As ADODB.Recordset
Dim intColCnt As Integer, intColFlds As Integer
Dim strCol As String
Dim t As Integer, c As Integer, f As Integer
Set cn = New ADODB.Connection
With 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
	.Open
End With
Set rsT = cn.OpenSchema(adSchemaTables)
intTblCnt = rsT.RecordCount
intTblFlds = rsT.Fields.Count
List1.AddItem "Tables:	" & intTblCnt
List1.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.MoveNext
Next
rsT.Close
cn.Close
				
使用数据视图窗口
<script type="text/javascript">loadTOCNode(3, 'moreinformation');</script> 在Visual Basic 的“数据视图”窗口中创建 Excel 数据源的数据链接时,“数据视图”中显示的信息与上文所述可以通过编程方式检索到的信息相同。特别应注意 Jet 提供程序将工作表和命名区域都列在“表”下,而 ODBC 提供程序仅在“表”下显示命名区域。如果使用的是 ODBC 提供程序,而且未定义任何命名区域,“表”列表中将不显示任何内容。
Excel 的限制
<script type="text/javascript">loadTOCNode(3, 'moreinformation');</script> 使用 Excel 作为数据源受限于 Excel 工作簿和工作表的内部限制。这包括但不限于以下事件:

工作表大小:65,536 行,256 列
单元格内容(文本):32,767 个字符
工作簿中的工作表数:受可用内存限制
工作簿中的名称数:受可用内存限制

回到顶端

参考

<script type="text/javascript">loadTOCNode(1, 'references');</script>
有关如何在 Visual Basic .NET 中使用 ADO.NET 检索和修改 Excel 工作簿中的记录的更多信息,请单击下面的文章编号,查看 Microsoft 知识库中相应的文章:
316934 (http://support.microsoft.com/kb/316934/) 如何在 Visual Basic .NET 中使用 ADO.NET 检索和修改 Excel 工作簿中的记录
有关其他信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
295646 (http://support.microsoft.com/kb/295646/) 如何使用 ADO 将数据从 ADO 数据源传输到 Excel
246335 (http://support.microsoft.com/kb/246335/) 如何使用“自动化”功能将数据从 ADO 记录集传输到 Excel
247412 (http://support.microsoft.com/kb/247412/) INFO:将数据从 Visual Basic 传输到 Excel 的方法
278973 (http://support.microsoft.com/kb/278973/) SAMPLE:ExcelADO 演示如何在 Excel 工作簿中使用 ADO 来读写数据
318373 (http://support.microsoft.com/kb/318373/) 如何使用 Visual Basic .NET 中的 GetOleDbSchemaTable 方法从 Excel 中检索元数据
有关更多信息,请参阅以下 Microsoft 培训和认证教程:
Microsoft Corporation 1301 Mastering Office 2000 Solution Development(1301 熟练掌握 Office 2000 解决方案开发) (http://www.microsoft.com/traincert/syllabi/1301Afinal.asp)

回到顶端

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值