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