Id. de artículo: 888634 - Última revisión: jueves, 27 de diciembre de 2007 - Versión: 4.1

Recibe el mensaje de error "Esta base de datos está en un estado inesperado" cuando intenta abrir una base de datos en Access 2000 o en una versión posterior de Access

Nota acerca de su sistema operativoEste artículo se aplica a un sistema operativo distinto al que usa. El contenido del artículo que puede que no sea importante para usted, se deshabilitará
Este artículo se refiere a un archivo de base de datos de Microsoft Access .mdb o .accdb.

Moderado: requiere conocimientos de macros, código e interoperabilidad.

En esta página

Expandir todo | Contraer todo

Síntomas

Cuando intenta abrir una base de datos en Microsoft Access 2000 o en una versión posterior, recibe un mensaje de error similar al siguiente:
Esta base de datos está en un estado inesperado

Causa

Este problema puede producirse cuando utiliza la biblioteca de Objeto de acceso a datos (DAO) para convertir una base de datos creada en Microsoft Access 97 o en una versión anterior utilizando el método CompactDatabase. El método CompactDatabase puede dejar la nueva base de datos en un estado parcialmente convertido.

Solución

Para resolver este problema, utilice uno de los métodos siguientes.

Método 1: utilice el comando Convertir base de datos cuando tenga la base de datos original

Si todavía tiene una copia de la base de datos original en su formato original, utilice el comando Convertir base de datos. Para ello, siga estos pasos:

Access 2000, Access 2002 o Access 2003

  1. Haga una copia de seguridad de la base de datos original.
  2. Inicie Access 2000 o una versión posterior.
  3. En el menú Herramientas, haga clic en Utilidades de la base de datos, haga clic en Convertir base de datos y, a continuación, haga clic en A formato de archivo de Access 2000.

    Nota: si está utilizando Access 2000, sólo aparecerá A la versión de la base de datos de Access actual en el menú Convertir base de datos.
  4. En el cuadro de diálogo Base de datos a convertir, haga clic en el nombre de archivo de la base de datos que desee convertir y, después, haga clic en Convertir.
  5. En el cuadro de diálogo Convertir la base de datos en, escriba el nuevo nombre del archivo de base de datos y haga clic en Guardar.

Access 2007

  1. Haga una copia de seguridad de la base de datos original.
  2. Intente abrir esa base de datos.
  3. Cuando abre una base de datos .mdb con el formato de archivo de Access 97 o Access 95, Access muestra el cuadro de diálogo Mejoras de base de datos. Se le preguntará si desea actualizar la base de datos.
  4. Haga clic en para actualizar la base de datos al formato de archivo que haya seleccionado como predeterminado en Access 2007. Después de convertir la base de datos, puede realizar cambios de diseño al archivo en Access 2007. Sin embargo, ya no puede abrir la base de datos utilizando una versión de Access anterior a la versión a la que convirtió la base de datos.

Método 2: recupere los datos y las consultas de base de datos cuando no tenga la base de datos original no segura

