2008-10-27 11 views
5

Quiero comparar dos archivos .mdb de acceso de ms para verificar que los datos que contienen sean los mismos en ambos.¿Puedo comparar dos archivos de acceso de ms?

¿Cómo puedo hacer esto?

+0

Con Office 2013 Professional Plus u Office 365 ProPlus, Microsoft ahora ofrece una herramienta de comparación de base de datos: https://support.office.com/en-gb/article/Basic-tasks-in-Database-Compare-bbb1574b-99ea -43f5-88a1-a02ff54cdcdb –

+1

¿por qué se cerró esto? no está pidiendo una herramienta, biblioteca o sitio alguno –

Respuesta

5

He hecho este tipo de cosas en código muchas, muchas veces, sobre todo en los casos en que un MDB local necesitaba tener aplicadas actualizaciones a partir de los datos ingresados ​​en un sitio web. En un caso, el sitio web fue manejado por un MDB, en otros, era una base de datos MySQL. Para el MDB, acabamos de descargarlo, para MySQL, ejecutamos scripts en el sitio web para exportar y FTP archivos de texto.

Ahora, el punto principal es que queríamos comparar datos en el MDB local con los datos descargados del sitio web y actualizar el MDB local para reflejar los cambios realizados en el sitio web (no, no fue posible usar un única fuente de datos: fue lo primero que sugerí, pero no fue posible).

Llamemos a MDB A su base de datos local, y MDB B la que está descargando para comparar. Lo que tienes que comprobar es:

  1. registros que existen en MDB A pero no en MDB B. Estos pueden o no pueden ser candidatos para su eliminación (esto dependerá de sus datos en particular).

  2. registros que existen en MDB B pero no en MDB A. Estos se le añadirá a partir MDB MDB B a A.

  3. registros que existen en ambos, que deberán ser comparados campo por campo.

Los pasos # 1 y # 2 se logran bastante fácilmente con las consultas que usan una combinación externa para encontrar los registros que faltan. El paso 3 requiere un código.

El principio detrás del código es que la estructura de todas las tablas en ambos MDB es idéntica. Por lo tanto, utiliza DAO para recorrer la colección TableDefs, abrir un conjunto de registros y recorrer la colección de campos para ejecutar una instrucción SQL en cada columna de cada tabla que actualiza los datos o genera una lista de las diferencias.

La estructura básica detrás del código es:

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 

Ahora, la mayor complejidad de este caso es que la cláusula WHERE para cada campo tiene que ser diferente - los campos de texto deben ser tratados de manera diferente a partir de datos numéricos y campos. Así que es probable que desee un SELECT CASE que escribe su cláusula WHERE basado en el tipo de campo:

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

Usted querrá utilizar Nz() para comparar los campos de texto, sino que tendría que utilizar Nz (TextField , '') para eso, al usar Nz (NumericField, 0) para campos numéricos o campos de fecha.

Mi código de ejemplo no usa realmente la estructura anterior para definir la cláusula WHERE porque está limitado a campos que funcionan muy bien comparando concatenado con un ZLS (campos de texto). Lo que está debajo es bastante complicado de leer, pero básicamente es una expansión en la estructura anterior.

Se escribió para la eficiencia de las actualizaciones, ya que ejecuta una ACTUALIZACIÓN SQL para cada campo de la tabla, que es mucho más eficiente que ejecutar una ACTUALIZACIÓN SQL para cada fila. Si, por otro lado, no desea hacer una actualización, pero desea una lista de las diferencias, puede tratar todo de manera diferente. Pero eso se vuelve bastante complicado dependiendo de la salida,

Si todo lo que quiere saber es si dos MDB son idénticos, primero debería verificar primero el número de registros en cada tabla, y si tiene una no coincidencia, salga y diga al usuario que los MDB no son lo mismo. Si la cantidad de registros es la misma, debe verificar el campo por campo, lo cual creo que se logra mejor con SQL columna por columna escrito dinámicamente: tan pronto como uno de los SELECTS SQL resultantes devuelva 1 o más registros, usted aborta y diga a su usuario que los MDB no son idénticos.

