Fehler „Die Datenbank befindet sich in einem unerwarteten Zustand“, wenn Sie eine Datenbank in Access öffnen

In diesem Artikel wird ein Problem behoben, das auftritt, wenn Sie eine Datenbank mithilfe der DAO-Bibliothek konvertieren.

Ursprüngliche KB-Nummer: 888634

Hinweis

Dieser Artikel bezieht sich auf eine Microsoft Access-Datenbankdatei (.MDB) oder eine Microsoft Access-Datenbankdatei (.ACCDB). Erfordert grundlegende Makro-, Codierungs- und Interoperabilitätskenntnisse.

Problembeschreibung

Wenn Sie versuchen, eine Datenbank unter Microsoft Access 2000 oder einer späteren Version zu öffnen, wird möglicherweise die folgende Fehlermeldung angezeigt:

Die Datenbank befindet sich in einem unerwarteten Zustand

Ursache

Dieses Problem kann auftreten, wenn Sie mithilfe der DAO-Bibliothek (Data Access Object) eine Datenbank konvertieren, die Sie mithilfe der CompactDatabase Methode in Microsoft Access 97 oder einer früheren Version erstellt haben. Die CompactDatabase Methode kann die neue Datenbank in einem teilweise konvertierten Zustand belassen.

Lösung

Verwenden Sie eine der folgenden Methoden, um das Problem zu beheben.

Methode 1: Verwenden Sie den Befehl „Datenbank konvertieren“, wenn Sie über die ursprüngliche Datenbank verfügen

Wenn Sie noch eine Kopie der ursprünglichen Datenbank im Originalformat haben, verwenden Sie den BefehlConvert Database. Gehen Sie dazu wie folgt vor:

Access 2000, Access 2002 oder Access 2003

  1. Erstellen Sie eine Sicherungskopie der ursprünglichen Datenbank.

  2. Starten Sie Access 2000 oder eine spätere Version.

  3. Im Menü Tools klicken Sie auf Datenbank-Hilfsprogramme, klicken Sie Datenbank konvertieren, und klicken Sie dann Zum Access 2000 Dateiformat.

    Hinweis

    Wenn Sie Access 2000 verwenden, wird im Menü Datenbank konvertieren nur zur aktuellen Access-Datenbankversion angezeigt.

  4. Im Dialogfeld Datenbank, von der konvertiert werden soll klicken Sie auf den Dateinamen der Datenbank, die Sie konvertieren wollen, und klicken dann auf Konvertieren.

  5. Geben Sie im Dialogfeld Datenbank konvertieren in den neuen Namen der Datenbankdatei ein, und klicken Sie dann auf Speichern.

Access 2007

  1. Erstellen Sie eine Sicherungskopie der ursprünglichen Datenbank.
  2. Versuchen Sie, diese Datenbank zu öffnen.
  3. Wenn Sie eine MDB-Datenbank im Access 97- oder Access 95-Dateiformat .mdb öffnen, zeigt Access das Dialogfeld Datenbankerweiterung an. Sie werden aufgefordert, die Datenbank zu aktualisieren.
  4. Klicken Sie auf Ja, um die Datenbank auf das Dateiformat zu aktualisieren, das Sie in Access 2007 als Standarddateiformat ausgewählt haben. Nachdem Sie die Datenbank konvertiert haben, können Sie in Access 2007 Entwurfsänderungen an der Datei vornehmen. Sie können die Datenbank jedoch nicht mehr mit einer früheren Version von Access öffnen als mit der, in die Sie die Datenbank konvertiert haben.

Methode 2: Wiederherstellen der Datenbankdaten und der Datenbankabfragen, wenn Sie nicht über die ursprüngliche Datenbank ohne Sicherung verfügen

