MS Access Forum / General 2 / May 2004
Link table in code doesn't "take"
|
|
Thread rating:  |
Ron Hinds - 04 May 2004 22:31 GMT Access 97, using ODBC linked tables. I try to change the link using this code snippet:
strConnect = "ODBC;Description=" & strDesc & ";DRIVER=SQL Server;SERVER=" & gstrSQLServer & ";UID=sa;PWD=" & strPWD & ";APP=Microsoft Open Database Connectivity;WSID=" & strWS & ";DATABASE=Prototype"
For Each tdf In db.TableDefs If tdf.Attributes And dbAttachedODBC Then tdf.Connect = strConnect tdf.RefreshLink db.TableDefs.Refresh End If Next
It doesn't happen for every table, but for some reason, for some of the tables, the new Connect string doesn't "take"; I check it and it's still the same as it was before. What causes this and what can I do about it?
Douglas J. Steele - 04 May 2004 23:21 GMT As far as I'm aware, you have to drop the table and recreate it with the new connection string. The Connect property is read-only once the TableDef object has been appended to the TableDefs collection.
 Signature Doug Steele, Microsoft Access MVP http://I.Am/DougSteele (No private e-mails, please)
> Access 97, using ODBC linked tables. I try to change the link using this > code snippet: [quoted text clipped - 14 lines] > tables, the new Connect string doesn't "take"; I check it and it's still the > same as it was before. What causes this and what can I do about it? Ron Hinds - 04 May 2004 23:36 GMT From Access Help: ============== Connect Property ------------------------- Sets or returns a value that provides information about the source of an open connection, an open database, a database used in a pass-through query, or a linked table. For Database objects, new Connection objects, linked tables, and TableDef objects not yet appended to a collection, this property setting is read/write. For QueryDef objects and base tables, this property is read-only. ============== Read/Write for linked tables. This fits as I have been using the same method with linked Access tables with no problem for quite some time.
> As far as I'm aware, you have to drop the table and recreate it with the new > connection string. The Connect property is read-only once the TableDef [quoted text clipped - 20 lines] > the > > same as it was before. What causes this and what can I do about it? Douglas J. Steele - 04 May 2004 23:48 GMT Well, my experience is that you need to delete the TableDef object and recreate it. That's the approach I've always used.
 Signature Doug Steele, Microsoft Access MVP http://I.Am/DougSteele (No private e-mails, please)
> From Access Help: > ============== [quoted text clipped - 36 lines] > > the > > > same as it was before. What causes this and what can I do about it? Ron Hinds - 05 May 2004 00:17 GMT Can you give me some details on how you implement that? Do you have a local table of attached tables that has the necessary information in it? E.g. sometimes the SourceTableName doesn't match the Name, etc. Or do you just do it in code, saving the relevant information in local variables? Thanks!
> Well, my experience is that you need to delete the TableDef object and > recreate it. That's the approach I've always used. [quoted text clipped - 46 lines] > > > the > > > > same as it was before. What causes this and what can I do about it? Douglas J. Steele - 05 May 2004 13:33 GMT I show one approach at http://members.rogers.com/douglas.j.steele/DSNLessLinks.html
There are other (better) approaches. For instance, you could create a collection and add to it, rather than having to dynamically redimension the array.
-- Doug Steele, Microsoft Access MVP http://I.Am/DougSteele (No private e-mails, please)
> Can you give me some details on how you implement that? Do you have a local > table of attached tables that has the necessary information in it? E.g. [quoted text clipped - 63 lines] > > > > the > > > > > same as it was before. What causes this and what can I do about it? Van T. Dinh - 05 May 2004 15:31 GMT Hi Doug
I think the Help topic is wrong. I have been using RefreshLink Method (in A2K2) to change the Connection String / Connect Property on ODBC-linked Tables without any problem.
 Signature HTH Van T. Dinh MVP (Access)
