msoffice-我可以比较两个ms-access文件吗



我想比较两个ms-access.mdb文件,以检查它们在两个文件中包含的数据是否相同。

我该怎么做?

我在代码中做过很多次这种事情,主要是在本地MDB需要从网站上输入的数据中进行更新的情况下。在一个案例中,网站是由MDB驱动的,而在另一个例子中,它是MySQL数据库。对于MDB,我们只是下载了它,对于MySQL,我们在网站上运行脚本来导出和FTP文本文件。

现在,主要的一点是,我们想将本地MDB中的数据与从网站下载的数据进行比较,并更新本地MDB以反映网站上所做的更改(不,不可能使用单个数据源——这是我建议的第一件事,但不可行)。

让我们将MDB A称为您的本地数据库,将MDB B称为您正在下载的数据库以进行比较。你要检查的是:

  1. MDB A中存在但MDB B中不存在的记录。这些记录可能是也可能不是删除的候选者(这将取决于您的特定数据)。

  2. 存在于MDB B中但不存在于MDB A中的记录。这些记录将从MDB B附加到MDB A中。

  3. 两者中都存在的记录,需要逐字段进行比较。

通过使用外部联接查找丢失记录的查询,步骤#1和#2可以很容易地完成。步骤3需要一些代码。

代码背后的原理是,两个MDB中的所有表的结构都是相同的。因此,您可以使用DAO来遍历TableDefs集合,打开一个记录集,并遍历字段集合,以便在每个表的每一列上运行一条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子句必须不同——文本字段需要与数字字段和数据字段区别对待。因此,您可能需要一个SELECT CASE,它根据字段类型编写WHERE子句:

  Select Case fld.Type
    Case dbText, dbMemo
    Case Else
  End Select

您将希望使用Nz()来比较文本字段,但您会使用Nz(TextField,'')来进行比较,而对数字字段或日期字段则使用N兹(NumericField,0)。

我的示例代码实际上并没有使用上面的结构来定义WHERE子句,因为它仅限于与ZLS(文本字段)连接时工作良好的字段。下面的内容读起来相当复杂,但它基本上是对上述结构的扩展。

它是为了提高更新效率而编写的,因为它为表的每个字段执行一个SQLUPDATE,这比为每行执行一个SQL UPDATE要高效得多。另一方面,如果您不想进行更新,但想要一份差异列表,您可能会以不同的方式对待整个事情。但这会变得相当复杂,这取决于输出,

如果您只想知道两个MDB是否相同,那么您应该首先检查每个表中的记录数,如果有一个不匹配,则退出并告诉用户MDB不相同。如果记录数相同,那么您必须逐个字段进行检查,我认为最好使用逐列动态编写的SQL来完成这一点——一旦其中一个SQL SELECTS返回1条或多条记录,您就中止并告诉用户MDB不相同。

复杂的部分是,如果你想记录差异并通知用户,但深入到这一点会使这篇已经没完没了的帖子变得更长!

下面只是一个较大子例程的一部分代码,该子例程使用qdfNewMembers(来自MDB B)的数据更新保存的查询qdfOldMembers(从MDB a)。第一个参数strSQL是一个SELECT语句,它仅限于要比较的字段,而strTmpDB是另一个MDB(在我们的示例中为MDB B)的路径/文件名。该代码假设strTmpDB已经创建了qdfNewMembers和qdfOldMembers(原始代码动态写入保存的QueryDef)。它可以很容易地成为直接的表名(我使用保存的查询的唯一原因是字段名在为其编写的两个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和一个命令行界面。

披露:我是这个工具的创造者。

获取数据库表的文本转储,并使用BeyondCompare(或任何其他文本比较工具)简单地比较转储的文本文件。粗糙但可以工作!

我对跨数据库比较器有很好的经验。它能够比较结构和/或数据。

请参阅我网站上Microsoft Access第三方实用程序、产品、工具、模块等页面上的比较访问数据库部分。

我添加了";表diff";不久前我的accdbmerge实用程序的功能。我相信这个答案不会帮助解决原来的问题,但它可能对将来面临同样问题的人有所帮助。

如果你想知道文件是否相同,那么

fc file1.mdb file2.mdb 

在DOS命令行上。

如果文件不完全相同,但您怀疑它们包含相同的表和记录,那么最简单的方法是快速编写一个小型实用程序,打开两个数据库并在两个数据库的表中循环执行异构查询,以提取两个文件之间的差异。

有一些工具可以为你做到这一点,但它们似乎都是共享软件。

相关内容

  • 没有找到相关文章

最新更新