Wenn Sie keine Kopie der ursprünglichen nicht gesicherten Datenbank im Originalformat haben und die standardmäßigen Verfahren zur Problembehandlung bei Beschädigungen ausprobiert haben, versuchen Sie, die Datenbankdaten und die Datenbankabfragen wiederherzustellen. Gehen Sie dazu wie folgt vor:

  1. Erstellen Sie eine Sicherungskopie der ursprünglichen Datenbank.

  2. Starten Sie Access 2000 oder eine spätere Version.

  3. Access 2000, Access 2002 oder Access 2003

    • Klicken Sie auf Leere Access-Datenbank, geben Sie den neuen Datenbanknamen in das Feld „Dateiname“ ein, und klicken Sie dann auf Erstellen.

    Access 2007

    • Klicken Sie auf Office-Schaltfläche, klicken Sie auf Neu, auf Leere Datenbank und dann auf Erstellen, um eine neue leere Datenbank zu erstellen.
  4. Access 2000, Access 2002 oder Access 2003

    • Klicken Sie im Menü Einfügen auf Modul. Der Microsoft Visual Basic-Editor wird gestartet, und es wird ein neues Modul erstellt.

    Access 2007

    • Klicken Sie auf der Registerkarte Erstellen auf den Pfeil nach unten unterhalb des Makros, und klicken Sie dann auf Modul. Der Microsoft Visual Basic-Editor wird gestartet, und es wird ein neues Modul erstellt.
  5. Klicken Sie im Menü Extras auf Verweise.

  6. Suchen Sie in der Liste Verfügbare Verweise nach der Microsoft DAO 3.6-Objektbibliothek, und setzen Sie einen Haken in das Kontrollkästchen Microsoft DAO 3.6-Objektbibliothek.

    Hinweis

    DAO 3.6 ist auch auf Windows XP Home Edition verfügbar.

  7. Um das Dialogfeld Verweise zu schließen, klicken Sie auf OK.

  8. Fügen Sie den folgenden Code in das neue Modul ein, das Sie erstellt haben.

    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
    

    Hinweis

    Der Code versucht, alle Tabellen und alle Abfragen aus der beschädigten Datenbank in die aktuelle Datenbank zu importieren. Ersetzen Sie C:\My Documents\yourDatabase.mdb durch den korrekten Pfad und Dateinamen Ihrer Datenbank.

  9. Klicken Sie zum Ausführen des Codes im Menü Ausführen auf Sub/UserForm ausführen.

Methode 3: Wiederherstellen der Datenbankdaten, wenn Sie nicht über die ursprüngliche gesicherte Datenbank verfügen

Wenn Sie nicht über eine Kopie der ursprünglichen gesicherten Datenbank im Originalformat verfügen und Sie die standardmäßigen Verfahren zur Problembehandlung bei Beschädigungen ausprobiert haben, versuchen Sie, die Datenbankdaten wiederherzustellen. Gehen Sie dazu wie folgt vor:

  1. Erstellen Sie eine Sicherungskopie der ursprünglichen Datenbank.

  2. Starten Sie Access 2000 oder eine spätere Version.

  3. Access 2000, Access 2002 oder Access 2003

    • Klicken Sie auf Leere Access-Datenbank, geben Sie den neuen Datenbanknamen in das Feld „Dateiname“ ein, und klicken Sie dann auf Erstellen.

    Access 2007

    • Klicken Sie auf die Microsoft Office-Schaltfläche, klicken Sie auf Neu, klicken Sie auf Leere Datenbank und dann auf Erstellen, um eine neue leere Datenbank zu erstellen.
  4. Access 2000, Access 2002 oder Access 2003

    • Klicken Sie im Menü Einfügen auf Modul. Der Microsoft Visual Basic-Editor wird gestartet, und es wird ein neues Modul erstellt.

    Access 2007

    • Klicken Sie auf der Registerkarte Erstellen auf den Pfeil nach unten unterhalb des Makros, und klicken Sie dann auf Modul. Der Microsoft Visual Basic-Editor wird gestartet, und es wird ein neues Modul erstellt.
  5. Klicken Sie im Menü Extras auf Verweise.

  6. Suchen Sie in der Liste Verfügbare Verweise nach der Microsoft DAO 3.6-Objektbibliothek, und setzen Sie einen Haken in das Kontrollkästchen Microsoft DAO 3.6-Objektbibliothek.

  7. Um das Dialogfeld Verweise zu schließen, klicken Sie auf OK.

  8. Fügen Sie den folgenden Code in das neue Modul ein, das Sie erstellt haben.

    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
    

    Hinweis

    Der Code versucht, alle Tabellen aus der beschädigten Datenbank in eine Sicherungsdatenbank zu importieren. Ersetzen Sie die Variablen in der Tabelle nach Schritt 10 durch die Speicherorte der Datenbankdateien und die Benutzereinstellungen.

  9. Wählen Sie in der Liste der Funktionen BackupSecureDatabase aus.

  10. Klicken Sie zum Ausführen des Codes im Menü Ausführen auf Sub/UserForm ausführen.

    Variable Beschreibung
    strSecurePathToDatabase Speicherort der gesicherten Datenbankdatei
    strSecurePathToWorkgroupFile Speicherort der Arbeitsgruppendatei
    strSecureUser Gesicherter Benutzeranmeldename
    strSecurePwd Gesichertes Benutzeranmeldekennwort
    strTempPathToDatabase Speicherort der temporären Datenbankdatei
    strBackupPathToDatabase Speicherort der Sicherungsdatenbankdatei
    strLogPath Screenshot einer Protokolldatei

Status

Microsoft hat bestätigt, dass es sich hierbei um ein Problem bei den in diesem Artikel genannten Microsoft-Produkten handelt.

Weitere Informationen

Weitere Informationen zur Problembehandlung bei einer beschädigten Microsoft Access-Datenbank finden Sie in folgendem Artikel:

Komprimieren und Reparieren einer Datenbank