0

我正在尝试使用 VBScript 查询 .xls 电子表格,但在尝试转换字段时遇到了问题。
我像这样连接到电子表格。

Set objConnection = CreateObject("ADODB.Connection")
objConnection.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & DataSource & ";Extended Properties=""Excel 8.0;HDR=No;"";" 

然后我尝试查询电子表格。我感兴趣的字段包含十进制值,但也可以包含 * 作为通配符。所以我想要做的是将字段转换为 varchar,这样我就可以检查 *.

Set objRecordset = CreateObject("ADODB.Recordset")
StrQuery = "SELECT * FROM [Sheet1$] WHERE F1 >= 2.3456 OR CAST(F1 AS VARCHAR) = '*'"
objRecordset.Open StrQuery, objConnection, adOpenDynamic, adLockOptimistic

这会导致未指定的错误 80004005。我在这里做错了什么?
注意:我也尝试过 CONVERT,但出现未定义函数错误。

4

5 回答 5

1

我会更改您服务器上的以下注册表项(当然是在备份之后):

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\4.0\Engines\Excel\ImportMixedTypes = Text
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\4.0\Engines\Excel\TypeGuessRows = 0

我还将您的连接字符串修改为以下内容:

Dim sConnectionString As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Server.MapPath("/PathTo/YourFile/" & Filename) & ";"
If chkUploadFileColumnsFirstRow.Checked Then
  sConnectionString &= "Extended Properties='Excel 8.0;HDR=YES;IMEX=1'"
Else
  sConnectionString &= "Extended Properties='Excel 8.0;IMEX=1'"
End If

如果在设置这些条件后失败,我会觉得您的工作表名称或查询本身有问题。

于 2009-11-06T14:51:22.667 回答
0

您可以尝试附加IMEX=1;到扩展属性。这告诉 JET DB 将混合数字、日期和字符串作为文本读取。然后你应该能够:

SELECT * FROM [F1$]

也就是说,ifF1是第一个工作表的名称。

于 2009-11-06T14:45:53.163 回答
0

问题是Microsoft Jet 4.0 引擎不支持该CAST()功能,也没有VARCHAR关键字(也没有VARCHAR数据类型,算了)。为什么需要转换这个值?你需要处理NULL价值吗?

说到数据类型:

F1 >= 2.3456

该值是定点十进制2.3456类型的文字。DECIMALExcel 没有本机固定十进制类型,因此您很可能将浮点值与定点值进行比较。我相信您会理解这可能导致的问题!

于 2009-11-06T15:47:34.363 回答
0

你的谓词

F1 >= 2.3456 

建议F1是数字数据类型。请解释如何将数值转换为VARCHAR并期望得到*结果......?我自己看不到它发生!

如果您的列包含数值和*字符,那么它将是混合类型,Jet 4.0 引擎需要决定是选择FLOAT(在这种情况下您的 * 字符将被NULL值替换)还是类型NVARCHAR(255)(在这种情况下您的数字值可以转换为科学计数法)。

您可能能够使用注册表值来影响结果,但在 SQL 代码中没有希望这样做,因为已经选择了数据类型。

更多详细信息,请参阅Excel 的每日剂量:外部数据 -所谓专家的混合数据类型 :) 评论中隐藏了很多很好的细节。

于 2009-11-06T16:32:59.467 回答
0

我认为你需要:

  1. 从查询中删除CASTandVARCHAR关键字(它们是非法的);
  2. 更改本地机器注册表项TypeGuessRows = 0(强制扫描扫描所有行应确定该列是混合类型...);
  3. 确保本地机器注册表项ImportMixedTypes = Text(...将混合类型作为文本导入,作为默认值)。有关详细信息,请参阅以前的答案。

完成后,您的 '*' 字符将出现在列中(即不再是NULL)。但是,您的浮点值将被强制转换为文本。您可以在 SQL 中将浮点文本值强制转换为数字,但首先您必须测试NULL一个数字值,例如

SELECT F1, 
       IIF(
           F1 IS NULL, 
           '{{Excel cell is blank}}', 
           IIF(
               F1 = '*', 
               '{{Excel cell is the ''*'' character}}', 
               IIF(
                   ISNUMERIC(F1), 
                   CDBL(F1), 
                   '{{Excel cell is non-nmeric and not the ''*'' character}}'
                  )
              )
       ) AS result       
FROM [F1$];

注意我通常更喜欢SWITCH()嵌套IIF(),但在这种情况下它必须是IIF(). 原因:IIF()如果为 Access 数据库引擎 SQL 重载,并且将评估TRUEFALSE条件,但不会同时评估两者。在 VBA 中,情况正好相反,即始终评估两个条件。SWITCH()在 Access 数据库引擎 SQL 或 VBA 中都没有快捷方式。

于 2009-11-07T09:54:57.500 回答