【问题标题】:How to connect to Excel named range in ADODB SQL query如何在 ADODB SQL 查询中连接到 Excel 命名范围
【发布时间】:2019-01-03 11:27:35
【问题描述】:

我需要将数据从 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 列限制内,但如果以正确的方式做到这一点会很棒。

【问题讨论】:

  • 命名范围是动态的还是静态的? Dynamic 不适用于 ADO。
  • 名称的范围是什么 - 工作表或工作簿?
  • @buran 我想在工作表中动态命名特定范围,然后在查询中引用它,然后循环执行,因为它是一张表中的多个小表。
  • 多年前,Excel 被限制为 255 或 256 列。我怀疑尝试连接到 Excel 可能会遇到此限制:提供程序可能未设计为请求/查看超过该数量的列和/或 Excel 未设计为提供超出该数量的列的列。这也可能与 Access 表中 255 个字段的限制有关。
  • 使用命名范围应该可以解决列号问题(假设命名范围本身不超过 255 列,并且源工作簿已关闭)。我认为我们缺少有关如何/何时创建这些名称的相关代码。

标签: excel vba ms-access adodb


【解决方案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

【讨论】:

  • 有趣的解决方案。正如我之前所写的,我有一个解决这个问题的方法,但我发现它很有趣,所以在这里寻求帮助。
【解决方案2】:

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

【讨论】:

  • 我很久以前就完成了这个项目,但我喜欢你的意见。我没有测试它,但乍一看它应该可以工作。我会通过方括号引用数据库。
【解决方案3】:

你需要使用构造:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-02
    • 2019-06-08
    • 1970-01-01
    • 1970-01-01
    • 2016-01-23
    • 1970-01-01
    相关资源
    最近更新 更多