Jet OLEDB提供程序在Windows 7 64位上除Excel 2010之外的任何地方都可以使用

时间:2011-06-22 17:36:07

标签: excel windows-7 64-bit oledb jet

我正在使用“Microsoft.Jet.OLEDB.4.0”提供程序在某些VBA代码中进行基本连接,除了在运行64位Microsoft Office安装的Windows 7 64位操作系统之外,代码可以在任何地方使用Excel 2010。

XP 32或64,Vista 32或64和7 32的所有其他组合,使用Excel 2003,2007或2010安装运行此代码没有问题,但在上述系统中,它会导致错误关于“缺少提供者”,我无法创建连接字符串。

With Conn
    .Provider = "Microsoft.Jet.OLEDB.4.0"
    .Mode = adModeRead
    .ConnectionString = "Data Source=" & path & ";Extended Properties='text;HDR=YES;FMT=Delimited'"
    .Open
End With

我做了大量的研究,但据我所知,操作系统应该配备一整套提供程序,包括32位版本的Jet Provider(不存在64位版本) ,Excel应该没有问题使用它进行连接。有任何想法吗?

2 个答案:

答案 0 :(得分:2)

答案 1 :(得分:1)

我不知道这对我的具体例子之外的人是否有帮助。我正在使用提供程序对CSV执行查询。例如:

SELECT C7, 0.0001, (C2+C4*10000000) FROM (filename)

此处,源文件已被修改,因此所有列都按其标题命名为Cn:

csvColumns = UBound(Split(lineIn, Delimiter)) + 1
For icol = 1 To csvColumns: columnLine = columnLine & "C" & icol & Delimiter: Next icol

所以在我的情况下,我有一个看起来像这样的文件:

C1       C2       C3       C4       C5       C6       C7
1234     654332   23.214   5432     12345    123      60918234.234
2345     876332   43.223   6534     23456    234      34958732.432
3456     987332   54.243   7654     34567    345      92645378.564

通常,使用Jet OLEDB提供程序,可以使用上面的查询字符串将文件内容读入单元格:

On Error GoTo PoviderError
With Conn
    .Provider = "Microsoft.Jet.OLEDB.4.0"
    .Mode = adModeRead
    .ConnectionString = "Data Source=" & path & ";Extended Properties='text;HDR=YES;FMT=Delimited'"
    .Open
End With
Rst.Open "SELECT " & selectText & " FROM [" & file & "];", Conn, adOpenKeyset, adLockOptimistic, adCmdText
If Not Rst.EOF Then Destination.CopyFromRecordset Rst

但是在上面的代码中,“ProviderError”将在64位计算机上触发,因为没有可用的Jet提供程序。我的解决方法如下。我实际上将文件加载到excel中,并自己解析查询字符串。我用逗号分隔符打破查询字符串,以便查询字符串的每个部分成为新单元格的公式。要创建公式,我只需添加一个=符号,并将字符串“Cn”替换为对源列的引用。这样,(C2+C4*10000000)等复杂查询仍会得到评估。然后,我根据源数据的长度复制公式,然后用硬编码值覆盖公式。最终结果与执行复杂的Jet OLEDB查询相同,尽管稍慢。代码如下。

PoviderError:
    Resume FailOver 'Resets the error state so that further errors can be thrown
FailOver:
    FileReadFailover fixedFile, Destination, selectText, Delimiter
    ...

Private Sub FileReadFailover(ByVal fName$, ByRef Dest As Range, ByVal inputs$, ByVal delim$)
    Dim newBook As Workbook
    Dim pos(0 To 2) As Integer, col(0 To 2) As String
    Dim referenceText As String, i As Integer

    'Parse the query string 'inputs'
    pos(0) = 0: pos(1) = InStr(pos(0) + 1, inputs, ","): pos(2) = InStr(pos(1) + 1, inputs, ",")
    col(0) = Trim(Mid(inputs, pos(0) + 1, pos(1) - pos(0) - 1))
    col(1) = Trim(Mid(inputs, pos(1) + 1, pos(2) - pos(1) - 1))
    col(2) = Trim(Mid(inputs, pos(2) + 1))

    Application.StatusBar = Application.StatusBar & " Missing Jet Provider, waiting for Excel to open file..."
    Application.ScreenUpdating = True 'Allow excel to display the status bar showing the file loading
    Application.Workbooks.OpenText Filename:=fName, DataType:=xlDelimited, Other:=True, OtherChar:=delim
    Set newBook = Application.ActiveWorkbook
    Application.ScreenUpdating = False
    If newBook Is Nothing Then Err.Raise 1, , "User Cancelled Load"

    'Create a formula that will pull the values from the external file just opened.
    referenceText = Replace(newBook.Sheets(1).Cells(1, 1).Address(, , , True), "$A$1", "R[" & 2 - Dest.row & "]C")
    For i = 0 To 2
        If InStr(1, col(i), "C") Then col(i) = "=" & Replace(col(i), "C", referenceText)
        Dest.Offset(0, i).FormulaR1C1 = col(i)
    Next i
    'Copy the formulae down the based on the length of the input file
    Dest.Worksheet.Range(Dest, Dest.Offset(0, 2)).Copy _
        Dest.Worksheet.Range(Dest.Offset(1), Dest.Offset(newBook.Sheets(1).UsedRange.Rows.Count - 2, 2))
    'Make sure the worksheet recalculates to pull the values
    If Application.Calculation = xlCalculationManual Then Dest.Worksheet.Calculate
    'Now overwrite the formulas that pull the values with the values themselves
    Dest.Worksheet.Range(Dest, Dest.Offset(0, 2).End(xlDown)).Copy
    Dest.Worksheet.Range(Dest, Dest.Offset(0, 2).End(xlDown)).PasteSpecial xlPasteValues
    Application.CutCopyMode = False
    Application.StatusBar = "File Import Successful"

    newBook.Close (False)
End Sub

上面的解决方案假设一个包含3列的查询,但可以轻松调整以进行任何查询,使用split来获取尽可能多的列,并动态地重新生成pos()和col()数组。