2016-07-29 14 views
4

Ich versuche, eine ADODB-Abfrage für einen benannten Bereich in einer Excel 2013-Arbeitsmappe durchzuführen.Probleme in Excel 2013 bei Verwendung von Bereichen, die über Zeile 65536 hinausgehen

Mein Code ist wie folgt:

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 

Wenn der Bereich HighRange erstreckt sich über Zeile 65.536 (zB A65527: B65537) Ich erhalte eine Fehlermeldung enter image description here

Wenn ich genug Zeilen entfernen die fallen Bereich unter Zeile 65536 funktioniert der Code.

Der Code funktioniert auch, wenn ich erzwinge, dass die Arbeitsmappe schreibgeschützt ist (und sicherstellen, dass niemand eine nicht schreibgeschützte Version geöffnet hat).

Ist das etwas, was ich falsch mache, oder ist das ein Fehler in Excel 2013?

(Problem existiert sowohl in 32-Bit- und 64-Bit-Versionen. Existiert auch in Excel 2016.)

+1

Ich werde vermuten, dass Sie eine Instanz mit MSoft vergessen, ein 'int' in ein' long' in ihrem MS Access db-Engine-Code zu ändern ... Klingt wie ein Fehler für mich. Versuchen Sie es in XL2016? –

+0

Leider ist es eine Arbeitssituation, also gehen wir einfach zu Excel 2013. (Ich glaube nicht, dass wir das Problem in Excel 2010 hatten.) – YowE3K

+3

http://forum.chandoo.org/threads/excel-recordset-only- returns-65536-rows-Wenn-du-Versuch-zu-ziehen-Daten-aus-einem-Bereich.12492/ –

Antwort

1

Ich habe nicht in der Lage gewesen, eine tatsächliche Antwort auf mein Problem zu finden, so dass die besten Work-around Ich könnte eine zusätzliche Arbeitsmappe erstellen, meinen Bereich in ein Arbeitsblatt in dieser Arbeitsmappe kopieren (ab Zelle A1), diese Arbeitsmappe speichern und dann diese Arbeitsmappe/dieses Arbeitsblatt als Quelle der Abfrage verwenden.

(Ich dachte ursprünglich, ich könnte einfach nur ein temporäres Arbeitsblatt in der bestehenden Arbeitsmappe erstellen, dh ohne eine temporäre Arbeitsmappe erstellen, aber Probleme auftreten, wenn der Benutzer zwei Instanzen von Excel aktiv hat - die Connection.Open Ereignis- Öffnet die Arbeitsmappe in der ersten Instanz von Excel, obwohl wir die Makros in der zweiten Instanz ausführen, und daher enthält die wieder geöffnete Arbeitsmappe nicht das Dummy-Arbeitsblatt darin, und ich möchte keine Kopie davon speichern die vorhandene Arbeitsmappe mit einem Dummy-Blatt in ihm.)

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 

ich würde immer noch eine robustere Lösung für dieses Problem bevorzugen, so würde jemand anderes zu kommen mit einer anderen Antwort liebt.