我正在尝试使用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,但是出现了Undefined Function错误。
答案 0 :(得分: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
如果在设置这些条件后失败,我会觉得您的工作表名称或查询本身有问题。
答案 1 :(得分:0)
您可以尝试将IMEX=1;
附加到扩展属性。这告诉JET DB将混合数字,日期和字符串作为文本读取。然后你应该能够:
SELECT * FROM [F1$]
即,如果F1
是第一个工作表的名称。
答案 2 :(得分:0)
问题是Microsoft Jet 4.0引擎不支持CAST()
函数,它也没有VARCHAR
关键字(也不是VARCHAR
数据类型。你为什么需要施放这个值?您需要处理NULL
值吗?
说到数据类型:
F1 >= 2.3456
值2.3456
是DECIMAL
类型的文字,是固定点十进制。 Excel没有固有的十进制固定类型,因此您最有可能将浮点值与定点值进行比较。我相信您会理解这可能导致的问题!
答案 3 :(得分:0)
你的谓词
F1 >= 2.3456
建议F1
是数字数据类型。请解释如何将数值转换为VARCHAR
,并期望得到*
...?我自己也看不到它!
如果您的列包含数值和*
个字符,那么它将是混合类型,Jet 4.0引擎需要决定是否选择FLOAT
(在这种情况下,您的*字符将被替换NULL
值)或NVARCHAR(255)
类型(在这种情况下,您的数值可能会转换为科学记数法)。
您可以使用注册表值来影响结果,但是没有希望在SQL代码中执行此操作,因为已经选择了数据类型。
更多细节请见所谓的专家Daily Dose of Excel: External Data - Mixed Data Types :)评论中隐藏了很多细节。
答案 4 :(得分:0)
我认为你需要:
CAST
和VARCHAR
个关键字
从你的查询(他们是非法的); TypeGuessRows = 0
(强制扫描
扫描所有行应该确定
列是混合类型...); ImportMixedTypes = Text
(... to
将混合类型作为文本导入
默认值)。有关详细信息,请参阅以前的答案。完成后,您的'*'字符将出现在列中(即不再是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重载,将评估TRUE
或FALSE
条件,但不会同时评估两者。在VBA中情况恰恰相反,即总是评估两个条件。在Access数据库引擎SQL或VBA中,SWITCH()
不会快捷方式。