如何插入从 Excel 到 SQL table 的范围

How do you INSERT a range from Excel to an SQL table

我正在使用一个旧的宏,它将定义的范围从 Excel 发送到 MS Access 数据库,并希望对其进行调整以发送到 SQL 服务器数据库。

旧代码(效果很好,我不是作者):

'ExportAccess

Dim db As DAO.Database
Dim Rst As DAO.Recordset

Dim localMDB As String 'this is the address of the access mdb, removed from this snippit

sht = ActiveCell.Worksheet.Name
With Worksheets(sht)
   .Range("L1:A" & .Range("A65536").End(xlUp).Row).Name = "Range"
End With

Set db = OpenDatabase(ActiveWorkbook.FullName, False, False, "excel 8.0")

db.Execute "INSERT INTO myTable IN '" & localMDB & "' SELECT * FROM [Range]", dbFailOnError 

我的修改尝试:

Dim db As DAO.Database 'sql database
Dim rs As DAO.Recordset
  
Dim bd As DAO.Database 'excel sheet?
Dim Rst As DAO.Recordset
    
Set db = OpenDatabase("myDatabase", dbDriverNoPrompt, False, "ODBC;DATABASE=DB_Backup;DSN=myDatabase") 

sht = ActiveCell.Worksheet.Name
With Worksheets(sht)
   .Range("B1:A" & .Range("A65536").End(xlUp).Row).Name = "Range"
End With
    
db.Execute "INSERT INTO myTable SELECT * FROM [Range]", dbFailOnError

当我 运行 我的尝试时,它给出了我的“范围”未定义的错误。 任何帮助将不胜感激,谢谢!

第一个代码块成功运行的原因是您连接到 Microsoft Access Jet/ACE 引擎,它可以查询 Access 数据库表、Excel 工作簿,甚至 CSV 文本文件。请注意如何将 db 直接设置为 Excel 工作簿,并且追加查询在外部连接到 Access 数据库。只有 Jet/ACE 引擎支持此语法。

但是,在第二个代码块中,您连接到外部数据库,即 SQL 服务器,而不是 Jet/ACE 引擎。因此,不支持类似的语法。具体来说,如错误所示,[Range] 不存在,因为您未连接到工作簿。您需要指定 VBA 范围内的所有单元格数据,以便进行适当的数据迁移。不要将 SQL Server 与 MS Office 混为一谈,即使它们是同一家公司的产品。


考虑 parameterization 个值的 ADO(而不是 DAO)。请务必在追加 SQL 查询中明确命名列。虽然您的实际范围不确定,但下面循环了范围的第一列并使用 .Offset 遍历当前行中的列。调整 SQL、范围限制、参数和类型以与实际数据保持一致。

Sub SQLServerAppend()
    ' ADD REFERENCE FOR Microsoft ActiveX Data Objects #.# Library
    Dim con As ADODB.Connection, cmd As ADODB.Command
    Dim cell As Range
    Dim strSQL As String

    Set con = New ADODB.Connection
    con.Open "DSN=myDatabase"

    ' PREPARED STATEMENT WITH QMARK PLACEHOLDERS
    strSQL = "INSERT INTO myTable (Col1, Col2, Col3, ...) " _
           & " VALUES (?, ?, ?, ...)"

    sht = ActiveCell.Worksheet.Name
    With Worksheets(sht)
        For Each cell In .Range("A1", .Range("A1").End(xlDown))
            Set cmd = New ADODB.Command
            With cmd
                .ActiveConnection = con
                .CommandText = strSQL
                .CommandType = adCmdText

                ' BIND PARAMETERS WITH ? IN SQL (ALIGN VALUES TO ADO TYPES)
                ' FIRST COLUMN OF ROW RANGE
                .Parameters.Append .CreateParameter("col1param", adVarChar, adParamInput, , cell.Offset(0, 0).Value)
                ' SECOND COLUMN OF ROW RANGE
                .Parameters.Append .CreateParameter("col2param", adDate, adParamInput, , cell.Offset(0, 1).Value)
                ' THIRD COLUMN OF ROW RANGE
                .Parameters.Append .CreateParameter("col3param", adDecimal, adParamInput, , cell.Offset(0, 2).Value)
                '... ADD OTHER COLUMNS

                ' RUN APPEND ACTION
                .Execute
            End With
        Next cell

    con.Close
    Set cmd = Nothing: Set con = Nothing
End Sub

我已经使用来自@Parfait 的循环修改了我的代码,使其适用于我。由于我的 DAO 连接正常,我决定坚持使用它。

Sub ToDbase()
'Modified by ployer. This sends values from an exel spreadsheet to your sql database
'with code from Parfait 

   Dim db As DAO.Database 'sql database
   Dim rs As DAO.Recordset

   Set db = OpenDatabase("myDB", dbDriverNoPrompt, False, "ODBC;DATABASE=myDB_Backup;DSN=myDB")

Dim cell As Range

Dim Value1 As String 'First value to import
Dim Value2 As String 'Second value to import. Add more as needed with the correct types

Dim i As Integer 'for testing in my exel sheet before trying in db
Dim n As Integer 'for testing in my exel sheet before trying in db

i = 1
n = 1

sht = ActiveCell.Worksheet.Name
    With Worksheets(sht)
        For Each cell In .Range("A1", .Range("A1").End(xlDown))
        
        Value1 = cell.Offset(0, 0).Value 'Assign to variable "Value1" the value stored in Cell at position 0,0 (First time through would be A1)
        Value2 = cell.Offset(0, 1).Value 'Assign to variable "Value2" the value stored in Cell at position 0,0 (First time through would be B1)
        
        'For testing if iteration works.
        'Cells(i, 5).Value = Value1
        'Cells(n, 6).Value = Value2
        'i = i + 1
        'n = n + 1


'each time we go through the loop the Value1 and Value2 get sent to Col1 and Col2 in myTable. You need to define the value of Col1, for instance, if in the db it is called Customer it needs to be written Customer here.
        db.Execute "INSERT INTO myTable (Col1, Col2) Values ('" & Value1 & "','" & Value2 & "') ", dbFailOnError
        
        Next cell
    
End With
End Sub