如何在 ADODB SQL 查询中连接到 Excel 命名范围

问题描述 投票:0回答:4

我需要将数据从 Excel 工作表移至数据库。为此,我创建了 ADODB 连接,并且能够执行这样的 SQL 查询:

INSERT INTO myTable SELECT * FROM [Excel 12.0 Macro;HDR=Yes;Database=C:\MyPath\MyFile.xlsb].[Shee1$A1:C100]

我的问题是范围不能指向超过 255 列,即 IU 列。我想尝试使用命名范围,但我找不到合适的符号。我发现的所有示例都直接连接到工作簿,并使用

SELECT * FROM [Sheet1$]
引用或
SELECT * FROM myRange
作为命名范围的示例。我尝试过类似的事情

[Excel 12.0 Macro;HDR=Yes;Database=C:\MyPath\MyFile.xlsb].[myRange]
[Excel 12.0 Macro;HDR=Yes;Database=C:\MyPath\MyFile.xlsb].[myRange$]
[Excel 12.0 Macro;HDR=Yes;Database=C:\MyPath\MyFile.xlsb].myRange
[Excel 12.0 Macro;HDR=Yes;Database=C:\MyPath\MyFile.xlsb;Name=myRange]

,但没有成功。

在这里使用命名范围的正确方法是什么?它甚至有助于解决列数限制吗?

我期望

[Excel 12.0 Macro;HDR=Yes;Database=C:\MyPath\MyFile.xlsb].[myRange]
能够工作,但它抛出以下错误:“Microsoft Access 数据库引擎找不到对象“myRange”。确保该对象存在 (...)'

我可以通过将数据从源表复制到临时表来解决这个问题,并将其限制在 255 列限制之内,但如果能正确地做到这一点那就太好了。

excel vba ms-access adodb
4个回答
1
投票

不确定您是否会找到连接到命名范围的解决方案。我看了一下让它工作,但我也没有运气,我怀疑它没有包含在过去 255 列的模式中,但可能是错误的。

我认为您最好有一个不依赖循环将数据添加到 Access 的有效解决方案。它的代码比仅仅执行插入要多,但我希望它适合您的具体问题。

我能够在大约 3 秒内插入约 2500 条记录(都是整数),所以速度相当快。

Option Explicit

Private Function GetDisconnectedRecordset(TableName As String) As ADODB.Recordset
    Dim conn As ADODB.connection: Set conn = getConn()
    Dim rs   As ADODB.Recordset: Set rs = New ADODB.Recordset

    With rs
        .CursorLocation = adUseClient ' <-- needed for offline processing
        'Get the schema of the table, don't return anything
        .Open "Select * from " & TableName & " where false", conn, adOpenDynamic, adLockBatchOptimistic
    End With

    rs.ActiveConnection = Nothing
    conn.Close
    Set conn = Nothing
    Set GetDisconnectedRecordset = rs
End Function

'Do an update batch of the data
'Portion used from: https://stackoverflow.com/questions/32821618/insert-full-ado-recordset-into-existing-access-table-without-loop
Sub PopulateDataFromNamedRange()
    Dim conn        As ADODB.connection
    Dim ws          As Excel.Worksheet: Set ws = ThisWorkbook.Worksheets("Sheet2") 'Update to your sheet/wb
    Dim NamedRange  As Excel.Range: Set NamedRange = ws.Range("Test") ' Update to your named range
    Dim NamedItem   As Excel.Range
    Dim rs          As ADODB.Recordset: Set rs = GetDisconnectedRecordset("[TestTable]") 'Specify your table name in access
    Dim FieldName   As String
    Dim Row         As Long
    Dim AddRow      As Long

    'Add Data to the disconnected recordset
    For Each NamedItem In NamedRange
        If Not NamedItem.Row = 1 Then
            Row = NamedItem.Row
            If Not Row = AddRow Then rs.AddNew
            AddRow = NamedItem.Row
            FieldName = ws.Cells(NamedItem.Row - (NamedItem.Row - 1), NamedItem.Column).Value
            rs.Fields(FieldName).Value = NamedItem.Value
        End If
    Next

    'Connect again
    Set conn = getConn()
    Set rs.ActiveConnection = conn

    rs.UpdateBatch '<-- 'Update all records at once to Access
    conn.Close
End Sub

Private Function getConn() As ADODB.connection
    Dim conn As ADODB.connection: Set conn = New ADODB.connection
    conn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\Ryan\Desktop\Example.accdb"
    Set getConn = conn
End Function

1
投票

我遇到了同样的问题,解决方案非常简单,尽管它仅适用于工作簿级别的命名范围。 必须连接到工作簿(即 [Excel 12.0 Macro;HDR=Yes;Database=C:\MyPath\MyFile.xlsb])。 然后在查询中输入: SELECT * FROM [myRange] (请注意方括号和没有 $ 符号)


0
投票

你需要使用一个结构:

[Excel 12.0 Macro;HDR=Yes;Database=C:\MyPath\MyFile.xlsb].[$myRange]

0
投票

我找到了这个链接sql on range

我已经测试了大部分内容,没有任何问题。我将添加一个新示例,该示例也可以使用名为 range 的工作表

strQuery = “SELECT * FROM [Sheet1$mynamedrange]“
© www.soinside.com 2019 - 2024. All rights reserved.