【发布时间】:2016-06-15 14:06:34
【问题描述】:
我正在尝试重新链接 MS Access 数据库中的表,该数据库与下面运行的代码不同;这样我就可以将修复数据库用作各种“补丁”......
我已经修改了我找到的代码here,以便它重新链接由“修复/补丁数据库”打开的数据库中的表
在我运行代码之前,我确保两个数据库都是打开的,以便一个可以修复另一个,以便更轻松地自动应用修复程序。
但是,当我运行代码时,当我到达读取 tdfLinked.RefeshLink 的行时,它会刷新链接表,我收到 Runtime error '3219' Invalid Operation 错误。
Sub FixDB()
Call LinkTable("somelinkedTble", "SOMESERVER\NAMED_SQL_INST32", "Database1", "Some_Schema.somelinkedTble", True)
End Sub
Function LinkTable(LinkedTableAlias As String, Server As String, database As String, SourceTableName As String, OverwriteIfExists As Boolean)
'This method will also update the link if the underlying table definition has been modified.
'The overwrite parameter will cause it to re-map/refresh the link for LinktedTable Alias, but only if it was already a linked table.
' it will not overwrite an existing query or local table with the name specified in LinkedTableAlias.
' Begin: Bit that I modified to access the database that needs fixed.
Dim objAccess As Access.application
Dim loginInfo As New AuthInfoz
loginInfo.workgroup = "E:\Tickets\Fix\SEC\Secured.mdw"
loginInfo.username = "someuser"
loginInfo.password = "********"
loginInfo.dbs = "E:\Tickets\Fix\Report.mdb"
Set objAccess = GetObject(loginInfo.dbs).application
'Links to a SQL Server table without the need to set up a DSN in the ODBC Console.
Dim dbsCurrent As database
Dim tdfLinked As TableDef
' Open a database to which a linked table can be appended.
Set dbsCurrent = objAccess.CurrentDb
' END: Bit that I modified to access the external database.
'Check for and deal with the scenario ofthe table alias already existing
If TableNameInUse(LinkedTableAlias) Then
If (Not OverwriteIfExists) Then
Debug.Print "Can't use name '" + LinkedTableAlias + "' because it would overwrite existing table."
Exit Function
End If
'delete existing table, but only if it is a linked table
If IsLinkedTable(LinkedTableAlias) Then
dbsCurrent.TableDefs.Delete LinkedTableAlias
dbsCurrent.TableDefs.Refresh
Else
Debug.Print "Can't use name '" + LinkedTableAlias + "' because it would overwrite an existing query or local table."
Exit Function
End If
End If
'Create a linked table
Set tdfLinked = dbsCurrent.CreateTableDef(LinkedTableAlias)
tdfLinked.SourceTableName = SourceTableName
tdfLinked.Connect = "ODBC;DRIVER={SQL Server};SERVER=" & Server & ";DATABASE=" & database & ";TRUSTED_CONNECTION=yes;"
On Error Resume Next
dbsCurrent.TableDefs.Append tdfLinked
If (Err.Number = 3626) Then 'too many indexes on source table for Access
Err.Clear
On Error GoTo 0
If LinkTable(LinkedTableAlias, Server, database, "vw" & SourceTableName, OverwriteIfExists) Then
Debug.Print "Can't link directly to table '" + SourceTableName + "' because it contains too many indexes for Access to handle. Linked to view '" & "vw" & SourceTableName & "' instead."
LinkTable = True
Else
Debug.Print "Can't link table '" + SourceTableName + "' because it contains too many indexes for Access to handle. Create a view named '" & "vw" & SourceTableName & "' that selects all rows/columns from '" & SourceTableName & "' and try again to circumvent this."
LinkTable = False
End If
Exit Function
End If
On Error GoTo 0
tdfLinked.RefreshLink
LinkTable = True
End Function
Function BuildSQLConnectionString(Server As String, DBName As String) As String
BuildSQLConnectionString = "Driver={SQL Server};Server=" & Server & ";Database=" & DBName & ";TRUSTED_CONNECTION=yes;"
End Function
Function TableNameInUse(TableName As String) As Boolean
'check for local tables, linked tables and queries (they all share the same namespace)
TableNameInUse = DCount("*", "MSYSObjects", "(Type = 4 or type=1 or type=5) AND [Name]='" & TableName & "'") > 0
End Function
Function IsLinkedTable(TableName As String) As Boolean
IsLinkedTable = DCount("*", "MSYSObjects", "(Type = 4) AND [Name]='" & TableName & "'") > 0
End Function
【问题讨论】:
-
如果
tdfLinked是新创建的,你为什么还要创建tdfLinked.RefreshLink? -
哦,那是因为它已经存在了。我正在重新链接它。
-
您过于复杂了。没有理由删除链接表,只需设置新的/修改后的 Connect 并执行 RefreshLink。
-
也许我误读了您的代码,但在我看来,您正在删除链接,然后使用更新的连接信息重新创建它 (
CreateTableDef)。如果您只是按照 Gustav 的建议更改现有链接的.Connect属性,那么您将调用RefreshLink以向 Access 发出信号,它需要更新它存储的有关链接表的元数据。 -
试试这个。 CurrentDB.TableDefs(TableName).RefreshLink 代替。您还确定要添加带有追加的字段吗?
标签: sql-server ms-access vba linked-tables