使用 VBA 在 Access 数据库中处理外部 Access 数据库?

Posted

技术标签:

【中文标题】使用 VBA 在 Access 数据库中处理外部 Access 数据库?【英文标题】:Handling an external Access database within an Access Database with VBA? 【发布时间】:2018-12-06 23:08:30 【问题描述】:

所以我对如何在 VBA 代码中处理外部数据库和当前数据库感到有些困惑。下面是一个子程序,其目的是使用在外部 Access 数据库中找到的唯一条目来更新当前的 Access 数据库。

传入外部SourceDBPathSelectedTable,我用字符串变量SourceDBTable指定外部数据库和表。然后,在 SQL 中,我尝试提取与其对应字段不匹配的值的条目,因此只有两个数据库之间的唯一条目被插入到源数据库中。

(例如,source = external:NOT EXIST sourceDB.SelectedTable.Field1 = currentDB.SelectedTable.Field1 And sourceDB.SelectedTable.Field2 = currentDB.SelectedTable.Field2 And sourceDB.SelectedTable.Field3 = currentDB.SelectedTable.Field3, 等)

所以,我的问题是:

1) 我是否需要在 SQL 中指定当前数据库(如 currentDB.table.field),或者如果在没有前缀的情况下调用表或字段(仅表或字段,如在下面的代码中)? 2)最终,我是否以正确的方式解决这个问题?

我的代码:

Private Sub UpdateDatabaseTable(SourceDBPath As String, SelectedTable As String)
    Dim SourceDBTable As String  

    On Error GoTo DBError  

    SourceDBTable = "[;DATABASE=" & SourceDBPath & "]." & SelectedTable

    Call DoCmd.RunSQL("INSERT INTO " & SelectedTable & " " & _
                        "SELECT Field1, Field2, Field3 " & _
                        "FROM " & SourceDBTable & " " & _
                        "WHERE NOT EXISTS( SELECT * " & _
                                            "FROM " & SourceDBTable & " " & _
                                            "WHERE (Field1=" & SourceDBTable & ".Field1 And Field2=" & SourceDBTable & ".Field2 And Field3=" & SourceDBTable & ".Field3"));")

    GoTo EndSub

DBError:
    MsgBox "Database Error!" & vbCrLf & "Error #" & Str(Err.Number) & ":  " & Err.Source & vbCrLf & Err.Description, vbExclamation, "Database Error"

EndSub:

End Sub

注意:我通过推断和修改解决方案 HERE 中的代码得出了我的 SQL

【问题讨论】:

不需要指定 CurrentDb。为什么不直接链接到其他数据库表? @June7 通常我会从那里开始,但我对这个项目的要求是避免链接表。重复条目由特定字段定义,因为其他条目更流畅。因此,在我们的例子中,在更新期间传统上看起来唯一的条目实际上是重复的。 嵌套 SELECT 中缺少 FROM 子句。 @June7 啊,确实。很好的收获。 【参考方案1】:

您的代码中有 2 个主要错误,否则,它应该可以工作。

    不要为每个字段指定表名。改用别名 您想同时转义表名和数据库名,而不仅仅是数据库名
    Private Sub UpdateDatabaseTable(SourceDBPath As String, SelectedTable As String)
        Dim SourceDBTable As String  

        On Error GoTo DBError  

        SourceDBTable = "[;DATABASE=" & SourceDBPath & "].[" & SelectedTable & "]"

        DoCmd.RunSQL "INSERT INTO " & SelectedTable & " t " & _
                            "SELECT Field1, Field2, Field3 " & _
                            "FROM " & SourceDBTable & " s" & _
                            "WHERE NOT EXISTS( SELECT * " & _
                                                "FROM " & SourceDBTable & " s1 " & _
                                                "WHERE (t.Field1=s1.Field1 And t.Field2=s1.Field2 And t.Field3=s1.Field3));"

        GoTo EndSub

    DBError:
        MsgBox "Database Error!" & vbCrLf & "Error #" & Str(Err.Number) & ":  " & Err.Source & vbCrLf & Err.Description, vbExclamation, "Database Error"

    EndSub:

    End Sub

我还删除了已弃用的 Call 关键字。或者,您可以使用CurrentDb.Execute 进一步调整此设置,但这不是必需的

【讨论】:

我明白了。别名是一个巧妙的解决方案。所以,为了清楚起见,我不需要指定一个 ThisDatabase (或类似的东西)来表示 "INSERT INTO " & SelectedTable & " t " 正在引用我们正在使用的数据库? SelectedTable 只是一个表名,例如 cars 是的,`t` 将名称 t 分配给 SelectedTable。在其余的查询中,您可以将其称为tss1 相同。您只需要指定一次全名。顺便说一句,您也可以使用 `As t` 而不仅仅是 t,但这不是必需的。 唯一的问题是 Access 不喜欢当前 DB 表的别名 t(SQL 代码的第 1 行)。我在其他帖子中读到,或多或少地只引用一张表格(根据我的经验水平仍然不清楚,因为我缺乏一点上下文)。没有大碍。我刚刚删除了别名t 并直接在WHERE 测试中引用了该表。除此之外,这是我需要回答的问题。谢谢。现在我遇到了一个逻辑问题,但这是另一个帖子的另一个问题。【参考方案2】:

以下代码从我的数据库发送数据到其他数据库:

strExtract = gstrBasePath & "Program\Editing\ConstructionExtract.accdb"

CurrentDb.Execute "INSERT INTO Bituminous IN '" & strExtract & "' SELECT * FROM ConstructionBIT;"

gstrBasePath 是通用模块中声明的全局常量:

Global Const gstrBasePath = "\\servernamehere\Crm\Lab\Database\"

您可以在过程中使用文字字符串路径。

从 OTHER db 获取 PULLS 数据:

CurrentDb.Execute "INSERT INTO Employees SELECT * FROM Employees IN '\\servername\filename.accdb'"

【讨论】:

所以即使您从该路径工作,您也必须指定当前数据库的路径?似乎编码太难了。我想我期望类似于 excel 中的ThisWorksheet CurrentDb 用于执行命令,但 SQL 语句本身没有引用当前数据库。我显示的路径是 OTHER db。现在我再看一遍,我发现我正在做与你想要的相反的事情。我正在向其他文件发送数据,而您正在拉动。请参阅我修改后的答案。 @LazyBear:你需要指定哪个数据库执行SQL语句。除了CurrentDb.Execute,您还可以使用Set db = OpenDatabase(strExtract): db.Execute "INSERT INTO [" & SelectedTable & "] IN '" & CurrentProject.Path & "\" & CurrentProject.Name & "' SELECT * FROM [" & SelectedTable & "]" 在外部数据库中执行SQL,但不建议这样做。如果表名和字段名来自 vars,并且您不能 100% 确定它们不包含不需要的字符(例如代码中的空白或 @junes 中的引号),请将它们括在方括号中。跨度>

以上是关于使用 VBA 在 Access 数据库中处理外部 Access 数据库?的主要内容,如果未能解决你的问题,请参考以下文章

通过 vba/sql 在 Access 中加入多个表

Access VBA添加引用正在重复

如何使用 Access VBA 更新所有 ODBC 链接的 SQL Server 表的服务器名称

使用Microsoft Access创建文档数据库

VBA 代码的结果在 Access 的文本框中不可见

Microsoft Access 不会处理 vba