通过vba链接表格

通过vba链接表格,vba,ms-access,ms-access-2007,Vba,Ms Access,Ms Access 2007,我正在完成分配给我的美国同事的任务(我在英国)。但是,我的数据库应用程序使用链接表通过网络连接到microsoft access数据库文件,该网络在存储客户信息时已加密 在美国方面,没有具有类似技能的同事能够通过VBA对数据库位置进行任何更改。我看到了各种连接SQL数据库的方法,如下面的microsoft链接所示。但是,为了使某人更容易更改数据库的位置 是否可以输入以下代码,以便查看包含数据库后端位置的文本文件(例如C:\users\public\test1),然后将表链接到前端 我找到了下面的

我正在完成分配给我的美国同事的任务(我在英国)。但是,我的数据库应用程序使用链接表通过网络连接到microsoft access数据库文件,该网络在存储客户信息时已加密

在美国方面,没有具有类似技能的同事能够通过VBA对数据库位置进行任何更改。我看到了各种连接SQL数据库的方法,如下面的microsoft链接所示。但是,为了使某人更容易更改数据库的位置

是否可以输入以下代码,以便查看包含数据库后端位置的文本文件(例如C:\users\public\test1),然后将表链接到前端

我找到了下面的代码,但它错误地说“对象msysaccessstorage已经存在”。它在“CurrentDb.TableDefs.Append tdf”行中出错

选项显式
Dim数据库作为DAO.Database
将tdf调暗为DAO.TableDef
将mypass设置为字符串
将mypath设置为字符串
将myDb设置为字符串
将表名设置为字符串
函数connectme()
mypass=“test1”
mypath=“C:\Users\Test1\Desktop\”
myDb=“EM1.accdb”
'删除链接,这样就不会有任何重复
对于CurrentDb.TableDefs中的每个tdf
如果左(tdf.Name,4)“MSys”和左(tdf.Name,15)“tblReportsState”和_
(tdf.Attributes和dbAttachedTable)=dbAttachedTable然后
CurrentDb.TableDefs.Delete tdf.Name
如果结束
下一个tdf
设置tdf=无
'设置链接
Set dbs=OpenDatabase(mypath&myDb,False,False,“MS-Access;PWD=“&mypass”)
对于dbs.TableDefs中的每个tdf
如果左(tdf.Name,4)“msys”,则
TableName=tdf.Name
设置tdf=CurrentDb.CreateTableDef(TableName)
tdf.Connect=“;PWD=“&mypass&”数据库=“+mypath+myDb
tdf.SourceTableName=TableName
CurrentDb.TableDefs.Append tdf
如果结束
下一个
端函数

您可能会遇到此错误,因为Access的Tabledefs列表并不总是立即反映您所做的更改,即删除。您可以在任何
.Append
s和/或
.Delete
s之后使用
CurrentDB.TableDefs.refresh
刷新它,但这需要时间,而且考虑到每次刷新链接表都需要大量时间,您可能负担不起时间

更好的做法是检查
TableDefs
中已有的链接并刷新它们,而不是删除并重新创建它们,因为删除它们也会删除任何格式,例如刷新后保持不变的列宽和字段格式

如果有需要刷新其链接的表,请更改
.Connect
属性,然后使用
CurrentDB.TableDefs(TableName).RefreshLink

仅当源表不再存在时,才应使用
CurrentDb.TableDefs.Delete tdf.Name

我自己也使用了类似的方法,但是我也存储上次链接表刷新的日期和时间,并且只刷新那些在该时间之后修改了模式的表。有100个或更多的表链接,每个表有2秒以上的时间刷新链接,我需要尽可能地节省时间

编辑:

下面的代码是我用来执行将MS Access链接到SQL Server的类似任务的代码

免责声明:以下代码按原样提供,不适用于纯访问前端/后端情况。有必要对其进行修改以满足您的需要