Si no tiene una copia de la base de datos original no segura en su formato original y ha intentado realizar técnicas estándar de solución de daños, intente recuperar los datos y las consultas de base de datos. Para ello, siga estos pasos:
  1. Haga una copia de seguridad de la base de datos original.
  2. Inicie Access 2000 o una versión posterior.
  3. Access 2000, Access 2002 o Access 2003
    • Haga clic en Base de datos de Access en blanco, escriba el nuevo nombre de la base de datos en el cuadro Nombre de archivo y haga clic en Crear.
    Access 2007
    • Haga clic en el botón de Office, haga clic en Nuevo, haga clic en Base de datos en blanco y, a continuación, haga clic en Crear para crear una nueva base de datos en blanco.
  4. Access 2000, Access 2002 o Access 2003
    • En el menú Insertar, haga clic en Módulo. Se iniciará el Editor de Microsoft Visual Basic y se creará un nuevo módulo.
    Access 2007
    • En la ficha Crear, haga clic en la flecha hacia abajo situada bajo Macro y, a continuación, haga clic en Módulo. Se iniciará el Editor de Microsoft Visual Basic y se creará un nuevo módulo.
  5. En el menú Herramientas, haga clic en Referencias.
  6. En la lista Referencias disponibles, busque Biblioteca de objetos de Microsoft DAO 3.6 y haga clic para activar la casilla Biblioteca de objetos de Microsoft DAO 3.6.

    Nota: DAO 3.6 también está disponible en Windows XP Home Edition.
  7. Para cerrar el cuadro de diálogo Referencias, haga clic en Aceptar.
  8. Pegue el código siguiente en el nuevo módulo que ha creado.
    Sub RecoverCorruptDB()
        Dim dbCorrupt As DAO.Database
        Dim dbCurrent As DAO.Database
        Dim td As DAO.TableDef
        Dim tdNew As DAO.TableDef
        Dim fld As DAO.Field
        Dim fldNew As DAO.Field
        Dim ind As DAO.Index
        Dim indNew As DAO.Index
        Dim qd As DAO.QueryDef
        Dim qdNew As DAO.QueryDef
        Dim strDBPath As String
        Dim strQry As String
        
        ' Replace the following path with the path of the
        ' corrupted database.
        strDBPath = "C:\My Documents\yourDatabase.mdb"
        
        On Error Resume Next
        Set dbCurrent = CurrentDb
        Set dbCorrupt = OpenDatabase(strDBPath)
     
        For Each td In dbCorrupt.TableDefs
            If Left(td.Name, 4) <> "MSys" Then
                strQry = "SELECT * INTO [" & td.Name & "] FROM [" & td.Name & "] IN '" & dbCorrupt.Name & "'"
                dbCurrent.Execute strQry, dbFailOnError
                dbCurrent.TableDefs.Refresh
                Set tdNew = dbCurrent.TableDefs(td.Name)
                
                ' Re-create the indexes on the table.
                For Each ind In td.Indexes
                    Set indNew = tdNew.CreateIndex(ind.Name)
                    For Each fld In ind.Fields
                        Set fldNew = indNew.CreateField(fld.Name)
                        indNew.Fields.Append fldNew
                    Next
                    indNew.Primary = ind.Primary
                    indNew.Unique = ind.Unique
                    indNew.IgnoreNulls = ind.IgnoreNulls
                    tdNew.Indexes.Append indNew
                    tdNew.Indexes.Refresh
                Next
            End If
        Next
            
        ' Re-create the queries.
        For Each qd In dbCorrupt.QueryDefs
            If Left(qd.Name, 4) <> "~sq_" Then
                Set qdNew = dbCurrent.CreateQueryDef(qd.Name, qd.SQL)
            End If
        Next
        
        dbCorrupt.Close
        Application.RefreshDatabaseWindow
        MsgBox "Procedure Complete."
    End Sub
    
    
    Nota: el código intentará importar a la base de datos actual todas las tablas y todas las consultas de la base de datos dañada. Reemplace C:\Mis documentos\suBaseDeDatos.mdb con la ruta de acceso y el nombre de archivo correctos de su base de datos.
  9. Para ejecutar el código, haga clic en Ejecutar Sub/UserForm en el menú Ejecutar.

Método 3: recupere los datos de la base de datos cuando no tenga la base de datos original segura

