2 つの ms-access .mdb ファイルを比較して、含まれているデータが両方で同じであることを確認したいと考えています。
これどうやってするの?
私はこの種のことをコードで何度も行ってきましたが、ほとんどの場合、Web サイトに入力されたデータから取得した更新をローカル MDB に適用する必要がありました。あるケースでは、Web サイトは MDB によって駆動され、他のケースでは MySQL データベースでした。MDB の場合はダウンロードしただけで、MySQL の場合は Web サイトでスクリプトを実行してテキスト ファイルをエクスポートし、FTP しました。
ここで重要な点は、ローカル MDB のデータを Web サイトからダウンロードしたデータと比較し、Web サイトで行われた変更を反映するようにローカル MDB を更新することでした (いいえ、単一のデータ ソースを使用することはできませんでした。 - それは私が最初に提案したことでしたが、実現可能ではありませんでした)。
MDB A をローカル データベースと呼び、MDB B を比較のためにダウンロードしているデータベースと呼びましょう。確認する必要があるのは次のとおりです。
MDB A には存在するが MDB B には存在しないレコード。これらは削除の候補になる場合とそうでない場合があります (これは特定のデータによって異なります)。
MDB B には存在するが MDB A には存在しないレコード。これらは MDB B から MDB A に追加します。
両方に存在するレコード。フィールドごとに比較する必要があります。
手順 1 と 2 は、外部結合を使用して欠落しているレコードを検索するクエリを使用すると、かなり簡単に実行できます。ステップ 3 にはいくつかのコードが必要です。
コードの背後にある原則は、両方の MDB のすべてのテーブルの構造が同一であるということです。したがって、DAO を使用して TableDefs コレクションをウォークし、レコードセットを開き、fields コレクションをウォークして、データを更新するか、相違点のリストを出力する各テーブルの各列で SQL ステートメントを実行します。
コードの背後にある基本的な構造は次のとおりです。
Set rs = db.OpenRecordset("[SQL statement with the fields you want compared]")
For Each fld In rs.Fields
' Write a SQL string to update all the records in this column
' where the data doesn't match
strSQL = "[constructed SQL here]"
db.Execute strSQL, dbFailOnError
Next fld
ここでの主な複雑さは、各フィールドの WHERE 句が異なる必要があることです。テキスト フィールドは、数値フィールドやデータ フィールドとは異なる方法で処理する必要があります。したがって、おそらく、フィールド タイプに基づいて WHERE 句を記述する SELECT CASE が必要になるでしょう。
Select Case fld.Type
Case dbText, dbMemo
Case Else
End Select
Nz() を使用してテキスト フィールドを比較する必要がありますが、そのためには Nz(TextField,'') を使用し、数値フィールドまたは日付フィールドには Nz(NumericField,0) を使用します。
私のコード例では、上記の構造を実際に使用して WHERE 句を定義していません。これは、連結された ZLS (テキスト フィールド) と比較して非常にうまく機能するフィールドに限定されているためです。以下は非常に読みにくいですが、基本的には上記の構造を拡張したものです。
これは、テーブルのフィールドごとに SQL UPDATE を実行するため、更新の効率化のために作成されました。これは、行ごとに SQL UPDATE を実行するよりもはるかに効率的です。一方、更新を行いたくないが、相違点のリストが必要な場合は、全体を別の方法で処理することができます。しかし、それは出力によってはかなり複雑になります。
2 つの MDB が同一かどうかだけを知りたい場合は、最初に各テーブルのレコード数を確認し、一致しないものが 1 つある場合は終了して、MDB が同じではないことをユーザーに伝えます。レコード数が同じ場合は、フィールドごとにチェックする必要があります。これは、動的に記述された列ごとの SQL で最もよく達成されると思います。結果の SQL SELECTS の 1 つが 1 つ以上のレコードを返すとすぐに、中止します。 MDB が同一ではないことをユーザーに伝えます。
複雑な部分は、違いを記録してユーザーに通知したい場合ですが、それを行うと、このすでに途方もない投稿がさらに長くなります!
以下は、保存されたクエリ qdfOldMembers (MDB A から) を qdfNewMembers (MDB B から) からのデータで更新する、より大きなサブルーチンのコードの一部です。最初の引数 strSQL は、比較するフィールドに限定された SELECT ステートメントです。strTmpDB は、他の MDB (この例では MDB B) のパス/ファイル名です。このコードは、strTmpDB に qdfNewMembers と qdfOldMembers が既に作成されていることを前提としています (元のコードは、保存された QueryDef をオンザフライで書き込みます)。簡単に直接のテーブル名にすることもできます (保存されたクエリを使用する唯一の理由は、それが作成された 2 つの MDB 間でフィールド名が正確に一致しないためです)。
Public Sub ImportMembers(strSQL As String, strTmpDB As String)
Const STR_QUOTE = """"
Dim db As Database
Dim rsSource As Recordset '
Dim fld As Field
Dim strUpdateField As String
Dim strZLS As String
Dim strSet As String
Dim strWhere As String
' EXTENSIVE CODE LEFT OUT HERE
Set db = Application.DBEngine(0).OpenDatabase(strTmpDB)
' UPDATE EXISTING RECORDS
Set rsSource = db.OpenRecordset(strSQL)
strSQL = "UPDATE qdfNewMembers INNER JOIN qdfOldMembers ON "
strSQL = strSQL & "qdfNewMembers.EntityID = qdfOldMembers.EntityID IN '" _
& strTmpDB & "'"
If rsSource.RecordCount <> 0 Then
For Each fld In rsSource.Fields
strUpdateField = fld.Name
'Debug.Print strUpdateField
If InStr(strUpdateField, "ID") = 0 Then
If fld.Type = dbText Then
strZLS = " & ''"
Else
strZLS = vbNullString
End If
strSet = " SET qdfOldMembers." & strUpdateField _
& " = varZLStoNull(qdfNewMembers." & strUpdateField & ")"
strWhere = " WHERE " & "qdfOldMembers." & strUpdateField & strZLS _
& "<>" & "qdfNewMembers." & strUpdateField & strZLS _
& " OR (IsNull(qdfOldMembers." & strUpdateField _
& ")<>IsNull(varZLStoNull(qdfNewMembers." _
& strUpdateField & ")));"
db.Execute strSQL & strSet & strWhere, dbFailOnError
'Debug.Print strSQL & strSet & strWhere
End If
Next fld
End If
End Sub
関数 varZLSToNull() のコード:
Public Function varZLStoNull(varInput As Variant) As Variant
If Len(varInput) = 0 Then
varZLStoNull = Null
Else
varZLStoNull = varInput
End If
End Function
それが複雑すぎて意味をなさないかどうかはわかりませんが、誰かの助けになるかもしれません。
AccessDiff(有料製品)を試すことができます。スキーマ、データを比較し、オブジェクトにアクセスする機能があります。GUIとコマンドラインインターフェイスがあります。
開示:私はこのツールの作成者です。
Cross-Database Comparator の使用経験は非常に豊富です。構造やデータを比較することができます。
データベース テーブルのテキスト ダンプを取得し、BeyondCompare (またはその他のテキスト比較ツール) を使用して、ダンプされたテキスト ファイルを単純に比較します。粗雑ですが動作します!
私の Web サイトのMicrosoft Access サード パーティのユーティリティ、製品、ツール、モジュールなどのページにある Access データベースの比較セクションを参照してください。
少し前にaccdbmergeユーティリティに「テーブル差分」機能を追加しました。この回答は元の質問の解決には役立たないと思いますが、将来同じ問題に直面した人にとっては役立つかもしれません。
ファイルが同一かどうかを知りたい場合は、
fc file1.mdb file2.mdb
DOS コマンドラインで。
ファイルが同一ではないが、同じテーブルとレコードが含まれていると思われる場合、最も簡単な方法は、両方のデータベースを開き、両方のテーブルを循環して異種クエリを実行し、2 つの間の差分を抽出する小さなユーティリティをすばやく作成することです。ファイル。
これを行うツールがいくつかありますが、それらはすべてシェアウェアのようです。