Поставщик Jet OLEDB работает везде, кроме Excel 2010 в Windows 7 64-bit - PullRequest
1 голос
/ 22 июня 2011

Я использую поставщика «Microsoft.Jet.OLEDB.4.0» для базового соединения в некотором коде VBA, и код работает везде, кроме 64-разрядных операционных систем Windows 7, работающих под управлением 64-разрядной установки Microsoft Office.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 ]

2 голосов
/ 22 июня 2011

эта ссылка может дать решение вашей проблемы: http://ellisweb.net/2010/01/connecting-to-excel-and-access-files-using-net-on-a-64-bit-server/

1 голос
/ 04 июля 2011

Я не знаю, будет ли это полезно людям за пределами моего конкретного примера.Я использовал провайдера для выполнения запроса на 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, чтобы получить столько столбцов, сколько имеется, и динамически изменить позицию) и массивы col ().

...