我有一个Access 2010数据库,其中所有表都链接到SQL Server 2014表。我有一个Excel 2010(.xlsx)文件(尽管它以.csv开头,我可以这样离开),我需要通过VBA代码导入到SQL Server表中。我知道有可用的导入工具,但是,我每月要导入20多个XLS文件,并且宁愿采用自动方法来执行此操作。
我的所有VBA代码都驻留在Access数据库中,我能够找到的所有VBA代码示例都是从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
正如您所看到的,我尝试了一些不同的选项来让事情顺利进行。这似乎是我现在得到的最好的除了:
运行时错误'-2147467259(80004005)':
数据库已由用户'Admin'置于机器'MINIT-EGHJSAU'上,以防止其被打开或锁定。
指示的机器名称是我的机器。由于代码是从我的机器上的Access中运行的,因此我打开数据库似乎是合乎逻辑的。
我并不喜欢这样做,所以欢迎任何修复或替代建议。
答案 0 :(得分:4)
您无需创建连接到当前在Access会话中打开的数据库的New ADODB.Connection
。您的Con
对象变量只能引用CurrentProject.Connection
...
Set Con = CurrentProject.Connection
但是,你甚至不需要那个对象变量。只需直接从Execute
...
CurrentProject.Connection
方法即可
CurrentProject.Connection.Execute SQLString
这比现在的简单,但我不确定它会消除“状态......这会阻止它被打开或锁定”投诉。
由于您说“欢迎使用备用建议”,请考虑使用DAO而不是ADO。并且不要在SELECT
查询的INSERT
部分中的字段表达式列表中包括括号(无论您选择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
答案 1 :(得分:3)
您可以在以下链接中找到几种将数据从Excel移动到SQL Server的方法。
http://www.excel-sql-server.com/excel-import-to-sql-server-using-distributed-queries.htm
显然,你从Excel运行那些。另外,考虑使用SQL Server循环遍历文件(与上面描述的相反)。
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文件在文件名中有某种模式,您可以利用它。
答案 2 :(得分:1)
我发现通过实际链接或从Excel导入表格更容易(和调试!)。然后你可以像任何其他表一样使用它。
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"