Solved

Relink tables in database with a database password, using ADO

Posted on 2006-11-13
12
1,125 Views
Last Modified: 2008-01-09
I am converting my DAO code to ADO for a function that relinks tables in a backend database. I have come across one glitch. The backend database has a database password. The code is below. When I try to run this code, it doesn't like the database password line. That is, when Access tries to execute:
     tdf.Properties("Jet OLEDB:Database Password") = strPassword
I get the following error:
     Run-time error '3265';
     Item cannot be found in the collection corresponding to the requested name or ordinal.

The code words fine if I omit the offending line and the database has no password. If I omit the line and the database DOES have a password, I get an "Invalid password" error.

Can I use ADO to relink tables in password-protected databases? If I can, then how do I fix my code?


Function ReLink(strDir As String) As Boolean

' Relink a broken linked Access table.

On Error Resume Next

    Dim cnn As New ADODB.Connection
    Dim cat As ADOX.Catalog
    Dim tdf As ADOX.Table
    Dim intCounter As Integer
    Dim varReturn As Variant
    Dim intNumBadLinks As Integer
    Dim strMissingTables As String
    Dim strPassword as String
   
    'First, make sure all of the linked tables are in the selected database.
    'If one table is missing, then do not try to link the database. If all
    'the linked tables exist, then go ahead and relink them.
   
    Set cnn = CurrentProject.Connection
   
    Set cat = New ADOX.Catalog
    Set cat.ActiveConnection = cnn
   
    With cat
        .ActiveConnection = CurrentProject.Connection
       
        strPassword = InputBox("Enter the password for the items database: " _
            & vbCr & strDir & vbCr _
            & "If there is no password, then just hit Enter.", "Enter Password")
       
        'Create progress meter
        Call SysCmd(acSysCmdInitMeter, "Linking Data Tables", .Tables.Count)
   
        'Loop through each table, attempting to update the link
        intNumBadLinks = 0
        strMissingTables = ""
        For Each tdf In .Tables
            intCounter = intCounter + 1
            Call SysCmd(acSysCmdUpdateMeter, intCounter)
            If .Tables(tdf.Name).Type = "LINK" And _
                Left(tdf.Name, 3) = "tbl" Then
                if strPassword <> "" then
                   tdf.Properties("Jet OLEDB:Database Password") = strPassword 'THIS LINE CAUSES THE ERROR
                end if
                tdf.Properties("Jet OLEDB:Link Datasource") = strDir
            End If
            If Err.Number Then
                If intNumBadLinks = 0 Then
                    MsgBox "The physical table '" & tdf.Name & "' " _
                        & "was not found in database '" & strDir & "'. " _
                        & "You either selected the wrong items database file or " _
                        & "the structure of this file must be updated to be " _
                        & "compatible with this version of gItemBank. I will continue to check for missing tables.",  _
                            vbExclamation, "Incompatible Items Database File"
                End If
                intNumBadLinks = intNumBadLinks + 1
                strMissingTables = strMissingTables & ", " & tdf.Name
                Err.Clear
            End If
        Next tdf
    End With
   
    'Reset the progress meter
    Call SysCmd(acSysCmdRemoveMeter)
   
    If intNumBadLinks > 0 Then
        MsgBox "The following " & intNumBadLinks & " tables were missing from your data file: " _
            & vbCrLf & vbCrLf & strMissingTables
    End If
   
    varReturn = SysCmd(acSysCmdClearStatus)
   
    Set tdf = Nothing
    Set cat = Nothing
    Set cnn = Nothing
   
    ReLink = (intNumBadLinks = 0)
   
End Function
0
Comment
Question by:gordonwwaugh
  • 7
  • 3
12 Comments
 
LVL 84

Accepted Solution

by:
Scott McDaniel (Microsoft Access MVP - EE MVE ) earned 500 total points
ID: 17935123
Why are you changing? You can have ADO and DAO live peacefully side-by-side ...

ADOX tables have different properties. Try something like this instead:

if strPassword <> "" then
  tdf.Name = YourTableName
  Set tdf.ParentCatalog = cat
  tdf.Properties("Jet OLEDB:Link Provider String") = "MS Access;DATABASE=C:\SomeFolder\SomeFile.mdb;Pwd=" & strPassword
  tdf.Properties("Jet OLEDB:Remote Table Name") = tdf.Name
  tdf.Properties("Jet OLDEB:Create Link") = True
  cat.Tables.Append tdf <<< you may not need this
End If
0
 

Author Comment

by:gordonwwaugh
ID: 17935311
It doesn't like "Link Provider String". Error message was something like "Invalid ISAM ..."

By the way, I don't need to create links. I just need to reassign them to a different data source.

Perhaps my code is fine, except that I need to replace "Jet OLEDB: Database Password" with the correct phrase. "Jet OLEDB: Link Database Password" does not work either.
0
 

Author Comment

by:gordonwwaugh
ID: 17935329
I found the Microsoft web page that you were probably looking at. The top half shows how to create links. The bottom half shows how to refresh links. I'll give it a try.

http://ask.support.microsoft.com/kb/240222
0
Simplifying Server Workload Migrations

This use case outlines the migration challenges that organizations face and how the Acronis AnyData Engine supports physical-to-physical (P2P), physical-to-virtual (P2V), virtual to physical (V2P), and cross-virtual (V2V) migration scenarios to address these challenges.

 

Author Comment

by:gordonwwaugh
ID: 17935443
Okay. I get farther. Now it says the password is invalid. But I can open the linked database manually using the same password ("garbage"). Here's the code I'm using now (pretty much straight from the MS web site).