Public Sub RefreshLinkedTables()
    Dim adoConn As ADODB.Connection
    Dim arSQLObjects As ADODB.Recordset
    Dim CreateLink As Boolean, UpdateLink As Boolean, Found As Boolean
    Dim dWS As DAO.Workspace
    Dim dDB As DAO.Database
    Dim drSQLSchemas As DAO.Recordset, drSysVars As DAO.Recordset, drMSO As DAO.Recordset
    Dim dTDef As DAO.TableDef
    Dim ObjectTime As Date
    Dim sTStart As Double, sTEnd As Double, TStart As Double, TEnd As Double
    Dim CtrA As Long, ErrNo As Long
    Dim DescStr As String, SQLStr As String, ConnStr As String
    Dim SQLObjects() As String

    sTStart = PerfTimer()
    Set dWS = DBEngine.Workspaces(0)
    Set dDB = dWS.Databases(0)
    Set drSysVars = dDB.OpenRecordset("tbl_SysVars", dbOpenDynaset)
    If drSysVars.RecordCount = 0 Then Exit Sub
    AppendTxtMain "Refreshing Links to """ & drSysVars![ServerName] & """: """ & drSysVars![Database] & """ at " & Format(Now, "hh:mm:ss AMPM"), True
    Set adoConn = SQLConnection()
    Set arSQLObjects = New ADODB.Recordset
    SQLStr = "SELECT sys.schemas.name AS [Schema], sys.objects.*, sys.schemas.name + '.' + sys.objects.name AS SOName " & _
             "FROM sys.objects INNER JOIN sys.schemas ON sys.objects.schema_id = sys.schemas.schema_id " & _
             "WHERE (sys.objects.type IN ('U', 'V')) AND (sys.objects.is_ms_shipped = 0) " & _
             "ORDER BY SOName"
    ObjectTime = Now()
    arSQLObjects.Open SQLStr, adoConn, adOpenStatic, adLockReadOnly, adCmdText
    Set drSQLSchemas = dWS.Databases(0).OpenRecordset("SELECT * FROM USys_tbl_SQLSchemas WHERE LinkObjects = True", dbOpenDynaset)
    Set drMSO = dWS.Databases(0).OpenRecordset("SELECT Name FROM MSysObjects WHERE Type In(1,4,6) ORDER BY Name", dbOpenSnapshot)
    ReDim SQLObjects(0 To arSQLObjects.RecordCount - 1)
    With arSQLObjects
        drMSO.MoveFirst
        If Not .EOF Then
            .MoveLast
            .MoveFirst
        End If
        prgProgress.Max = .RecordCount
        prgProgress = 0
        CtrA = 0
        ConnStr = "DRIVER={SQL Server Native Client 10.0};SERVER=" & drSysVars![ServerName] & ";DATABASE=" & drSysVars![Database]
        If Nz(drSysVars![UserName]) = "" Then
            ConnStr = ConnStr & ";Trusted_Connection=YES"
        Else
            ConnStr = ConnStr & ";Uid=" & drSysVars![UserName] & ";Pwd=" & drSysVars![Password] & ";"
        End If
        Do Until .EOF
            TStart = PerfTimer
            SQLObjects(CtrA) = arSQLObjects![Schema] & "_" & arSQLObjects![Name]
            AppendTxtMain ![SOName] & " (" & ![modify_date] & "): ", True
            drSQLSchemas.FindFirst "[SchemaID] = " & ![schema_id]
            If Not drSQLSchemas.NoMatch Then
                UpdateLink = False
                CreateLink = False
                drMSO.FindFirst "Name=""" & drSQLSchemas![SchemaName] & "_" & arSQLObjects![Name] & """"
                If drMSO.NoMatch Then
                    CreateLink = True
                    AppendTxtMain "Adding Link... "
                    Set dTDef = dDB.CreateTableDef(arSQLObjects![Schema] & "_" & arSQLObjects![Name], dbAttachSavePWD, ![SOName], "ODBC;" & ConnStr)
                    dDB.TableDefs.Append dTDef
                    dDB.TableDefs(dTDef.Name).Properties.Append dTDef.CreateProperty("Description", dbText, "«Autolink»")
                ElseIf ![modify_date] >= Nz(drSysVars![SchemaUpdated], #1/1/1900#) Or RegexMatches(dDB.TableDefs(arSQLObjects![Schema] & "_" & arSQLObjects![Name]).Connect, "SERVER=(.+?);")(0).SubMatches(0) <> drSysVars![ServerName] _
                       Or (dDB.TableDefs(arSQLObjects![Schema] & "_" & arSQLObjects![Name]).Attributes And dbAttachSavePWD) <> dbAttachSavePWD Then
                    UpdateLink = True
                    AppendTxtMain "Refreshing Link... "
                    With dDB.TableDefs(arSQLObjects![Schema] & "_" & arSQLObjects![Name])
                        .Attributes = dbAttachSavePWD
                        .Connect = "ODBC;" & ConnStr
                        .RefreshLink
                    End With
                End If
            End If
            TEnd = PerfTimer()
            AppendTxtMain SplitTime(TEnd - TStart, 7, "s")
            .MoveNext
            prgProgress = prgProgress + 1
            CtrA = CtrA + 1
        Loop
    End With
    prgProgress = 0
    prgProgress.Max = dDB.TableDefs.Count
    DoEvents
    dDB.TableDefs.Refresh
    TStart = PerfTimer()
    AppendTxtMain "Deleting obsolete linked tables, started " & Now() & "...", True
    For Each dTDef In dDB.TableDefs
        If dTDef.Connect <> "" Then ' Is a linked table...
            On Error Resume Next
            DescStr = dTDef.Properties("Description")
            ErrNo = Err.Number
            On Error GoTo 0
            Select Case ErrNo
                Case 3270   ' Property does not exist
                    ' Do nothing.
                Case 0      ' Has a Description.
                    If RegEx(DescStr, "«Autolink»") Then    ' Description includes "«Autolink»"
                        Found = False
                        For CtrA = 0 To UBound(SQLObjects)
                            If SQLObjects(CtrA) = dTDef.Name Then
                                Found = True
                                Exit For
                            End If
                        Next
                        If Not Found Then   ' Delete if not in arSQLObjects
                            AppendTxtMain "Deleting """ & dTDef.Name & """", True
                            dDB.TableDefs.Delete dTDef.Name
                        End If
                    End If
            End Select
        End If
        prgProgress = prgProgress + 1
    Next
    TEnd = PerfTimer()
    AppendTxtMain "Completed at " & Now() & " in " & SplitTime(TEnd - TStart, 7, "s"), True
    drSysVars.Edit
    drSysVars![SchemaUpdated] = ObjectTime
    drSysVars.Update
    drSQLSchemas.Close
    dDB.TableDefs.Refresh
    Application.RefreshDatabaseWindow
    Set drSQLSchemas = Nothing
    arSQLObjects.Close
    Set arSQLObjects = Nothing
    adoConn.Close
    Set adoConn = Nothing
    drSysVars.Close
    Set drSysVars = Nothing
    drMSO.Close
    Set drMSO = Nothing
    dDB.Close
    Set dDB = Nothing
    dWS.Close
    Set dWS = Nothing
    prgProgress = 0
End Sub
公共子刷新链接表()
作为ADODB.连接的Dim adoConn
将对象设置为ADODB.Recordset
Dim CreateLink为布尔值,UpdateLink为布尔值,找到时为布尔值
Dim dWS作为DAO.Workspace
Dim dDB作为DAO.Database
将drSQLSchemas作为DAO.Recordset进行Dim,将drSysVars作为DAO.Recordset进行Dim,将drMSO作为DAO.Recordset进行Dim
将dTDef调暗为DAO.TableDef
以日期表示的时间
开始时双倍,听写时双倍,开始时双倍,趋向时双倍
调暗CtrA为长,ErrNo为长
Dim DescStr作为字符串,SQLStr作为字符串,ConnStr作为字符串
Dim SQLObjects()作为字符串
sTStart=PerfTimer()
设置dWS=DBEngine.Workspaces(0)
设置dDB=dWS.Databases(0)
Set drSysVars=dDB.OpenRecordset(“tbl_SysVars”,dbOpenDynaset)
如果drSysVars.RecordCount=0,则退出Sub
AppendTxtMain“刷新到“”的链接”&drSysVars![ServerName]&“:”&drSysVars![数据库]&“at”和格式(现在是“hh:mm:ss-AMPM”),正确
设置adoConn=SQLConnection()
Set arSQLObjects=New ADODB.Recordset
SQLStr=“选择sys.schemas.name作为[Schema],选择sys.objects.*,选择sys.schemas.name+”。+sys.objects.name作为SOName”&_
“从sys.objects内部连接sys.objects.schema_id=sys.schemas.schema_id上的sys.schemas”&_
其中(sys.objects.type IN('U','V'))和(sys.objects.is_ms_shipped=0)&_
“索纳姆命令”
ObjectTime=Now()
打开SQLStr、adoConn、adOpenStatic、adLockReadOnly、adCmdText
Set drSQLSchemas=dWS.Databases(0).OpenRecordset(“从USys_tbl_SQLSchemas中选择*其中LinkObjects=True”,dbOpenDynaset)
Set drMSO=dWS.Databases(0).OpenRecordset(“从MSysObjects中选择名称,其中按名称顺序键入(1,4,6)”,dbOpenSnapshot)
ReDim SQLObjects(0到arSQLObjects.RecordCount-1)
使用arSQLObjects
drMSO.MoveFirst
如果不是,那么EOF
.最后一个
.先走一步
如果结束
prgProgress.Max=.RecordCount
prgProgress=0
CtrA=0
ConnStr=“DRIVER={SQL Server本机客户端10.0};Server=“&drSysVars![ServerName]&“DATABASE=“&drSysVars!”![数据库]
如果Nz(drSysVars![UserName])=“”那么
ConnStr=ConnStr&“受信任的连接=是”
其他的
ConnStr=ConnStr&“Uid=”&drSysVars![用户名]&“Pwd=”&drSysVars![密码]&“
如果结束
直到。EOF
TStart=PerfTimer
SQLObjects(CtrA)
Public Sub RefreshLinkedTables()
    Dim adoConn As ADODB.Connection
    Dim arSQLObjects As ADODB.Recordset
    Dim CreateLink As Boolean, UpdateLink As Boolean, Found As Boolean
    Dim dWS As DAO.Workspace
    Dim dDB As DAO.Database
    Dim drSQLSchemas As DAO.Recordset, drSysVars As DAO.Recordset, drMSO As DAO.Recordset
    Dim dTDef As DAO.TableDef
    Dim ObjectTime As Date
    Dim sTStart As Double, sTEnd As Double, TStart As Double, TEnd As Double
    Dim CtrA As Long, ErrNo As Long
    Dim DescStr As String, SQLStr As String, ConnStr As String
    Dim SQLObjects() As String

    sTStart = PerfTimer()
    Set dWS = DBEngine.Workspaces(0)
    Set dDB = dWS.Databases(0)
    Set drSysVars = dDB.OpenRecordset("tbl_SysVars", dbOpenDynaset)
    If drSysVars.RecordCount = 0 Then Exit Sub
    AppendTxtMain "Refreshing Links to """ & drSysVars![ServerName] & """: """ & drSysVars![Database] & """ at " & Format(Now, "hh:mm:ss AMPM"), True
    Set adoConn = SQLConnection()
    Set arSQLObjects = New ADODB.Recordset
    SQLStr = "SELECT sys.schemas.name AS [Schema], sys.objects.*, sys.schemas.name + '.' + sys.objects.name AS SOName " & _
             "FROM sys.objects INNER JOIN sys.schemas ON sys.objects.schema_id = sys.schemas.schema_id " & _
             "WHERE (sys.objects.type IN ('U', 'V')) AND (sys.objects.is_ms_shipped = 0) " & _
             "ORDER BY SOName"
    ObjectTime = Now()
    arSQLObjects.Open SQLStr, adoConn, adOpenStatic, adLockReadOnly, adCmdText
    Set drSQLSchemas = dWS.Databases(0).OpenRecordset("SELECT * FROM USys_tbl_SQLSchemas WHERE LinkObjects = True", dbOpenDynaset)
    Set drMSO = dWS.Databases(0).OpenRecordset("SELECT Name FROM MSysObjects WHERE Type In(1,4,6) ORDER BY Name", dbOpenSnapshot)
    ReDim SQLObjects(0 To arSQLObjects.RecordCount - 1)
    With arSQLObjects
        drMSO.MoveFirst
        If Not .EOF Then
            .MoveLast
            .MoveFirst
        End If
        prgProgress.Max = .RecordCount
        prgProgress = 0
        CtrA = 0
        ConnStr = "DRIVER={SQL Server Native Client 10.0};SERVER=" & drSysVars![ServerName] & ";DATABASE=" & drSysVars![Database]
        If Nz(drSysVars![UserName]) = "" Then
            ConnStr = ConnStr & ";Trusted_Connection=YES"
        Else
            ConnStr = ConnStr & ";Uid=" & drSysVars![UserName] & ";Pwd=" & drSysVars![Password] & ";"
        End If
        Do Until .EOF
            TStart = PerfTimer
            SQLObjects(CtrA) = arSQLObjects![Schema] & "_" & arSQLObjects![Name]
            AppendTxtMain ![SOName] & " (" & ![modify_date] & "): ", True
            drSQLSchemas.FindFirst "[SchemaID] = " & ![schema_id]
            If Not drSQLSchemas.NoMatch Then
                UpdateLink = False
                CreateLink = False
                drMSO.FindFirst "Name=""" & drSQLSchemas![SchemaName] & "_" & arSQLObjects![Name] & """"
                If drMSO.NoMatch Then
                    CreateLink = True
                    AppendTxtMain "Adding Link... "
                    Set dTDef = dDB.CreateTableDef(arSQLObjects![Schema] & "_" & arSQLObjects![Name], dbAttachSavePWD, ![SOName], "ODBC;" & ConnStr)
                    dDB.TableDefs.Append dTDef
                    dDB.TableDefs(dTDef.Name).Properties.Append dTDef.CreateProperty("Description", dbText, "«Autolink»")
                ElseIf ![modify_date] >= Nz(drSysVars![SchemaUpdated], #1/1/1900#) Or RegexMatches(dDB.TableDefs(arSQLObjects![Schema] & "_" & arSQLObjects![Name]).Connect, "SERVER=(.+?);")(0).SubMatches(0) <> drSysVars![ServerName] _
                       Or (dDB.TableDefs(arSQLObjects![Schema] & "_" & arSQLObjects![Name]).Attributes And dbAttachSavePWD) <> dbAttachSavePWD Then
                    UpdateLink = True
                    AppendTxtMain "Refreshing Link... "
                    With dDB.TableDefs(arSQLObjects![Schema] & "_" & arSQLObjects![Name])
                        .Attributes = dbAttachSavePWD
                        .Connect = "ODBC;" & ConnStr
                        .RefreshLink
                    End With
                End If
            End If
            TEnd = PerfTimer()
            AppendTxtMain SplitTime(TEnd - TStart, 7, "s")
            .MoveNext
            prgProgress = prgProgress + 1
            CtrA = CtrA + 1
        Loop
    End With
    prgProgress = 0
    prgProgress.Max = dDB.TableDefs.Count
    DoEvents
    dDB.TableDefs.Refresh
    TStart = PerfTimer()
    AppendTxtMain "Deleting obsolete linked tables, started " & Now() & "...", True
    For Each dTDef In dDB.TableDefs
        If dTDef.Connect <> "" Then ' Is a linked table...
            On Error Resume Next
            DescStr = dTDef.Properties("Description")
            ErrNo = Err.Number
            On Error GoTo 0
            Select Case ErrNo
                Case 3270   ' Property does not exist
                    ' Do nothing.
                Case 0      ' Has a Description.
                    If RegEx(DescStr, "«Autolink»") Then    ' Description includes "«Autolink»"
                        Found = False
                        For CtrA = 0 To UBound(SQLObjects)
                            If SQLObjects(CtrA) = dTDef.Name Then
                                Found = True
                                Exit For
                            End If
                        Next
                        If Not Found Then   ' Delete if not in arSQLObjects
                            AppendTxtMain "Deleting """ & dTDef.Name & """", True
                            dDB.TableDefs.Delete dTDef.Name
                        End If
                    End If
            End Select
        End If
        prgProgress = prgProgress + 1
    Next
    TEnd = PerfTimer()
    AppendTxtMain "Completed at " & Now() & " in " & SplitTime(TEnd - TStart, 7, "s"), True
    drSysVars.Edit
    drSysVars![SchemaUpdated] = ObjectTime
    drSysVars.Update
    drSQLSchemas.Close
    dDB.TableDefs.Refresh
    Application.RefreshDatabaseWindow
    Set drSQLSchemas = Nothing
    arSQLObjects.Close
    Set arSQLObjects = Nothing
    adoConn.Close
    Set adoConn = Nothing
    drSysVars.Close
    Set drSysVars = Nothing
    drMSO.Close
    Set drMSO = Nothing
    dDB.Close
    Set dDB = Nothing
    dWS.Close
    Set dWS = Nothing
    prgProgress = 0
End Sub