我需要将数据从 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 列限制之内,但如果能正确地做到这一点那就太好了。
不确定您是否会找到连接到命名范围的解决方案。我看了一下让它工作,但我也没有运气,我怀疑它没有包含在过去 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
我遇到了同样的问题,解决方案非常简单,尽管它仅适用于工作簿级别的命名范围。 必须连接到工作簿(即 [Excel 12.0 Macro;HDR=Yes;Database=C:\MyPath\MyFile.xlsb])。 然后在查询中输入: SELECT * FROM [myRange] (请注意方括号和没有 $ 符号)
你需要使用一个结构:
[Excel 12.0 Macro;HDR=Yes;Database=C:\MyPath\MyFile.xlsb].[$myRange]
我找到了这个链接sql on range
我已经测试了大部分内容,没有任何问题。我将添加一个新示例,该示例也可以使用名为 range 的工作表
strQuery = “SELECT * FROM [Sheet1$mynamedrange]“