从Access VBA中插入Access从Excel中选择

时间:2015-11-24 14:51:44

标签: sql-server vba ms-access ms-access-2010 excel-2010

我有一个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中运行的,因此我打开数据库似乎是合乎逻辑的。

我并不喜欢这样做,所以欢迎任何修复或替代建议。

3 个答案:

答案 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

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

显然,你从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"