2016-07-29 6 views
4

Я пытаюсь выполнить запрос ADODB по именованному диапазону в книге Excel 2013.Проблемы в Excel 2013 при использовании диапазонов, выходящих за пределы строки 65536

Мой код выглядит следующим образом:

Option Explicit 
Sub SQL_Extract() 
    Dim objConnection   As ADODB.Connection 
    Dim objRecordset   As ADODB.Recordset 
    Set objConnection = CreateObject("ADODB.Connection")  ' dataset query object 
    Set objRecordset = CreateObject("ADODB.Recordset")   ' new dataset created by the query 

    objConnection.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;" & _ 
            "Data Source=" & ThisWorkbook.FullName & ";" & _ 
            "Extended Properties=""Excel 12.0;HDR=Yes;IMEX=1"";" 
    objConnection.Open 

    objRecordset.Open "SELECT * FROM [HighRange]", objConnection, adOpenStatic, adLockOptimistic, adCmdText 

    If Not objRecordset.EOF Then 
     ActiveSheet.Cells(1, 1).CopyFromRecordset objRecordset 
    End If 

    objRecordset.Close 
    objConnection.Close 
End Sub 

Если диапазон HighRange выходит за пределы строки 65536 (например, A65527: B65537) Я получаю сообщение enter image description here

об ошибке Если удалить достаточное количество строк, чтобы опускать диапазон ниже строки 65536, код работает.

Код также работает, если я принуждаю книгу читать только для чтения (и убедитесь, что у кого-то еще есть версия, не предназначенная для чтения).

Является ли это чем-то, что я делаю неправильно, или это ошибка в Excel 2013?

(проблема существует в обоих 32-битных и 64-битных версиях. Также существует в Excel 2016.)

+1

Я собираюсь угадать, что вы нашли экземпляр с MSoft, забыл изменить 'int' на' long' в своем коде двигателя MS Access db ... Звучит как ошибка для меня. Попробуйте в XL2016? –

+0

К сожалению, это рабочая ситуация, поэтому мы просто перейдем к Excel 2013. (Я не думаю, что у нас была проблема в Excel 2010.) – YowE3K

+3

http://forum.chandoo.org/threads/excel-recordset-only- return-65536-rows-if-you-try-to-pull-data-from-the-range.12492/ –

ответ

1

Я не смог найти фактический ответ на мою проблему, так что лучшая работа вокруг Я могу придумать, чтобы создать дополнительную книгу, скопировать мой диапазон на лист в этой книге (начиная с ячейки A1), сохранить эту книгу, а затем использовать эту рабочую книгу/рабочий лист в качестве источника запроса.

(Первоначально мне казалось, что я мог бы избежать просто создания временного листа в существующей книге, то есть без создания временной книги, но возникают проблемы, если у пользователя есть два экземпляра Excel - событие Connection.Open, открывает книгу в первом экземпляре Excel, даже несмотря на то, что мы запускаем макросы во втором экземпляре, и поэтому вновь открытая рабочая книга не содержит в ней фиктивного листа. И я не хочу сохранять копию существующая книга с фиктивным листа в нем.)

Sub SQL_Extract_Fudged() 
    Dim objConnection   As ADODB.Connection 
    Dim objRecordset   As ADODB.Recordset 
    Dim wsOrig As Worksheet 
    Dim wbTemp As Workbook 
    Dim wbTempName As String 
    Dim wsTemp As Worksheet 

    Set wsOrig = ActiveSheet 

    'Generate a filename for the temporary workbook 
    wbTempName = Environ$("TEMP") & "\TempADODBFudge_" & Format(Now(), "yyyymmdd_hhmmss") & ".xlsx" 
    'Create temporary workbook 
    Set wbTemp = Workbooks.Add 
    'Use first sheet as the place for the temporary copy of the range we want to use 
    Set wsTemp = wbTemp.Worksheets(1) 
    wsTemp.Name = "TempADODBFudge" 
    'Copy the query range to the temporary worksheet 
    wsOrig.Range("HighRange").Copy Destination:=wsTemp.Range("A1") 
    'Save and close the temporary workbook 
    wbTemp.SaveAs wbTempName 
    wbTemp.Close False 
    'Get rid of references to the temporary workbook 
    Set wsTemp = Nothing 
    Set wbTemp = Nothing 

    'Create connection and recordset objects 
    Set objConnection = CreateObject("ADODB.Connection") 
    Set objRecordset = CreateObject("ADODB.Recordset") 

    'Create the connection string pointing to the temporary workbook 
    objConnection.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;" & _ 
            "Data Source=" & wbTempName & ";" & _ 
            "Extended Properties=""Excel 12.0;HDR=Yes;IMEX=1"";" 
    objConnection.Open 

    'Perform the query against the entire temporary worksheet 
    objRecordset.Open "SELECT * FROM [TempADODBFudge$]", objConnection, adOpenStatic, adLockOptimistic, adCmdText 

    'Copy output (for this example I am just copying back to the original sheet) 
    If Not objRecordset.EOF Then 
     wsOrig.Cells(1, 1).CopyFromRecordset objRecordset 
    End If 

    'Close connections 
    objRecordset.Close 
    objConnection.Close 

    'Get rid of temporary workbook 
    On Error Resume Next 
    Kill wbTempName 
    On Error GoTo 0 

End Sub 

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