ADODB.Connection не отражает текущие поля набора данных;'[Microsoft] [ODBC Excel Driver] Слишком мало параметров.Ожидаемое 11 - PullRequest
0 голосов
/ 20 ноября 2018

Ниже приведен пример использования процедуры для чтения данных из входных файлов Excel, сохраненных в папке.Запрос SQl имеет операции соединения из нескольких таблиц (листов), которые являются частью reportWorkbook .После успешного выполнения этой процедуры для некоторых файлов на каком-то этапе выдается ошибка '[Microsoft] [ODBC Excel Driver] Слишком мало параметров.Ожидается 11. ' для следующего входного файла.

Sub RunQueryOnInputFiles ()

Dim fldr            As Folder
Dim fil             As File
Dim oConn           As ADODB.Connection
Dim oRs             As ADODB.Recordset
Dim tmpWkb          As Workbook
Dim reportWorkbook  As Workbook
Dim sSql            As String

Set reportWorkbook = Workbooks.Add
reportWorkbook.Save tmpFilePath

'Loop through all files in input folder

    For Each fil In fldr.Files                                              
        Set tmpWkb = Workbooks.Open(fil.Path)
        tmpWkb.Sheets(1).Range("A1").CurrentRegion.Copy
        reportWorkbook.Sheets("TmpSheet").Range("A1").Paste xlPasteValues   
'Paste input data
        tmpWkb.Close SaveChanges:=False

        Set oConn = OpenConnection(reportWorkbook.FullName)
        sSql = GenrateSQL("SOME QUERY FROM SHEET [TmpSheet$]")              
'Genrate SQL query from [TmpSheet$]`
        Set oRs = GetRecordset(sSql, oConn)
        reportWorkbook.Sheets("XYZ").Range("A1").CopyFromRecordset oRs
        CloseConnection oConn
    Next fils

End Sub

Я отлаживаю проблему отдельно, используя описанную ниже процедуру

Sub testing()
    Dim sSql As String
    Dim x As ADODB.Connection
    Dim r As Object
    Dim fl As Object
    sSql = "SELECT * FROM [TmpSheet$A1:U4]"
'considering reportWorkbook is in scope it is same workbook
    Set x = OpenConnection(reportWorkbook.FullName)    
    GetRecordset sSql, x
    Set r = GetRecordset(sSql, x)
    For Each fl In r.Fields
        Debug.Print fl.Name
    Next
End Sub

Здесь fl.Name возвращает имена, принадлежащие предыдущемуфайл, который уже обработан и данные на TmpSheet уже перезаписаны.Выполнение той же процедуры test () через несколько минут показывает правильные поля, доступные в Tmpsheet.

Кажется, что соединение не может быть обновлено.Пожалуйста, предложите какой-нибудь метод, который может принудительно обновлять соединение во время выполнения.

1 Ответ

0 голосов
/ 20 ноября 2018

С момента публикации вашего сокращенного кода проблема, с которой вы сталкиваетесь, это запрос самой книги, которую вы обрабатываете, которая всегда отражает снимок последнего сохраненного экземпляра.

Рассмотрите возможность включения Workbook.Save метод после обработки каждого файла Excel в цикле.

For Each fil In fldr.Files                                              
    ...

    reportWorkbook.Save
Next fils

Кроме того, рассмотрите возможность запроса текущей рабочей книги в цикле, чтобы избежать затрат на открытие файла, копирование и вставку значений.

For Each fil In fldr.Files                                              
    ' QUERY CURRENT WORKBOOK
    Set oConn = OpenConnection(fil.Path)
    sSql = GenrateSQL("SELECT * FROM [Sheet1$]") 
    Set oRs = GetRecordset(sSql, oConn)
    reportWorkbook.Sheets("TmpSheet").Range("A1").CopyFromRecordset oRs
    oRs.Close()
    CloseConnection oConn

    ' QUERY MASTER WORKBOOK
    Set oConn = OpenConnection(reportWorkbook.FullName)
    sSql = GenrateSQL("SOME QUERY FROM SHEET [TmpSheet$]")                      
    Set oRs = GetRecordset(sSql, oConn)
    reportWorkbook.Sheets("XYZ").Range("A1").CopyFromRecordset oRs
    oRs.Close()
    CloseConnection oConn

    reportWorkbook.Save
Next fils

Дополнительные примечания:

  • Похоже, вы перезаписываете данные в листе XYZ при каждой итерации цикла, если это является намерением.Добавьте или измените лист, чтобы избежать перезаписи.

  • Если ваши листы имеют заголовки, обязательно скопируйте набор записей, начинающийся с A2, и имена полей цикла, начинающиеся с A1 (например, ваш testing() подпрограмма).Или используйте статические заголовки в строке 1.

  • Для нижнего решения для запроса зацикленной книги, если лист не известен заранее, вам нужно будет открыть документ в цикле, чтобы получить имя листа и передать егов первый запрос SQL.

...