web-dev-qa-db-ja.com

プログラムによるリンクテーブルの場所の変更

最初のデータベースと同じディレクトリにある2番目のデータベースにリンクテーブルのあるAccessデータベースがあります。

(テスト用に)ディレクトリ全体を新しい場所にコピーし、データベース1をデータベース2のテーブルにリンクしたままにしますが、リンケージはまだ新しい場所ではなく元のディレクトリにリンクしています。

次の2つのいずれかを実行します。

  1. フォルダーのパスが相対パスになるように、データベース2のテーブルへのリンクを作成します。つまり、データベース2へのパスがハードコーディングされないようにします。

    または

  2. Application.pathをチェックし、それに応じてプログラムでリンケージを調整するルーチンをForm_Load(またはautoexecマクロ)に用意します。

12
Steve H

必要なバックエンドとリンクする必要があるテーブルのテーブルを参照できるスタートアップフォームがあると便利です。テーブルコレクションを反復処理することもできますが、リストの方が少し安全だと思います。その後、必要なのは少しのコードだけです。これがスニペットです。

''Connection string with database password 
strConnect = "MS Access;PWD=pw;DATABASE=" & Me.txtNewDataDirectory

Set rs = CurrentDb.OpenRecordset("Select TableName From LinkTables " _
& "WHERE TableType = 'LINK'")

Do While Not rs.EOF
    ''Check if the table is already linked, if it is, update the connection
    ''otherwise, link the table. 

    If IsNull(DLookup("[Name]", "MSysObjects", "[Name]='" & rs!TableName & "'")) Then
        Set tdf = db.CreateTableDef(rs!TableName, dbAttachSavePWD, _
            rs!TableName, strConnect)
        db.TableDefs.Append tdf
    Else
        db.TableDefs(rs!TableName).Connect = strConnect
    End If
    db.TableDefs(rs!TableName).RefreshLink
    rs.MoveNext
Loop
6
Fionnuala

おかげで、

私はそれを問題なく使用しましたが、レコードセットでは使用しませんでした。

Const LnkDataBase = "C:\NorthWind.mdb"
Sub relinktables()
'Routine to relink the tables automatically. Change the constant LnkDataBase to the desired one and run the sub
Dim dbs As DAO.Database
Dim tdf As DAO.TableDef
Dim strTable As String
Set dbs = CurrentDb()
For Each tdf In dbs.TableDefs
    If Len(tdf.Connect) > 1 Then 'Only relink linked tables
        If tdf.Connect <> ";DATABASE=" & LnkDataBase Then 'only relink tables if the are not linked right
            If Left(tdf.Connect, 4) <> "ODBC" Then 'Don't want to relink any ODBC tables
                strTable = tdf.Name
                dbs.TableDefs(strTable).Connect = ";DATABASE=" & LnkDataBase
                dbs.TableDefs(strTable).RefreshLink
            End If
        End if
    End If
Next tdf
End Sub
5
Arnoud

私はusncahillのソリューションを使用し、自分のニーズに合わせて修正しました。私は彼らの解決策に投票する十分な評判がないので、私の追加のコードが気に入ったら、両方に投票してください。

ライブデータとテストデータを含む2つのバックエンドデータベースをすばやく切り替える方法が必要でした。したがって、前述のコードを次のように変更しました。

Private Sub ReplaceLink(oldLink As String, newLink As String)
    Dim tbl As TableDef, db As Database

    Set db = CurrentDb

    For Each tbl In db.TableDefs
        If InStr(tbl.Connect, oldLink) > 0 Then
            tbl.Connect = Replace(tbl.Connect, oldLink, newLink)
            tbl.RefreshLink
        End If
    Next
End Sub

Public Function ConnectTestDB()
    ReplaceLink "Data.accdb", "Test.accdb"
End Function

Public Function ConnectLiveDB()
    ReplaceLink "Test.accdb", "Data.accdb"
End Function

