如何使用WHERE条件将Excel工作表中的字段插入Access数据库

时间:2014-07-11 20:12:00

标签: sql vba excel-vba access-vba adodb

我一直在讨论这个问题,我想知道是否有解决方案!

所以我有一个名为R1的表,在Access中有两个列:[Department]和[DepartmentQV],[Department]列有一些带有值的字段,但[DepartmentQV]列是空白的

我还在Excel中有一个电子表格,它还有[Department]列和[DepartmentQV]列。 [Department]列与Access中的列相同,但[DepartmentQV]列具有值。

我想要做的就是使用ADODB和SQL将[DepartmentQV]值从Excel工作表拉入到[Department]值匹配的Access数据库中。

不幸的是,这根本不起作用,我一直得到同样的错误"没有给出一个或多个所需参数的值"我完全不解。任何帮助,将不胜感激!感谢您抽出宝贵时间阅读本文!

最佳, 库尔特

到目前为止,这是我的代码!

 lastRow = ActiveWorkbook.ActiveSheet.Range("B" & ActiveWorkbook.ActiveSheet.Rows.Count).End(xlUp).Row

  Set cn = CreateObject("ADODB.Connection")
  dbPath = glob_sdbPath
  dbWb = Application.ActiveWorkbook.FullName
  dbWs = ActiveWorkbook.ActiveSheet.Name
  scn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & dbPath
  dsh = "[" & Application.ActiveSheet.Name & "$B2:C" & lastRow & "]"
  cn.Open scn

  sSql = "INSERT INTO  R1([Department_QV])"
  sSql = sSql & " SELECT [Spoilage] FROM [Excel 12.0;HDR=YES;DATABASE=" & dbWb & "]." & dsh & "    WHERE " & dsh  & ".[Department] = R1.[Department]"

  cn.Execute sSql

1 个答案:

答案 0 :(得分:1)

此处的问题是使用ADO在Access和Excel之间进行更新。当我尝试针对Access表INNER JOIN派生的Excel表并执行更新时,我收到错误:

"Run-time error '-2147467259 (80004005)':
You cannot edit this field because it resides in a linked Excel spreadsheet. The ability to edit data in a linked Excel spreadsheet has been disabled in this Access Release."

没关系Access表没有链接到Excel,我找不到解决方案。我决定将Excel数据推送到Access中的临时表,并针对R1和临时表运行更新。另一种执行更新的方法是打开两个记录集,一个是Excel表,另一个是Access表,另一个是针对另一个进行搜索并更新,但我选择了它。

(我引用了Microsoft ActiveX Data Objects 2.8 Library和Microsoft ADOX Ext.2.8 for DDL And Security,所以我有智能感知。你可以根据需要实例化对象。):

Public Sub ExcelToAcessUpdate()
On Error GoTo ErrorHandler

    Dim cn As New ADODB.Connection
    Dim rstTables As New ADODB.Recordset
    Dim cat As New ADOX.Catalog

    Dim dbWb As String
    Dim dbWs As String
    Dim dsh As Variant
    Dim lastRow As Integer

    Dim dbPath As String
    Dim scn As String
    Dim sTempTable As String
    Dim sSql As String

    dbWb = Application.ActiveWorkbook.FullName
    dbWs = ActiveWorkbook.ActiveSheet.Name
    dsh = "[" & Application.ActiveSheet.Name & "$B2:C" & lastRow & "]"
    lastRow = ActiveWorkbook.ActiveSheet.Range("B" & ActiveWorkbook.ActiveSheet.Rows.Count).End(xlUp).Row

    dbPath = glob_sdbPath
    scn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & dbPath

    'This is the name of the temp table in Access
    'we will use to hold our Excel data.
    sTempTable = "tblMyExcelTemp"

    cn.Open scn

    'Make the ADO connection get a recordset of tables in database.
    Set rstTables = cn.OpenSchema(adSchemaTables)

    'If temp table we want to use already exists in db, delete it.
    With rstTables
        Do Until .EOF
            If .Fields("TABLE_TYPE") = "TABLE" And _
               .Fields("TABLE_NAME") = sTempTable Then
                    Set cat.ActiveConnection = cn
                    cat.Tables.Delete sTempTable

                    Exit Do
            End If

            .MoveNext
        Loop
    End With

    'Get all our Excel data and push it into temp table.
    sSql = "SELECT [Department], [Spoilage] INTO " & sTempTable & " " & _
           "FROM [Excel 12.0;HDR=YES;DATABASE=" & dbWb & "]." & dsh

    cn.Execute sSql

    'Update R1 using inner join against Excel Temp table.
    sSql = "UPDATE R1 INNER JOIN " & sTempTable & " e ON R1.[Department] = e.[Department] " & _
           " SET Department_QV = e.[Spoilage]"

    cn.Execute sSql

ExitMe:
    If cn Is Nothing = False Then
        If cn.State <> adStateClosed Then
            cn.Close
        End If
    End If

    Set cat = Nothing
    Set rstTables = Nothing
    Set cn = Nothing

    Exit Sub
ErrorHandler:
    'Lazy error handling, need to go through cn.Errors collection, actually.
    MsgBox Err.Number & ": " & Err.Description
    GoTo ExitMe

End Sub

我不是临时表解决方案的忠实粉丝,但是它有效,如果你需要做很多这样的事情,它可以成为你的范例。希望它对你有用。使用记录集的基于游标的解决方案效率太低,但我想也可以这样做。