使用超出行65536的范围时Excel 2013中的问题

时间:2016-07-29 03:34:11

标签: excel vba excel-vba adodb

我正在尝试在Excel 2013工作簿中的命名区域上执行ADODB查询。

我的代码如下:

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中。)

2 个答案:

答案 0 :(得分: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

我仍然更喜欢这个问题的更强大的解决方案,所以希望别人能够提出另一个答案。

答案 1 :(得分:0)

好吧,如果这仍然是一个未解决的问题,我遇到了同样的问题并通过不指定查询范围内的任何行号来解决它。例如:

我试图查询[SheetName $ A1:W100000],这给了我完全相同的错误。然后我将范围指定为[SheetName $ A:W]并且它是weeerks!

希望这有帮助!