> As far as I'm aware, you have to drop the table and recreate it with the new > connection string. The Connect property is read-only once the TableDef > object has been appended to the TableDefs collection. Terry Kreft - 06 May 2004 11:57 GMT I'm sorry Doug that is not the case.
-- Terry Kreft MVP Microsoft Access
> As far as I'm aware, you have to drop the table and recreate it with the new > connection string. The Connect property is read-only once the TableDef [quoted text clipped - 25 lines] > the > > same as it was before. What causes this and what can I do about it? Pieter Wijnen - 05 May 2004 05:05 GMT You are simply providing it with to much info (& some wrong) cnstr = "driver={SQL Server};server=myserver;" & _ "database=mydb;Username=<username>;PWD=<strong password>"
ref http://support.microsoft.com/default.aspx?scid=http://support.microsoft.com:80/s upport/kb/articles/Q147/8/75.asp&NoWebContent=1
should suffice
Pieter
> Access 97, using ODBC linked tables. I try to change the link using this > code snippet: [quoted text clipped - 14 lines] > tables, the new Connect string doesn't "take"; I check it and it's still the > same as it was before. What causes this and what can I do about it? david epsom dot com dot au - 05 May 2004 08:40 GMT Interesting, but you should not believe all you read at microsoft.com!
DAO, unlike RDO, can connect to several different kinds of things, not just to ODBC. DAO assumes that the first field is a type field: the default blank value is for Jet databases. That is, if your string does not start ";Database=" or "ODBC" or "TEXT" or whatever, you will get an error message something like: "driver=mydb" is not a recognised ISAM
(david)
> You are simply providing it with to much info (& some wrong) > cnstr = "driver={SQL Server};server=myserver;" & _ > "database=mydb;Username=<username>;PWD=<strong password>" > > ref http://support.microsoft.com/default.aspx?scid=http://support.microsoft.com:80/s upport/kb/articles/Q147/8/75.asp&NoWebContent=1
> should suffice > [quoted text clipped - 20 lines] > the > > same as it was before. What causes this and what can I do about it? Ron Hinds - 05 May 2004 22:38 GMT Well I got that connection string by first linking the tables in Access manually. Then, in the Debug window I typed:
?CurrentDb.TableDefs("error_log").Connect
I used the Connect string returned as a template. I will try your suggestion though which seems to dovetail nicely with Doug's (see earlier post). Is this a so-called "DSN-less" connection string?
> You are simply providing it with to much info (& some wrong) > cnstr = "driver={SQL Server};server=myserver;" & _ > "database=mydb;Username=<username>;PWD=<strong password>" > > ref http://support.microsoft.com/default.aspx?scid=http://support.microsoft.com:80/s upport/kb/articles/Q147/8/75.asp&NoWebContent=1
> should suffice > [quoted text clipped - 20 lines] > the > > same as it was before. What causes this and what can I do about it? ???? - 06 May 2004 05:46 GMT > Well I got that connection string by first linking the tables in Access > manually. Then, in the Debug window I typed: [quoted text clipped - 10 lines] > > > > ref http://support.microsoft.com/default.aspx?scid=http://support.microsoft.com: 80/support/kb/articles/Q147/8/75.asp&NoWebContent=1
> > should suffice > > [quoted text clipped - 21 lines] > > the > > > same as it was before. What causes this and what can I do about it? david epsom dot com dot au - 05 May 2004 08:12 GMT 1) Can't refresh to change from ODBC to MDB 2) Stays the same if there is an error 3) Looses the connect string if the TDF goes out of scope before the Refresh.
What does your exception handling look like?
(david)
> Access 97, using ODBC linked tables. I try to change the link using this > code snippet: [quoted text clipped - 14 lines] > tables, the new Connect string doesn't "take"; I check it and it's still the > same as it was before. What causes this and what can I do about it? Ron Hinds - 05 May 2004 22:47 GMT > 1) Can't refresh to change from ODBC to MDB They are already ODBC-linked tables - I just want to point them to a different server.
> 2) Stays the same if there is an error That would appear to be the problem. Unfortunately, no error is returned (see response below).
> 3) Looses the connect string if the TDF goes out of scope before the > Refresh. Well I've tried to keep that code in the loop.
> What does your exception handling look like? I'm checking the return codes for API calls and calling an API error function for those. Otherwise I am using the standard VBA error handling/reporting. Here is the entire function:
Public Function RefreshLinksODBC(DSNFile As String) As Boolean
On Error GoTo Error_RefreshLinksODBC
RefreshLinksODBC = False
Dim db As Database Dim strError As String Dim lRet As Long, lSize As Long, lErrCode As Long Dim I As Integer, iSize As Integer Dim strDesc As String Dim strWS As String Dim strPWD As String Dim strConnect As String Dim tdf As TableDef
Set db = DBEngine(0)(0)
'Initialize string variables to fixed length for API calls gstrSQLServer = String(32, vbNullChar) strDesc = String(32, vbNullChar) strWS = String(32, vbNullChar)
lRet = SQLReadFileDSN(DSNFile, "ODBC", "SERVER", gstrSQLServer, 32, lSize) If lRet Then If lSize = 0 Then 'Need to prompt for server name DoCmd.openform "frmSQLServer" If Len(gstrSQLServer) < 1 Then msgbox "Must select a Database server!", vbCritical, "Hey hammerhead!" GoTo Exit_RefreshLinksODBC End If Else gstrSQLServer = Left(gstrSQLServer, lSize) End If Else GoTo ODBC_Error End If
'Save new server name in DSN file lRet = SQLWriteFileDSN(DSNFile, "ODBC", "SERVER", gstrSQLServer) If lRet = 0 Then GoTo ODBC_Error
lRet = SQLReadFileDSN(DSNFile, "ODBC", "Description", strDesc, 32, lSize) If lRet Then strDesc = Left(strDesc, lSize) Else GoTo ODBC_Error End If
If InStr(1, strDesc, "Backup") > 0 Then strPWD = "yyyyyyyy" Else strPWD = "xxxxxx" End If
lSize = Len(strWS)
If GetComputerName(strWS, lSize) Then strWS = Left(strWS, lSize) Else err.Raise GetLastError() End If
strConnect = "ODBC;Description=" & strDesc & ";DRIVER=SQL Server;SERVER=" & gstrSQLServer & ";UID=sa;PWD=" & strPWD & ";APP=Microsoft Open Database Connectivity;WSID=" & strWS & ";DATABASE=Prototype"
For Each tdf In db.TableDefs If tdf.Attributes And dbAttachedODBC Then tdf.Connect = strConnect tdf.RefreshLink db.TableDefs.Refresh End If Next
'Set global connect string for PassThrough queries gstrODBC = strConnect
RefreshLinksODBC = True
GoTo Exit_RefreshLinksODBC
ODBC_Error: 'ODBC error - enumerate For I = 1 To 8 strError = String(255, vbNullChar) lRet = SQLInstallerError(I, lErrCode, strError, 255, iSize) strError = Left(strError, CLng(iSize)) If lErrCode > 0 Then LogError "RefreshLinksODBC", lErrCode, strError End If Next
Exit_RefreshLinksODBC:
Exit Function
Error_RefreshLinksODBC: Dim errX As error
For Each errX In Errors LogError "RefreshLinksODBC", errX.Number, errX.Description Next
Resume Exit_RefreshLinksODBC
End Function
> (david) > [quoted text clipped - 18 lines] > the > > same as it was before. What causes this and what can I do about it? david epsom dot com dot au - 06 May 2004 01:44 GMT I don't trust this:
>If tdf.Attributes And dbAttachedODBC Then because (a) it's not how I do it, and (b) the attributes are not independent binary flags. I check the connect string to see if it starts with "ODBC"
Also, I see in my code that I only refresh the tabledefs collection BEFORE and AFTER the tdf loop, not during.
You might want to check inside the IF in the loop to see if you are actually hitting all the ODBC tables.
There are also, I think, some situations in which the refresh really does not work correctly or in the expected way. I do in fact mostly use create/delete, although I have refresh as an option in my interface. I have always been suspicious about refreshing ODBC links to point to a new server, because (a) I don't do it that way, and (b) ODBC connections are cached by the Jet engine.
But plenty of VB people do refresh from one ODBC connection to another. Problem reports mostly have to do with IISAMs, DSN's or Server Alias's, not (before now) with straight forward DSN'less ODBC connection strings.
(david)
> > 1) Can't refresh to change from ODBC to MDB > [quoted text clipped - 152 lines] > > the > > > same as it was before. What causes this and what can I do about it? Gary Walter - 06 May 2004 13:25 GMT I concede all of you know more than I do... but I was wondering if it was possible that including the Refresh within the loop might not be "reordering" the TableDefs.....
it would be interesting to see what you get if you debug printed the table name in the loop, with and without the Refresh.
> Also, I see in my code that I only refresh the tabledefs collection BEFORE > and AFTER the tdf loop, not during. > > > For Each tdf In db.TableDefs Debug.Print "All tables: " & tdf.Name
> > If tdf.Attributes And dbAttachedODBC Then Debug.Print " Change Me table: " & tdf.Name
> > tdf.Connect = strConnect > > tdf.RefreshLink > > 'db.TableDefs.Refresh > > End If > > Next Joe Fallon - 06 May 2004 03:11 GMT I use this procedure to re-create links to SQL Server. ==================================================== For Jet re-linking code see: http://www.mvps.org/access/tables/tbl0009.htm ==================================================== (This eliminates the need to re-name all the tables to strip out dbo_ and it allows you to point to different versions of the same database easily.) There is a local Access table (tblODBCTables) that contains the table names I want to link to on the Server. Note: the source table name needs the dbo. prefix which is in the code. The linked table name usualy omits this. .
Public Sub LinkSQLServerTables(strDSN As String, strDatabase) On Error GoTo Err_LinkSQLServerTables
Dim dbs As Database, rs As Recordset, tdfAccess As TableDef Dim dbsODBC As Database, strConnect As String
If strDSN = "" Then MsgBox "You must supply a DSN in order to link tables." Exit Sub Else strConnect = "ODBC;DSN=" & strDSN & ";UID=User;PWD=password;DATABASE=" & strDatabase & ";" End If
SysCmd acSysCmdSetStatus, "Connecting to SQL Server..."
Call DeleteODBCTableNames
Set dbs = CurrentDb Set rs = dbs.OpenRecordset("tblODBCTables") Set dbsODBC = OpenDatabase("", False, False, strConnect)
Do While Not rs.EOF Set tdfAccess = dbs.CreateTableDef(rs![LinkTablename], dbAttachSavePWD) tdfAccess.Connect = dbsODBC.Connect tdfAccess.SourceTableName = dbsODBC.TableDefs("dbo." & rs![LinkTablename]).Name dbs.TableDefs.Append tdfAccess rs.MoveNext Loop
rs.Close Set rs = Nothing Set dbsODBC = Nothing Set dbs = Nothing
Exit_LinkSQLServerTables: SysCmd acSysCmdClearStatus Exit Sub
Err_LinkSQLServerTables: MsgBox ("Error # " & Str(Err.Number) & " was generated by " & Err.Source & Chr(13) & Err.Description) Resume Exit_LinkSQLServerTables
End Sub
'This procedure deletes all linked ODBC table names in an mdb. Public Sub DeleteODBCTableNames() On Error GoTo Err_DeleteODBCTableNames
Dim dbs As Database, tdf As TableDef, I As Integer Set dbs = CurrentDb For I = dbs.TableDefs.Count - 1 To 0 Step -1 Set tdf = dbs.TableDefs(I) If (tdf.Attributes And dbAttachedODBC) Then dbs.TableDefs.Delete (tdf.Name) End If Next I
dbs.Close Set dbs = Nothing
Exit_DeleteODBCTableNames: Exit Sub
Err_DeleteODBCTableNames: MsgBox ("Error # " & Str(Err.Number) & " was generated by " & Err.Source & Chr(13) & Err.Description) Resume Exit_DeleteODBCTableNames
End Sub
 Signature Joe Fallon Access MVP