Any thoughts why it thinks my password is wrong?


Private Sub Command2_Click()

Dim adoCn As ADODB.Connection
Dim adoCat As New ADOX.Catalog
Dim adoTbl As New ADOX.Table
Dim strDir As String

'Refresh Link...
Set adoCn = CurrentProject.Connection
Set adoCat = New ADOX.Catalog
Set adoCat.ActiveConnection = adoCn

Set adoTbl.ParentCatalog = adoCat

strDir = "C:\My Backend Database.mdb"

For Each adoTbl In adoCat.Tables
    If adoTbl.Type = "LINK" Then
        adoTbl.Properties("Jet OLEDB:Link Provider String") = "MS Access;Pwd=garbage"
        adoTbl.Properties("Jet OLEDB:Link Datasource") = strDir
    End If
Next

Debug.Print "Link Refreshed..."

End Sub
0
 
LVL 84
ID: 17937225
I would suppose it's because you're setting your adoCn object to the current database's connection object, which is (most likely) NOT C:\My Backend Database.mdb ... try building your adoCn object in this manner, then using that connection as the ActiveConnection, something link this:

Private Sub Command2_Click()

Dim adoCn As ADODB.Connection
Dim adoCat As New ADOX.Catalog
Dim adoTbl As New ADOX.Table
Dim strCn as String
Dim strDir As String

strDir = "C:\My Backend Database.mdb"
Set adoCn = New ADODB.Connection
With adoCn
    .Provider = "Microsoft.JET.OLEDB.4.0;Jet OLEDB:Database Password=garbage"
    .Open strDir
End With

'Refresh Link...
'/Set adoCn = CurrentProject.Connection << removed this line - it was pointing to your current db connection

Set adoCat = New ADOX.Catalog
Set adoCat.ActiveConnection = adoCn

Set adoTbl.ParentCatalog = adoCat

For Each adoTbl In adoCat.Tables
    If adoTbl.Type = "LINK" Then
        adoTbl.Properties("Jet OLEDB:Link Provider String") = "MS Access;Pwd=garbage"
        adoTbl.Properties("Jet OLEDB:Link Datasource") = strDir
    End If
Next

Debug.Print "Link Refreshed..."

End Sub

Also, I noticed that you didn't set your Connection object to a New object:

Set adoCn = New ADODB.Connection

When dealing with ADO, you must set several objects to New, depending on what you wish to accomplish with them ... for example, Recordsets and Connection objects must always be initialized and then set to New:

Dim con As ADODB.Connection
<other stuff here>
Set con = new ADODB.Connection

Also, it's typically not a good idea to do this all in one line:

dim con as New ADODB.Connection

since you cannot trap for errors, should they occur. If you use the syntax as above, and there is a problem initializing your Connection object, ADO will throw the error and your users will be VERY confused <g> ... if you use the two line method, where you Dim the object and then later Set it (AFTER you fire up your error handling code), you can trap the error and deal with it.

0
 

Author Comment

by:gordonwwaugh
ID: 17939578
My code works fine if the database is not password-protected. Doesn't that mean that my connection objects are fine?

I also see that your code actually opens the backend database.

On the other hand, maybe adding the password property requires that things be done differently. I'll give your suggestion a shot and see what happens.
0
 
LVL 84
ID: 17940245
Access handles the two types differently. If your backend is password protected, Access will require you to provide the password in your code, and simply setting your tables to the current connection isn't sufficient. In general, you should ALWAYS build a new connection and use that to relink your tables. Don't depend on the current connection - else what's the point of relinking, if all you're doing is using the same connection?

0
 

Author Comment

by:gordonwwaugh
ID: 17948384
It works!

I very much appreciate you taking the time to explain things. I'll be careful to always build new ADO connections in the future.
0
 

Author Comment

by:gordonwwaugh
ID: 17949146
Actually, it did not work after all. The backend database does not get linked.

The problem is that the table type is never "LINK". Thus, the link datasource line is never executed.

I think that's because you are opening the adodb connection and directly referencing its tables. In fact, I think we need to reference the tables in the current database. Only then will the linked tables have a table type of "LINK."

0
 

Author Comment

by:gordonwwaugh
ID: 18025569
I have received no further replies, so I'm going to close this question now.

I have gone ahead and rewritten my code in DAO. Although it's not the answer I wanted most, using DAO works fine. This is what LSMConsulting suggested in the first place, so I'll consider the question answered.
0

Featured Post

Networking for the Cloud Era

Join Microsoft and Riverbed for a discussion and demonstration of enhancements to SteelConnect:
-One-click orchestration and cloud connectivity in Azure environments
-Tight integration of SD-WAN and WAN optimization capabilities
-Scalability and resiliency equal to a data center

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
update query 4 25
trouble referencing field on sub form 8 37
Signature required on a report 5 33
Access Schema 6 26
Regardless of which version on MS Access you are using, one of the harder data-entry forms to create is one where most data from previous entries needs to be appended to new records, especially when there are numerous fields and records involved.  W…
Overview: This article:       (a) explains one principle method to cross-reference invoice items in Quickbooks®       (b) explores the reasons one might need to cross-reference invoice items       (c) provides a sample process for creating a M…
Familiarize people with the process of retrieving data from SQL Server using an Access pass-thru query. Microsoft Access is a very powerful client/server development tool. One of the ways that you can retrieve data from a SQL Server is by using a pa…
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …

830 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question