Si no tiene una copia de la base de datos original segura en su formato original y ha intentado realizar técnicas estándar de solución de daños, intente recuperar los datos de la base de datos. Para ello, siga estos pasos:
  1. Haga una copia de seguridad de la base de datos original.
  2. Inicie Access 2000 o una versión posterior.
  3. Access 2000, Access 2002 o Access 2003
    • Haga clic en Base de datos de Access en blanco, escriba el nuevo nombre de la base de datos en el cuadro Nombre de archivo y haga clic en Crear.
    Access 2007
    • Haga clic en el botón de Microsoft Office, haga clic en Nuevo, haga clic en Base de datos en blanco y, a continuación, haga clic en Crear para crear una nueva base de datos en blanco.
  4. Access 2000, Access 2002 o Access 2003
    • En el menú Insertar, haga clic en Módulo. Se iniciará el Editor de Microsoft Visual Basic y se creará un nuevo módulo.
    Access 2007
    • En la ficha Crear, haga clic en la flecha hacia abajo situada bajo Macro y, a continuación, haga clic en Módulo. Se iniciará el Editor de Microsoft Visual Basic y se creará un nuevo módulo.
  5. En el menú Herramientas, haga clic en Referencias.
  6. En la lista Referencias disponibles, busque Biblioteca de objetos de Microsoft DAO 3.6 y haga clic para activar la casilla Biblioteca de objetos de Microsoft DAO 3.6.
  7. Para cerrar el cuadro de diálogo Referencias, haga clic en Aceptar.
  8. Pegue el código siguiente en el nuevo módulo que ha creado.
    Option Compare Database
    
    Function BackupSecureDatabase()
        
       On Error GoTo Err_BackupSecureDatabase
       Dim wrkDefault As DAO.Workspace
       Dim dbsNew As DAO.Database
       Dim dbeSecure As DAO.PrivDBEngine
       Dim wrkSecure As DAO.Workspace
       Dim dbsSecure As DAO.Database
       Dim tdfSecure As DAO.TableDef
       Dim strSecureUser As String
       Dim strSecurePwd As String
       Dim strSecurePathToDatabase As String
       Dim strSecurePathToWorkgroupFile As String
       Dim strTableName As String
       Dim strSQL As String
       Dim dbsTemp As DAO.Database
       Dim strTempPathToDatabase As String
       Dim strBackupPathToDatabase As String
       Dim strLogPath As String
       Dim SourceRec As DAO.Recordset
       Dim DestRec As DAO.Recordset
           
    
       ' Set the variables (change for environment).
       strSecurePathToDatabase = "C:\MyDatabases\Northwind.mdb"
       strSecurePathToWorkgroupFile = "C:\MyDatabases\Secured.mdw"
       strSecureUser = "Administrator"
       strSecurePwd = "password"
       strTempPathToDatabase = "C:\MyDatabases\Temp.mdb"
       strBackupPathToDatabase = "C:\MyDatabases\Backup.mdb"
       strLogPath = "C:\MyDatabases\Backup.log"
       
       ' Open the log file.
       Open strLogPath For Output As #1
       Print #1, Time, "Log file opened"
       Print #1, Time, "Variables set"
       
       ' Delete old files.
       If Dir(strTempPathToDatabase) <> "" Then Kill strTempPathToDatabase
       If Dir(strBackupPathToDatabase) <> "" Then Kill strBackupPathToDatabase
       Print #1, Time, "Old backup files deleted"
       
       ' Create the new temp database.
       Set wrkDefault = DBEngine.Workspaces(0)
       Set dbsNew = wrkDefault.CreateDatabase(strTempPathToDatabase, dbLangGeneral)
       Set dbsNew = Nothing
       Print #1, Time, "Temp database created"
       
       ' Open the secured database.
       Set dbeSecure = New PrivDBEngine
       dbeSecure.SystemDB = strSecurePathToWorkgroupFile
       dbeSecure.DefaultUser = strSecureUser
       dbeSecure.DefaultPassword = strSecurePwd
       
       Set wrkSecure = dbeSecure.Workspaces(0)
       Set dbsSecure = wrkSecure.OpenDatabase(strSecurePathToDatabase)
       Print #1, Time, "Secured database opened from " & strSecurePathToDatabase
       
       ' Open the temp database.
       DBEngine(0).CreateUser
       Set dbsTemp = DBEngine(0).OpenDatabase(strTempPathToDatabase)
       
       Print #1, Time, "Temp database opened from " & strTempPathToDatabase
       
       ' Loop through the tables in the secured database.
       For Each tdfSecure In dbsSecure.TableDefs
           strTableName = tdfSecure.Name
           If Left(strTableName, 4) <> "MSys" Then
               Print #1, Time, "Export of " & strTableName
               ' Copy the table definition to the temp database.
               If CopyTableDef(tdfSecure, dbsTemp, strTableName) Then
                   ' Then append all the data into the table.
                    Set SourceRec = tdfSecure.OpenRecordset(dbOpenTable, dbReadOnly)
                    Set DestRec = dbsTemp.OpenRecordset(strTableName)
                    AppendRecordsFromOneRecordSetToAnother SourceRec, DestRec 
                    SourceRec.Close
                    DestRec.Close
    
               End If
           End If
       Next tdfSecure
    
       ' Close open objects.
       dbsSecure.Close
       Print #1, Time, "Secured database closed"
       dbsTemp.Close
       Print #1, Time, "Temp database closed"
           
       ' Compact the database into the backup database.
       DBEngine.CompactDatabase strTempPathToDatabase, strBackupPathToDatabase, dbLangGeneral
       Print #1, Time, "New backup database created at " & strBackupPathToDatabase
       
       ' Delete the temp database.
       If Dir(strTempPathToDatabase) <> "" Then Kill strTempPathToDatabase
       Print #1, Time, "Temp database deleted"
       Print #1, Time, "Log file closed"
       Close #1
    
    Exit_BackupSecureDatabase:
    
       Set wrkDefault = Nothing
       Set dbsNew = Nothing
       Set dbeSecure = Nothing
       Set wrkSecure = Nothing
       Set dbsSecure = Nothing
       Set tdfSecure = Nothing
       Set dbsTemp = Nothing
       Exit Function
    
    Err_BackupSecureDatabase:
       Print #1, Time, "     ***ERROR: " & Err.Number, Err.Description, strTableName
       Resume Next
    
    End Function
    
    
    Function CopyTableDef(SourceTableDef As TableDef, TargetDB As Database, TargetName As String) As Integer
    Dim SI As DAO.Index, SF As DAO.Field, SP As DAO.Property
    Dim T As DAO.TableDef, I As DAO.Index, F As DAO.Field, P As DAO.Property
    Dim I1 As Integer, f1 As Integer, P1 As Integer
      
      If SourceTableDef.Attributes And dbAttachedODBC Or SourceTableDef.Attributes And dbAttachedTable Then
        CopyTableDef = False
        Exit Function
      End If
      Set T = TargetDB.CreateTableDef(TargetName)
      
      ' Copy Jet Properties.
        On Error Resume Next
        For P1 = 0 To T.Properties.Count - 1
          If T.Properties(P1).Name <> "Name" Then
            T.Properties(P1).Value = SourceTableDef.Properties(P1).Value
          End If
        Next P1
        On Error GoTo 0
        
      ' Copy Fields.
        For f1 = 0 To SourceTableDef.Fields.Count - 1
          Set SF = SourceTableDef.Fields(f1)
          
          ' DAO 3.0 and later versions. ****
          If (SF.Attributes And dbSystemField) = 0 Then
            Set F = T.CreateField()
            ' Copy Jet Properties.
              On Error Resume Next
              For P1 = 0 To F.Properties.Count - 1
                F.Properties(P1).Value = SF.Properties(P1).Value
              Next P1
              On Error GoTo 0
            T.Fields.Append F
          End If ' Corresponding End If ****
        Next f1
        
      ' Copy Indexes.
        For I1 = 0 To SourceTableDef.Indexes.Count - 1
          Set SI = SourceTableDef.Indexes(I1)
          
          ' Foreign indexes are added by relationships.
          If Not SI.Foreign Then
            Set I = T.CreateIndex()
            ' Copy Jet Properties.
              On Error Resume Next
              For P1 = 0 To I.Properties.Count - 1
                I.Properties(P1).Value = SI.Properties(P1).Value
              Next P1
              On Error GoTo 0
            ' Copy Fields.
              For f1 = 0 To SI.Fields.Count - 1
                Set F = T.CreateField(SI.Fields(f1).Name, T.Fields(SI.Fields(f1).Name).Type)
                I.Fields.Append F
              Next f1
            T.Indexes.Append I
          End If
        Next I1
    
    ' Append TableDef.
      TargetDB.TableDefs.Append T
      
      ' Copy Access/User Table Properties.
        For P1 = T.Properties.Count To SourceTableDef.Properties.Count - 1
          Set SP = SourceTableDef.Properties(P1)
          Set P = T.CreateProperty(SP.Name, SP.Type)
          P.Value = SP.Value
          T.Properties.Append P
        Next P1
        
      ' Copy Access/User Field Properties.
        For f1 = 0 To T.Fields.Count - 1
          Set SF = SourceTableDef.Fields(f1)
          Set F = T.Fields(f1)
          For P1 = F.Properties.Count To SF.Properties.Count - 1
            Set SP = SF.Properties(P1)
            Set P = F.CreateProperty(SP.Name, SP.Type)
            P.Value = SP.Value
            F.Properties.Append P
          Next P1
        Next f1
        
      ' Copy Access/User Index Properties.
        For I1 = 0 To T.Indexes.Count - 1
          Set SI = SourceTableDef.Indexes(T.Indexes(I1).Name)
          
          ' Do not copy foreign indexes. They are created by relationships.
          If Not SI.Foreign Then
            Set I = T.Indexes(I1)
            For P1 = I.Properties.Count To SI.Properties.Count - 1
              Set SP = SI.Properties(P1)
              Set P = I.CreateProperty(SP.Name, SP.Type)
              P.Value = SP.Value
              I.Properties.Append P
            Next P1
          End If
        Next I1
      CopyTableDef = True
    End Function
    
    Function AppendRecordsFromOneRecordSetToAnother(SR As DAO.Recordset, DR As DAO.Recordset)
    Dim x As Integer
    
    Do While Not SR.EOF
    DR.AddNew
        For x = 0 To SR.Fields.Count - 1
            DR(x).Value = SR(x).Value
        Next x
    DR.Update
    SR.MoveNext
    Loop
    End Function
    
    Nota: el código intentará importar a una base de datos de copia de seguridad todas las tablas de la base de datos dañada. Reemplace las variables de la tabla después del paso 10 con las ubicaciones y las configuraciones de usuario de su archivo de base de datos.
  9. En la lista de funciones, seleccione BackupSecureDatabase.
  10. Para ejecutar el código, haga clic en Ejecutar Sub/UserForm en el menú Ejecutar.
