如何使用 WHERE 条件从 Excel 工作表中插入字段以访问数据库

Posted

技术标签:

【中文标题】如何使用 WHERE 条件从 Excel 工作表中插入字段以访问数据库【英文标题】:How to insert a field from Excel Sheet to Access Database with a WHERE condition 【发布时间】:2014-07-11 20:11:59 【问题描述】:

我一直在为这个问题苦恼一段时间,我想知道是否有解决方案!

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

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

我要做的就是使用 ADODB 和 SQL 将 Excel 工作表中的 [DepartmentQV] 值拉入到 [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

【问题讨论】:

在您的 B2:Cx 范围内,您是否省略了标题行?在这种情况下,记录集不会有您期望的名称。此外,您的 SQL 很奇怪:您是在尝试插入新行还是更新现有行? 标题行实际上在 B2:C2 中,我实际上是在尝试更新现有行。我一直在使用带有 adodb 和访问的更新时遇到问题,你不会碰巧知道我可以用更新来实现我想要做的事情吗?到目前为止仍然没有运气叹息 【参考方案1】:

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

"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

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

【讨论】:

非常感谢您提供这个彻底的替代方案!通过你的方法,我什至还学到了一些 adodb 的巧妙技巧! @bluecat:非常欢迎。希望它至少可以帮助您或让您走上更好的道路。

以上是关于如何使用 WHERE 条件从 Excel 工作表中插入字段以访问数据库的主要内容,如果未能解决你的问题,请参考以下文章

Excel - UDF 函数,用于根据条件从多个工作表中获取 SUM 值

Excel表中连接sql并使用sql语句引用excel单元格数据作为查询条件

如何使用 Where 子句从多个表中删除多行?

MySQL根据条件查询表名,并提取这些表的数据。

使用“where”条件从 Amazon DynamoDB 获取项目

从条件表中获取 WHERE 子句的条件