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
显然,您 运行 来自 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 文件在文件名中有某种模式,您可以利用它。
我有一个 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
显然,您 运行 来自 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 文件在文件名中有某种模式,您可以利用它。