Contraer esta tablaAmpliar esta tabla
VariableDescripción
strSecurePathToDatabaseUbicación de archivo de base de datos seguro
strSecurePathToWorkgroupFileUbicación del archivo de grupo de trabajo
strSecureUserNombre de inicio de sesión de usuario seguro
strSecurePwdContraseña de inicio de sesión de usuario segura
strTempPathToDatabaseUbicación del archivo temporal de base de datos
strBackupPathToDatabaseUbicación del archivo de copia de seguridad de la base de datos
strLogPathUbicación del archivo de registro

Estado

Microsoft ha confirmado que se trata de un problema de los productos de Microsoft enumerados en la sección "La información de este artículo se refiere a".

Más información

Para obtener más información acerca de cómo solucionar daños en una base de datos de Microsoft Access, haga clic en el número de artículo siguiente para verlo en Microsoft Knowledge Base:
306204  (http://support.microsoft.com/kb/306204/ ) Cómo solucionar problemas en una base de datos de Microsoft Access dañada

La información de este artículo se refiere a:
  • Microsoft Office Access 2007
  • Microsoft Office Access 2003
  • Microsoft Access 2002 Standard Edition
  • Microsoft Access 2000 Standard Edition
Palabras clave: 
kbcorrupt kbconversion kbimport kbinfo kbtshoot kbprb KB888634