1

我正在使用 ADO ( ) 将电子表格从 Excel 2003 导入 Access 2003 Provider = "Microsoft.Jet.OLEDB.4.0"。但是,我在日期字段中有一些文本条目。#Num!正如您所料,这些都是作为值出现的。

我想做的是将有问题的字段包装在类似IIf(IsDate(FIELDNAME),FIELDNAME,#1/1/1900#). 但是,这仍然会导致#Num!. 测试IsDate(), IsDate(CVar()), IsError(),IsError(CDat())和 也是如此VBAFunctionThatReturns0GivenAnyValue(FIELDNAME)

任何人都知道我可以使用的包装函数来完成这项工作吗?我或多或少已无计可施?

请注意:我无法控制导入的数据,因此我无法修复电子表格,就像我想的那样。我还想避免在导入函数本身中出现特定的骇客(例如,改用 TransferSpreadsheet)。目标是使用相同的方法来引入数据,只是忽略不起作用的位。

还应该指出,这里的非日期值被丢弃是合适的。理想情况下,导入为文本是我想避免的,因为它会在链条的下游导致各种其他错误。

编辑:添加了 2003 年的规定。我还应该指出,安装在环境中的 .Net 框架版本不包括(或似乎不包括)ACE.12.0 提供程序。

编辑 2:根据要求,这是我正在执行的 SQL 的(稍微清理过的)版本。请注意,这不是确切的查询,但在同一个电子表格上运行它会导致相同的问题:

SELECT 
    CStr(Nz([Notes], "")), 
    [ID],
    [Date]
INTO
    [;DATABASE=C:\DatabaseTarget.Mdb].[tblImport]
FROM
    [Excel 8.0;Database=C:\ExcelSheet.xls].[sheet1$]
WHERE
    [ID] IS NOT NULL

通过取出INTO子句并查看[Date]. 如果其中任何一个是Then 甚至对所有 Test1-5#Num!执行以下结果,这反而证明了这个问题。:#Num!

SELECT 
    CStr(Nz([Notes], '')), 
    [ID],
    CStr(Nz([Date],'')) As [Test1],
    IsError([Date]) As [Test2],
    IsDate([Date]) As [Test3],
    IsNull([Date]) As [Test4],
    IIf(True, 1, [Date]) As [Test5],
FROM
    [Excel 8.0;Database=C:\ExcelSheet.xls].[sheet1$]
WHERE
    [ID] IS NOT NULL
4

2 回答 2

0

测试IsNull()看起来应该可以工作。对于 Excel 数据...

ID  ActivityDescription ActivityDate
1   activity_1          2013-05-12
2   activity_2          2013-05-13
3   activity_3          2013-05-14
4   activity_4          2013-05-15
5   activity_5          2013-05-16
6   activity_6          2013-05-17
7   activity_7          2013-05-18
8   activity_8          2013-05-19
9   activity_9          2013-05-20
10  activity_10         2013-05-21
11  activity_11         2013-05-22
12  activity_12         2013-05-23
13  activity_13         oops!
14  activity_14         2013-05-25
15  activity_15         2013-05-26

...以下访问 VBA 代码...

Sub adoTest()
Dim con As ADODB.Connection, rst As ADODB.Recordset
Set con = New ADODB.Connection
con.Open _
        "Provider=Microsoft.JET.OLEDB.4.0;" & _
        "Data Source=C:\Users\Public\xlsTest.xls;" & _
        "Extended Properties=""Excel 8.0;HDR=YES"";"
Set rst = New ADODB.Recordset
rst.Open "SELECT * FROM [Sheet1$]", con
Do While Not rst.EOF
    Debug.Print _
            Format(rst("ID").Value, "00") & _
            "  " & _
            IIf(IsNull(rst("ActivityDate").Value), "<NULL>", rst("ActivityDate").Value)
    rst.MoveNext
Loop
rst.Close
Set rst = Nothing
con.Close
Set con = Nothing
End Sub

...产生这个:

01  2013-05-12
02  2013-05-13
03  2013-05-14
04  2013-05-15
05  2013-05-16
06  2013-05-17
07  2013-05-18
08  2013-05-19
09  2013-05-20
10  2013-05-21
11  2013-05-22
12  2013-05-23
13  <NULL>
14  2013-05-25
15  2013-05-26

这表明IsNull()将“错误”日期值识别为Null并替换为文本<NULL>

根据上下文,该Nz()功能也可能被证明是有用的。

于 2013-05-13T14:46:58.200 回答
0

#数字!错误似乎是由提供者在遇到大多数可用于查询中的错误处理的错误方法之前引发的。坚持使用 ADO 似乎很容易失败。

但是,在 DAO 中测试我的查询(没有INTO仅生成记录集的子句)确实产生了有效的 sata,所以我认为 DAO 是否可以处理对 OLEDB 记录源的查询可能值得一看。原来可以!

因此最终代码看起来像

On Error Resume Next
cmdFirstTry.Execute '' Includes fields which are pulled through as #Num! errors
Select Case Err.Number
    Case 0
        On Error Goto ErrorHandler
    Case &H80040E14
        '' Failed in this manner; Try with DAO
        On Error Goto ErrorHandler
        CurrentDb.Execute strSQL
    Case Else
        lngErrNum = Err.Number
        strErrDesc = Err.Description
        On Error Goto ErrorHandler
        Err.Raise lngErrNum, , strErrDesc
End Select

对于我的需要,这可以完成工作,但我不会在几天内接受作为答案,以防真的有一种优雅的方法。

于 2013-05-13T15:43:54.443 回答