Public Function TestDBSwitch()
    Dim tbl As TableDef, db As Database
    Dim wasData As Boolean
    Dim wasTest As Boolean

    wasData = False
    wasTest = False

    Set db = CurrentDb

    For Each tbl In db.TableDefs
        If InStr(tbl.Connect, "JGFC Flooring Data") > 0 Then
            wasData = True
        ElseIf InStr(tbl.Connect, "JGFC Flooring Test") > 0 Then
            wasTest = True
        End If
    Next

    If wasData = True And wasTest = True Then
        MsgBox "Data Mismatch.  Both Test and Live Data are currently linked! Connecting all tables to Test database. To link to Live database, please run again.", , "Data Mismatch"
        ConnectTestDB
    ElseIf wasData = True Then
        ConnectTestDB
        MsgBox "You are now connected to the Test database.", , "Connection Changed"
    ElseIf wasTest = True Then
        ConnectLiveDB
        MsgBox "You are now connected to the Live database.", , "Connection Changed"
    End If
 End Function

(前のコードは、テストファイルとライブデータファイルの両方が同じディレクトリにあり、ファイル名がテストとデータで終わることを前提としていますが、他のパス/ファイル名に簡単に変更できます)

フロントエンドDBのボタンからTestSwitchDBを呼び出して、テスト環境と本番環境をすばやく切り替えます。私のAccess DBにはユーザー環境を切り替えるユーザーコントロールがあるため、管理ユーザーがフロントエンドDBにログインするときに、ConnectTestDB関数を直接使用して、管理ユーザーをデフォルトでテストDBに接続します。同様に、他のユーザーがフロントエンドにログインするときにConnectLiveDB関数を使用します。

また、TestSwitchDB関数には、switch関数を呼び出す前に両方の環境への接続が混在しているかどうかを通知する、迅速なエラー検出があります。このエラーが繰り返し発生する場合は、他の問題の兆候である可能性があります。

2
David Beckman

企業のIT部門は、共有ファイルのパスをローカルから企業に変更したため、すべてのデータベーステーブルをリダイレクトする必要がありました。これは、特に複数の異なるデータベースがリンクされている場合に、すべてのリンクを削除して再作成するのは面倒だったでしょう。この質問を見つけましたが、他の回答はどれもうまくいきませんでした。以下は私が使用したものです。多くのテーブルでは、更新ごとに数秒かかるため、これにはしばらく時間がかかります。

Public Sub Fix_Table_Locations()
    Dim tbl As TableDef, db As Database, strConnect As String

    Set db = CurrentDb

    For Each tbl In db.TableDefs
        If InStr(tbl.Connect, "Portion of connect string to change") > 0 Then
            tbl.Connect = Replace(tbl.Connect, "Portion of connect string to change", "New portion of connect string")
            tbl.RefreshLink
        End If
    Next
End Sub
1
usncahill

ファイルの場所によっては、相対パスを使用できる場合があります。 Accessが検索するデフォルトの場所はドキュメント(C:\ Users\UserName\Documents)です。したがって、..と入力すると、Documentsから1つ上のフォルダ(ユーザーのフォルダ)が表示されます。たとえば、データベースファイルが常に次の場所に保存される場合

C:\ Users\UserName\Access App\Access Database

次に、関連するファイルの場所として「..\Access App\Database」と入力します。それ以外の場合は、VBAを使用する必要があります。私の場合、ファイル/ファイルフォルダーが常に同じ場所にあるとは限りません。一部のユーザーはファイルをGoogleドライブに保存し、他のユーザーはマイドキュメントまたはデスクトップを使用します。 usncahillが投稿したものと同様の関数を使用することができました。

Sub relinkBackendDB()
    Dim sFilePath As String
    Dim connectionString As String
    Dim tbl As TableDef
    Dim db As Database

    sFilePath = (Application.CurrentProject.Path & "\system\Dojo Boss Database.accdb")
    connectionString = ("MS Access;PWD=MyPassword;DATABASE=" & sFilePath)
    Set db = CurrentDb

    For Each tbl In db.TableDefs
        If Len(tbl.Connect) > 0 Then
            'MsgBox tbl.Connect 'If you're getting errors, uncomment this to see connection string syntax
            tbl.Connect = connectionString
            tbl.RefreshLink
        End If
    Next
End Sub

この関数は、「ホーム」フォームがロードされたときにon_loadイベントプロシージャを介して呼び出すため、アプリが最初にロード/開かれるたびに呼び出されます。この方法では、ユーザー名が何であっても、関連するファイルフォルダーが常に検索されます。

0
technoman23