Insert into Access Select from Excel from within Access VBA

Insert into Access Select from Excel from within Access VBA

我有一个 Access 2010 数据库,所有 table 都链接到 SQL Server 2014 table。我有一个 Excel 2010 (.xlsx) 文件(尽管它以 .csv 开头,我可以保留它),我需要将其导入 SQL 服务器 table通过 VBA 代码。我知道有导入工具可用于执行此操作,但是,我每个月要导入 20 多个 XLS 文件,因此我宁愿使用自动化方法来执行此操作。

我所有的 VBA 代码都驻留在 Access 数据库中,我能找到的所有 VBA 代码示例都是针对 pushing来自 Excel 的数据(即代码在 Excel 中)而不是 从 Access 中拉取(即代码在 Access 中)。

我宁愿使用单个 INSERT INTO AccessTable SELECT FROM ExcelRange 查询而不是逐行读取 Excel,并且我需要在插入之前对 Excel 数据进行一些转换.

我目前拥有的:

Private Sub TransferData(ByVal Company As String, ByVal Address As String, ByVal XLName As String)

Dim Con As ADODB.Connection
Dim SQLString As String

  SQLString = "INSERT INTO SatSurvey " & _
              "(ClinicID, Method, CollectionDate, Duration, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q10, Q11, Q12, Q13, Q14, Q15, Q16, Q17, Q18, Q19, Q20, Q21, Q22, Physician, Nurse, MedAst) " & _
              "SELECT " & _
              "('clinic name', IDFormat, IDendDate, IDtime, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q10, Q11, Q12, Q13, Q14, Q15, Q16, Q17, Q18, Q19, Q20, Q21, Q22, NZ(Q9s1,1), NZ(Q9s2,1), NZ(Q9s3,1)) " & _
              "  FROM [Excel 12.0;HDR=Yes;Database=" & XLName & "]." & Address

  Set Con = New ADODB.Connection
'  Con.ConnectionString = "Datasource=" & CurrentProject.Connection
  Con.ConnectionString = CurrentProject.Connection

'  Con.Properties(9).Value = "Extended Properties='Excel 12.0 Xml;HDR=YES';"
'  Con.Provider = "Microsoft.ACE.OLEDB.12.0;Extended Properties='Excel 12.0 Xml;HDR=YES';"

  Con.Open

  Con.Execute SQLString

End Sub

如您所见,我已经尝试了几个不同的选项来让事情正常进行。这似乎是最好的 除了 我现在得到的:

Run-time error '-2147467259 (80004005)':
The Database has been placed in a state by user 'Admin' on machine 'MINIT-EGHJSAU' that prevents it from being opened or locked.

指示的机器名称是我的机器。由于代码是 运行 来自我机器上的 Access,因此我打开数据库似乎是合乎逻辑的。

我并不一定要这样做,所以欢迎任何修正或替代建议。

我发现通过从 Excel 实际链接或导入 table 更容易做到(和调试!)然后你就可以像其他任何东西一样使用它了 table.

DoCmd.TransferSpreadsheet acLink, acSpreadsheetTypeExcel12Xml, "TempImport", XLName, True
' If the range is needed, linking doesn't work. Use import instead.
DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel12Xml, "TempImport", XLName, True, Address

SQLString = "INSERT INTO SatSurvey ... SELECT ... FROM TempImport"
CurrentDb.Execute SQLString

' Clean up temp table
DoCmd.DeleteObject acTable, "TempImport"

您不需要创建 New ADODB.Connection 来连接到您当前在 Access 会话中打开的数据库。您的 Con 对象变量可以简单地引用 CurrentProject.Connection ...

Set Con = CurrentProject.Connection

但是,您实际上什至不需要那个对象变量。直接从 CurrentProject.Connection ...

使用 Execute 方法
CurrentProject.Connection.Execute SQLString

这比您现在拥有的要简单,但我不确定它是否会消除 "state ... that prevents it from being opened or locked" 投诉。

既然你说了"alternate suggestions are welcome",请考虑使用 DAO 而不是 ADO。并且不要在 INSERT 查询的 SELECT 部分的字段表达式列表两边加上括号(无论您选择 ADO 还是 DAO)。

Private Sub TransferData(ByVal Company As String, ByVal Address As String, ByVal XLName As String)
    Dim SQLString As String

    SQLString = "INSERT INTO SatSurvey " & _
                "(ClinicID, Method) " & _
                "SELECT '<location>', IDFormat " & _
                " FROM [Excel 12.0;HDR=Yes;Database=" & XLName & "]." & Address
    Debug.Print SQLString
    CurrentDb.Execute SQLString, dbFailOnError
End Sub

您将在下面的链接中找到几种将数据从 Excel 移动到 SQL 服务器的方法。

http://www.excel-sql-server.com/excel-import-to-sql-server-using-distributed-queries.htm

http://www.excel-sql-server.com/excel-sql-server-import-export-using-vba.htm#Excel%20Data%20Export%20to%20SQL%20Server%20Test%20Code

显然,您 运行 来自 Excel 的人。此外,考虑使用 SQL 服务器(与上述相反)遍历文件。

DECLARE @intFlag INT
SET @intFlag = 1
WHILE (@intFlag <=10000)
BEGIN

PRINT @intFlag


declare @fullpath1 varchar(1000)
select @fullpath1 = '''\FTP\your_path' + convert(varchar, getdate()- @intFlag , 112) + '_your_file.txt'''
declare @cmd1 nvarchar(1000)
select @cmd1 = 'bulk insert [dbo].[your_table] from ' + @fullpath1 + ' with (FIELDTERMINATOR = ''\t'', FIRSTROW = 2, ROWTERMINATOR=''0x0a'')'
exec (@cmd1)


SET @intFlag = @intFlag + 1

END
GO

此脚本假定您的文件在文件名中包含日期。希望您的 Excel 文件在文件名中有某种模式,您可以利用它。