> Access 97, using ODBC linked tables. I try to change the link using this > code snippet: [quoted text clipped - 14 lines] > tables, the new Connect string doesn't "take"; I check it and it's still the > same as it was before. What causes this and what can I do about it? david epsom dot com dot au - 06 May 2004 06:03 GMT I do append, delete, rename:
2680 Set tbldef = dbRemote.CreateTableDef(sLinkName & "_", nTDFAttribute, sRemote, sConnect) 2700 dbRemote.TableDefs.Append tbldef 'using modified name 2710 dbRemote.TableDefs.Delete sLinkName 2720 tbldef.Name = sLinkName 'change name to correct name
(david)
> I use this procedure to re-create links to SQL Server. > ==================================================== [quoted text clipped - 101 lines] > the > > same as it was before. What causes this and what can I do about it? Terry Kreft - 06 May 2004 11:56 GMT Personally I would do it like this
strConnect = "ODBC;Description=" & strDesc & ";DRIVER=SQL Server;SERVER=" & gstrSQLServer & ";UID=sa;PWD=" & strPWD & ";APP=Microsoft Open Database Connectivity;WSID=" & strWS & ";DATABASE=Prototype"
For Each tdf In db.TableDefs with tdf if len(.Connect)> 0 then .Connect = strConnect .RefreshLink End If end with Next
I seem to remember (in the dim distant past) that testing the Attribute as you are doing can fail which is why I test whether the table has a connection string.
-- Terry Kreft MVP Microsoft Access
> Access 97, using ODBC linked tables. I try to change the link using this > code snippet: [quoted text clipped - 14 lines] > tables, the new Connect string doesn't "take"; I check it and it's still the > same as it was before. What causes this and what can I do about it? Ron Hinds - 06 May 2004 17:25 GMT Excellent stuff everyone - thanks so much! I will do some experimentation and see what works best for me.
> Personally I would do it like this > [quoted text clipped - 39 lines] > the > > same as it was before. What causes this and what can I do about it?
|
|
|