[AccessD] Connect String for Linked Table

Jim Dettman jimdettman at verizon.net
Sat Nov 21 06:26:21 CST 2015


Charlotte,

 Yes, that's exactly the method you need to use.

 I would say the same for checking for the existence of a tabledef and not
rely on looking at msysobjects.  The reason I say that is because the tables
are un-documented, so you never know what changes Microsoft might make in
them.  

 Msysobjects is pretty safe and a lot of people have used it however.  I've
never heard of anyone having a problem, but you are using a backdoor method.
Personally I've always used a method/property through the object model
rather than anything direct.  In this case I do:

Function DoesTblExist(strTblName As String) As Boolean

    Dim db As DAO.Database, tbl As DAO.TableDef

    On Error Resume Next

    Set db = CurDb(True)
    Set tbl = db.TableDefs(strTblName)

    If Err.Number = 3265 Then
        DoesTblExist = False
    Else
        DoesTblExist = True
    End If

End Function


 As for checking the link, I do what gustav suggested and attempt to open a
recordset on the table:


Function IsJETTableAttached(strDatabaseName As String, strTableName As
String) As Integer

    Dim rstTest As DAO.Recordset
    Dim intRet As Integer

    On Error Resume Next
    Err = 0

    Set rstTest = CurDb.OpenRecordset("SELECT * FROM " & strTableName & "
WHERE 1 = 0")
    
    If Err = 0 Then
        intRet = True
    Else
        intRet = RefreshJETTables(strDatabaseName)
    End If

    rstTest.Close
    Set rstTest = Nothing

    IsJETTableAttached = intRet
    
    If IsJETTableAttached = False Then
        Call ApplicationExit
    End If

End Function

 The WHERE 1 = 0 is a cheap way to return no records.   I also allow the
user to browse to the location of the BE in RefreshJETTables(), which is why
the logic is the way it is.  The BE database name is explicitly passed in
intentionally rather than relying on what's in the TableDefs connect string.


 Couple other points:

1. I'd check what's being passed to the routine as a table name when called
from code.  Looks to me like a problem with the call rather than the
routine.

2. CurrentDB() vs dbEngine(0)(0): CurrentDB() is Access's reference to the
database, dbengine is JET's.   Access's is the one you want to use as it
will always be up to date.   If you want to know a little more about all
that and a method that gives you the best of both worlds, give this a read:

CurrentDB() vs. dbEngine.Workspaces(0).Databases(0) and an alternative
http://rdsrc.us/rO0m9j

3. Your existing routine could be simplified a bit:

Public Function DoesObjectExist(ByVal strObjName As String) As Boolean

    On Error Resume Next

    DoesObjectExist = DCount("*", "MSysObjects", "[Name] = '" & strObjName &
"'")>0

End Function

 Don't need the variable really and the count should use "*" instead of a
field name.  The asterisk has optimizations built-in to speed up the count.

 Both are very moot points given the task at hand, but it would be
fractionally faster.

HTH,
Jim.


-----Original Message-----
From: AccessD [mailto:accessd-bounces at databaseadvisors.com] On Behalf Of
Gustav Brock
Sent: Saturday, November 21, 2015 04:41 AM
To: Access Developers discussion and problem solving
Subject: Re: [AccessD] Connect String for Linked Table

Hi Charlotte

By second thought, I don't think you can check for a broken link other than
trying to open the table and catch an error.

A TableDef with a link doesn't go except if you delete it (why should you?).
Or it might never has been there - it's a new table required by a new
version of the application - and you would know that and have code that
creates this TableDef.

I just check one essential small table linked from the backend. If opening
it fails, I relink all tables of that backend.

/gustav

________________________________________
Fra: AccessD <accessd-bounces at databaseadvisors.com> på vegne af Charlotte
Foust <charlotte.foust at gmail.com>
Sendt: 21. november 2015 00:02
Til: Access Developers discussion and problem solving
Emne: Re: [AccessD] Connect String for Linked Table

Public Function DoesObjectExist(ByVal strObjName As String) As Boolean
    On Error Resume Next
    Dim intCnt As Integer

    intCnt = DCount("[Name]", "MSysObjects", "[Name] = '" & strObjName &
"'")
    DoesObjectExist = (intCnt > 0)
End Function

this *usually* returns true for a table with a broken link. Except,
sometimes it doesn't.  It does when I call it from the immediate window,
but when it's called from code, it may return a False.  If my hair weren't
already nearly white, it would be with this.

I'm also sometimes getting "item not found in this collection" when I try
to call the above routine from code.

Charlotte


Charlotte Foust
(916) 206-4336

On Fri, Nov 20, 2015 at 2:57 PM, Gustav Brock <gustav at cactus.dk> wrote:

> Hi Charlotte
>
> And your code is?
>
> /gustav
>
> ________________________________________
> Fra: AccessD <accessd-bounces at databaseadvisors.com> på vegne af Charlotte
> Foust <charlotte.foust at gmail.com>
> Sendt: 20. november 2015 23:15
> Til: Access Developers discussion and problem solving
> Emne: [AccessD] Connect String for Linked Table
>
> I'm working on a db built in 2010 on Windows 7 but I'm using 2013 on
> Windows 10.  I have code that worked just fine last year but is breaking
> this year because suddenly, if the back end file is moved or renamed, the
> code to set a tabledef object to the linked table in question can't find
> the linked table.  Obviously, the table still exists because the linked
> table manager can see it, so it's still in the system tables, but the code
> breaks.
>
> Any ideas?
>
> Charlotte Foust
> (916) 206-4336

-- 
AccessD mailing list
AccessD at databaseadvisors.com
http://databaseadvisors.com/mailman/listinfo/accessd
Website: http://www.databaseadvisors.com




More information about the AccessD mailing list