Felet "Databasen är i ett oväntat tillstånd" när du öppnar en databas i Access

I den här artikeln åtgärdas ett problem som uppstår när du använder DAO-biblioteket för att konvertera en databas.

Anteckning

Office 365 ProPlus byter namn till Microsoft 365-appar för företag. Mer information om den här ändringen finns i det här blogginlägget.

Ursprungligt KB-nummer:   888634

Anteckning

Den här artikeln gäller en Microsoft Access-databasfil (.mdb) eller en Microsoft Access-databasfil (.accdb). Kräver grundläggande kunskaper i makro, kodning och interoperabilitet.

Symptom

När du försök försök försök försök att ör en databas i Microsoft Access 2000 eller en senare version visas fö1 ã¶tkomstmeddelandet:

Databasen är i ett oväntat tillstånd

Orsak

Det här problemet kan uppstÃ¥ när du använder DAO-biblioteket (Data Access Object) fÃ¥r fär konvertera en databas som du skapade i Microsoft Access 97 eller en tidigare version med CompactDatabase metoden. CompactDatabaseMetoden kan lämna den nya databasen i ett delvis konverterat tillstånd.

Lösning

Lös problemet genom att an㥠¥

Metod 1: Använd kommandot Konvertera databas när du har den ursprungliga databasen

Om du fortfarande har en kopia av den ursprungliga databasen i dess ursprungliga format använder du Convert Database kommandot. Gör så här:

Access 2000, Access 2002 eller Access 2003

  1. Gör en säkerhetskopia av den ursprungliga databasen.

  2. Starta Access 2000 eller en senare version.

  3. Klicka på DatabasverktygVerktyg-menyn, klicka på Konvertera databasoch klicka sedan på Till Access 2000-filformat.

    Anteckning

    Om du använder Access 2000 visas bara till aktuell access-databasversionmenyn Konvertera databas.

  4. Klicka på det databasfilnamn som du vill konvertera i dialogrutan Databas att konvertera från och klicka sedan på Konvertera.

  5. Skriv det nya namnet på databasfilen i dialogrutan Konvertera databas till och klicka sedan på Spara.

Tillgång 2007

  1. Gör en säkerhetskopia av den ursprungliga databasen.
  2. Försök att öppna databasen.
  3. När du öppnar en MDB-databas med Access 97- eller Access 95-filformat visas dialogrutan Databasförbättring. Du uppmanas att uppgradera databasen.
  4. Klicka på Ja om du vill uppgradera databasen till vilket filformat du har valt som standardfilformat i Access 2007. När du har konverterat databasen kan du göra designändringar i filen i Access 2007. Du kan dock inte längre öppna databasen med hjälp av en tidigare version av Access än den version som du konverterade databasen till.

Metod 2: Återställa databasdata och databasfrågor när du inte har den ursprungliga icke-citerade databasen

Om du inte har en kopia av den ursprungliga icke-ade databasen i sitt ursprungliga format och du har provat standardteknik för felsökning av korruption kan du försöka återställa databasdata och databasfrågor. Gör så här:

  1. Gör en säkerhetskopia av den ursprungliga databasen.

  2. Starta Access 2000 eller en senare version.

  3. Access 2000, Access 2002 eller Access 2003

    • Klicka på Tom Access-databas, skriv det nya databasnamnet i rutan Filnamn och klicka sedan på Skapa.

    Tillgång 2007

    • Klicka på Knappen Office, klicka på Ny, klicka på Tom databasoch sedan på Skapa för att skapa en ny tom databas.
  4. Access 2000, Access 2002 eller Access 2003

    • Klicka på ModulInfoga-menyn . Microsoft Visual Basic Editor startar och en ny modul skapas.

    Tillgång 2007

    • Klicka på nedpilen under Makropå fliken Skapa och klicka sedan på Modul. Microsoft Visual Basic Editor startar och en ny modul skapas.
  5. Klicka på ReferenserVerktyg-menyn .

  6. Leta reda på Microsoft DAO 3.6-objektbiblioteki listan Tillgängliga referenser och markera sedan kryssrutan Microsoft DAO 3.6-objektbibliotek.

    Anteckning

    DAO 3.6 finns också på Windows XP Home Edition.

  7. Om du vill stänga dialogrutan Referenser klickar du på OK.

  8. Klistra in följande kod i den nya modulen som du skapade.

    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
    

    Anteckning

    Koden försöker importera alla tabeller och alla frågor från den skadade databasen till den aktuella databasen. Ersätt C:\My Documents\yourDatabase.mdb med databasens rätta sökväg och filnamn.

  9. Om du vill köra koden klickar du på Kör under-/användarformulärKör-menyn.

Metod 3: Återställa databasdata när du inte har den ursprungliga skyddade databasen

Om du inte har en kopia av den ursprungliga skyddade databasen i sitt ursprungliga format och du har provat standardteknik för felsökning av korruption kan du försöka återställa databasdata. Gör så här:

  1. Gör en säkerhetskopia av den ursprungliga databasen.

  2. Starta Access 2000 eller en senare version.

  3. Access 2000, Access 2002 eller Access 2003

    • Klicka på Tom Access-databas, skriv det nya databasnamnet i rutan Filnamn och klicka sedan på Skapa.

    Tillgång 2007

    • Klicka på Microsoft Office-knappen, klicka på Ny, klicka på Tom databasoch sedan på Skapa för att skapa en ny tom databas.
  4. Access 2000, Access 2002 eller Access 2003

    • Klicka på ModulInfoga-menyn . Microsoft Visual Basic Editor startar och en ny modul skapas.

    Tillgång 2007

    • Klicka på nedpilen under Makropå fliken Skapa och klicka sedan på Modul. Microsoft Visual Basic Editor startar och en ny modul skapas.
  5. Klicka på ReferenserVerktyg-menyn .

  6. Leta reda på Microsoft DAO 3.6-objektbiblioteki listan Tillgängliga referenser och markera sedan kryssrutan Microsoft DAO 3.6-objektbibliotek.

  7. Om du vill stänga dialogrutan Referenser klickar du på OK.

  8. Klistra in följande kod i den nya modulen som du skapade.

    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
    

    Anteckning

    Koden försöker importera alla tabeller från den skadade databasen till en säkerhetskopia. Ersätt variablerna i tabellen efter steg 10 med databasfilsplatserna och användarinställningarna.

  9. Välj BackupSecureDatabasei listan över funktioner .

  10. Om du vill köra koden klickar du på Kör under-/användarformulärKör-menyn.

    Variabel Beskrivning
    strSecurePathToDatabase Plats för säker databasfil
    strSecurePathToWorkgroupFile Plats för arbetsgruppsfil
    strSecureUser Skyddat användarnamn
    strSecurePwd Lösenord för säker inloggning för användare
    strTempPathToDatabase Plats för temporär databasfil
    strBackupPathToDatabase Plats för databasfil för säkerhetskopiering
    strLogPath Plats för loggfilen

Status

Microsoft har bekräftat att detta är ett problem i Microsoft-produkterna som anges i avsnittet "Gäller" .

Mer information

Mer information om felsökning av skador i en Microsoft Access-databas finns i följande artikel:

Komprimera och reparera en databas