La parte complicada es si desea registrar las diferencias e informar al usuario, pero entrar en eso ¡haría que esta publicación ya sea interminable sea aún más larga!

Lo que sigue es solo una parte del código de una subrutina más grande que actualiza la consulta guardada qdfOldMembers (de MDB A) con datos de qdfNewMembers (de MDB B). El primer argumento, strSQL, es una declaración SELECT que está limitada a los campos que desea comparar, mientras que strTmpDB es la ruta/nombre de archivo de la otra MDB (MDB B en nuestro ejemplo). El código asume que strTmpDB ya tiene qdfNewMembers y qdfOldMembers creados (el código original escribe QueryDef guardado sobre la marcha). Podría ser tan fácilmente como nombres de tabla directa (la única razón por la que uso una consulta guardada es porque los nombres de campo no coinciden exactamente entre los dos MDB para los que fue escrito).

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 

Código para la función varZLSToNull():

Public Function varZLStoNull(varInput As Variant) As Variant 
    If Len(varInput) = 0 Then 
    varZLStoNull = Null 
    Else 
    varZLStoNull = varInput 
    End If 
End Function 

No sé si eso es demasiado compleja como para tener sentido, pero tal vez va a ayudar a alguien.

-4

Si desea saber si los archivos son idénticos a continuación

fc file1.mdb file2.mdb 

en una línea de comandos de DOS.

Si los archivos no son idénticos pero sospecha que contienen las mismas tablas y registros, la forma más fácil sería escribir rápidamente una pequeña utilidad que abra ambas bases de datos y recorra las tablas de ambos realizando una consulta heterogénea para extraer el Diferencia entre los dos archivos.

Existen algunas herramientas que harán esto por usted, pero todas parecen ser shareware.

+0

Esto parecía estar funcionando. –

+1

Esto no compara los archivos mdb, diciéndole que estos formularios son diferentes, ¡o que estas tablas no tienen la misma estructura! –

+0

Esto no funcionará en absoluto si quiere comparar los datos. Incluso si los datos y los objetivos son completamente idénticos, el estado compacto de la base de datos podría ser diferente. – JohnFx

2

Realice volcados de texto de tablas de bases de datos y simplemente compare los archivos de texto objeto de dumping utilizando BeyondCompare (o cualquier otra herramienta de comparación de texto). Crudo pero puede funcionar!

+0

@Ather, ¿me puede explicar cómo puedo obtener un volcado de texto? –

+0

Tengo la misma necesidad y uso el método de Ather. Tengo un programa simple que solo hace "seleccionar *" de cada tabla y escribe los resultados en texto. En realidad, en mi caso, espero que algunos campos sean diferentes y mi pequeño programa se salte esos. Luego difiero el texto. –

+0

@Varun - Estoy usando MS Access 2007 y hay una opción para exportar a archivo de texto (y Word, XML, Excel, etc.) en la cinta de datos externos. No recuerdo si el archivo de exportación a texto existía en el acceso anterior a 2007. Lo siento, debería haber mencionado eso en respuesta. – Ather

4

Puedes probar AccessDiff (producto pagado). Tiene la capacidad de comparar el esquema, los datos y también acceder a los objetos. Tiene una GUI y también una interfaz de línea de comando.

Divulgación: soy el creador de esta herramienta.

+0

Debería decir en su respuesta que usted es el creador de esta herramienta, en lugar de dejar que alguien siga el enlace. La divulgación completa mejora la credibilidad. –

+0

Lo siento David. Sí, soy el creador de esta herramienta. Es lo mejor que hay. Compara todos los objetos de Access, no solo el esquema y los registros. –

+0

, así como un gui y cli, también tiene un precio :) –

0

Agregué la función "diff de tabla" a mi utilidad accdbmerge no hace tanto tiempo. Creo que esta respuesta no ayudará a resolver la pregunta original, pero puede ser útil para alguien que tenga el mismo problema en el futuro.