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