Ms access 需要使用用户名、密码和系统数据库更改MS Access数据库中的链接表

Ms access 需要使用用户名、密码和系统数据库更改MS Access数据库中的链接表,ms-access,vba,mdw,Ms Access,Vba,Mdw,我有一个前端数据库,它需要链接到不同的后端数据库。为了给您提供透视图,它与独立的MDB文件相关。该软件为每家公司建立了一个数据库 目前,我正在其中一个MDB文件中编写代码 为了可伸缩性,我现在创建了一个新的DB,它将通过代码链接到每个MDB,因此我的问题如下 如何通过code/VB更改链接表的位置,以便用户可以选择他们想要处理的公司/DB 我如何通过传递用户名和密码来做到这一点,这对所有公司/DBs都是一样的 根据以下内容,我们需要通过systemDB验证用户名和密码,以便成功打开 作为供参考,

我有一个前端数据库,它需要链接到不同的后端数据库。为了给您提供透视图,它与独立的MDB文件相关。该软件为每家公司建立了一个数据库

目前,我正在其中一个MDB文件中编写代码

为了可伸缩性,我现在创建了一个新的DB,它将通过代码链接到每个MDB,因此我的问题如下

  • 如何通过code/VB更改链接表的位置,以便用户可以选择他们想要处理的公司/DB

  • 我如何通过传递用户名和密码来做到这一点,这对所有公司/DBs都是一样的

  • 根据以下内容,我们需要通过systemDB验证用户名和密码,以便成功打开

  • 作为供参考,这是我们在独立基础上打开数据库的方式-
    “C:\Program Files(x86)\Microsoft Office\root\Office16\MSACCESS.EXE”“C:\temp\SAMPLE.mdb”/WRKGRP“C:\ProgramData\SOFTWARE\SYSTEM.mdw”/user:username/pwd:password

    这根本不是问题,只要说明您使用的是单个mdw文件,就完全可以完成

    阐明Microsoft Access工作组安全性本质上是一种“会话”安全模型,在打开前端MDB文件时直接应用于该文件

    您的示例命令行意味着Microsoft Access将使用您指定的工作组文件打开
    SAMPLE.MDB
    前端文件

    一旦Microsoft Access在该工作组文件下打开了
    SAMPLE.MDB
    ,您就不能在该“会话”中更改到另一个工作组文件,除非关闭Microsoft Access并在新工作组文件下重新打开

    仅供参考-可以通过代码打开另一个MDB中的表,该表使用该连接中的另一个工作组文件,但通过这种方式,该表只能作为记录集在代码中使用(例如,您不能将其设置为链接表)

    无论如何,回到你真正的问题上来。如何为每个公司链接一组不同的后端表

    我的建议是在您的
    公司
    表中添加几个字段,用于定义每个后端文件的文件名和位置。例如:

    请注意,该位置可以是UNC路径,也可以是映射的驱动器路径。或者,您不需要在表中显式定义位置。可能所有后端都在同一个文件夹中,或者位于可定义的动态位置,如
    \Dallas\Dallas.mdb
    \NewYork\NewYork.mdb
    ,等等。只要您能够以某种方式确定每个后端的位置,就可以了

    现在,由于您可能有“全局”前端表,也可能有一些“全局”链接后端表
    ,即Common.mdb
    ,以及您公司特定的后端表,因此我建议您有一个前端表,该表定义仅涉及公司特定文件的每个表的名称。这样,我们就可以轻松地循环使用这些表名并更改链接

    对于链接代码,假设您已提示用户他们想要哪个公司,并将
    CompanyID
    传递给重新链接功能:

    Public Function ChangeCompanyLinks(CompanyID As Long) As Boolean
        Dim db As DAO.Database
        Dim ldb As DAO.Database
        Dim tdf As DAO.TableDef
        Dim rstCompany As DAO.Recordset
        Dim rstTables As DAO.Recordset
        Dim mssql As String
        Dim dbFullPath As String
        Dim retVal As Boolean
    
        Set db = CurrentDb()
        retVal = False
        mssql = "SELECT * FROM [tblCompany] WHERE [CompanyID] = " & CompanyID
        Set rstCompany = db.OpenRecordset(mssql, dbOpenSnapshot)
        If Not rstCompany.BOF Then
            dbFullPath = rstCompany("DBLocation") & "\" & rstCompany("DBName")
            If Dir(dbFullPath) = rstCompany("DBName") Then
                'NOTE: By opening a temporary constant link to the back-end during
                '      relinking, the relinking runs faster
                Set ldb = OpenDatabase(dbFullPath)
                mssql = "SELECT * FROM [tblLinkedTables] WHERE [FileType] = ""Company"""
                Set rstTables = db.OpenRecordset(mssql, dbOpenSnapshot)
                Do While Not rstTables.EOF
                    Set tdf = db.TableDefs(rstTables("TableName"))
                    tdf.Connect = ";DATABASE=" & dbFullPath
                    tdf.RefreshLink
                    rstTables.MoveNext
                Loop
                rstTables.Close
                ldb.Close
                retVal = True
            Else
                MsgBox "Unable to Locate Company File"
            End If
        End If
        rstCompany.Close
    
        ChangeCompanyLinks = retVal
        Set rstCompany = Nothing
        Set rstTables = Nothing
        Set ldb = Nothing
        Set tdf = Nothing
        db.Close
        Set db = Nothing
    
    End Function
    
    显然,您需要添加错误处理,并对其进行一些自定义以适应您的情况,但这段代码会将指定的表重新链接到新的后端


    请注意,如果最终更改为在SQL Server中使用后端表(我强烈建议这样做),则需要对重新链接的代码进行一些修改。有关这方面的更多详细信息,请参阅。

    这根本不是问题,如果您使用的是单个MDW文件,则完全可以实现这一点

    阐明Microsoft Access工作组安全性本质上是一种“会话”安全模型,在打开前端MDB文件时直接应用于该文件

    您的示例命令行意味着Microsoft Access将使用您指定的工作组文件打开
    SAMPLE.MDB
    前端文件

    一旦Microsoft Access在该工作组文件下打开了
    SAMPLE.MDB
    ,您就不能在该“会话”中更改到另一个工作组文件,除非关闭Microsoft Access并在新工作组文件下重新打开

    仅供参考-可以通过代码打开另一个MDB中的表,该表使用该连接中的另一个工作组文件,但通过这种方式,该表只能作为记录集在代码中使用(例如,您不能将其设置为链接表)

    无论如何,回到你真正的问题上来。如何为每个公司链接一组不同的后端表

    我的建议是在您的
    公司
    表中添加几个字段,用于定义每个后端文件的文件名和位置。例如:

    请注意,该位置可以是UNC路径,也可以是映射的驱动器路径。或者,您不需要在表中显式定义位置。可能所有后端都在同一个文件夹中,或者位于可定义的动态位置,如
    \Dallas\Dallas.mdb
    \NewYork\NewYork.mdb
    ,等等。只要您能够以某种方式确定每个后端的位置,就可以了

    现在,由于您可能有“全局”前端表,也可能有一些“全局”链接后端表
    ,即Common.mdb
    ,以及您公司特定的后端表,因此我建议您有一个前端表,该表定义仅涉及公司特定文件的每个表的名称。这样,我们就可以轻松地循环使用这些表名并更改链接

    对于链接代码,假设您已提示用户他们想要哪个公司,并将
    CompanyID
    传递给重新链接功能:

    Public Function ChangeCompanyLinks(CompanyID As Long) As Boolean
        Dim db As DAO.Database
        Dim ldb As DAO.Database
        Dim tdf As DAO.TableDef
        Dim rstCompany As DAO.Recordset
        Dim rstTables As DAO.Recordset
        Dim mssql As String
        Dim dbFullPath As String
        Dim retVal As Boolean
    
        Set db = CurrentDb()
        retVal = False
        mssql = "SELECT * FROM [tblCompany] WHERE [CompanyID] = " & CompanyID
        Set rstCompany = db.OpenRecordset(mssql, dbOpenSnapshot)
        If Not rstCompany.BOF Then
            dbFullPath = rstCompany("DBLocation") & "\" & rstCompany("DBName")
            If Dir(dbFullPath) = rstCompany("DBName") Then
                'NOTE: By opening a temporary constant link to the back-end during
                '      relinking, the relinking runs faster
                Set ldb = OpenDatabase(dbFullPath)
                mssql = "SELECT * FROM [tblLinkedTables] WHERE [FileType] = ""Company"""
                Set rstTables = db.OpenRecordset(mssql, dbOpenSnapshot)
                Do While Not rstTables.EOF
                    Set tdf = db.TableDefs(rstTables("TableName"))
                    tdf.Connect = ";DATABASE=" & dbFullPath
                    tdf.RefreshLink
                    rstTables.MoveNext
                Loop
                rstTables.Close
                ldb.Close
                retVal = True
            Else
                MsgBox "Unable to Locate Company File"
            End If
        End If
        rstCompany.Close
    
        ChangeCompanyLinks = retVal
        Set rstCompany = Nothing
        Set rstTables = Nothing
        Set ldb = Nothing
        Set tdf = Nothing
        db.Close
        Set db = Nothing
    
    End Function
    
    显然,您需要添加错误处理,并对其进行一些定制以适应您的情况,但这段代码将重新编写