Błąd "Baza danych znajduje się w nieoczekiwanym stanie" podczas otwierania bazy danych w programie Access
W tym artykule przedstawiono rozwiązanie problemu, który występuje, gdy używasz biblioteki obiektów DAO do konwertowania bazy danych.
Oryginalny numer KB: 888634
Uwaga
Ten artykuł dotyczy pliku bazy danych programu Microsoft Access (.mdb) lub pliku bazy danych programu Microsoft Access (.accdb). Wymaga podstawowych umiejętności w zakresie makr, kodowania i współdziałania.
Symptomy
Podczas próby otwarcia bazy danych programu Microsoft Access 2000 lub jego starszych wersji, jest zwracany następujący komunikat o błędzie:
Baza danych znajduje się w nieoczekiwanym stanie
Przyczyna
Ten problem może wystąpić, gdy korzystasz z biblioteki obiektów Data Access Object (DAO) w celu przekonwertowania bazy danych utworzonej w programie Microsoft Access 97 lub w starszej jego wersji przy użyciu metodyCompactDatabase
. Metoda CompactDatabase
może spowodować pozostawienie nowej bazy danych w stanie częściowego przekonwertowania.
Rozwiązanie
Aby rozwiązać ten problem, skorzystaj z jednej z następujących metod.
Metoda nr 1: Używanie polecenia "Konwertuj bazę danych", jeśli masz oryginalną bazę danych
Jeśli nadal masz kopię oryginalnej bazy danych w oryginalnym formacie, użyj poleceniaConvert Database
. Aby to zrobić, wykonaj następujące kroki.
Access 2000, Access 2002 lub Access 2003
Wykonaj kopię zapasową oryginalnej bazy danych.
Wymaga uruchomienia programu Access 2000 lub jego nowszej wersji.
W menu Narzędzia kliknij polecenie Narzędzia bazy danych, kliknij polecenie Konwertuj bazę danych, a następnie kliknij polecenie Aby uzyskać format pliku programu Access 2000.
Uwaga
Jeśli korzystasz z programu Access 2000, w menu Konwertuj bazę danych jest wyświetlana tylko opcja Do bieżącej wersji bazy danych programu Access.
W oknie dialogowym Baza danych, z której wykonywana jest konwersja kliknij nazwę pliku bazy danych, który chcesz przekonwertować, a następnie kliknij przycisk Konwertuj.
W oknie dialogowym Konwertuj bazę danych do wpisz nazwę nowego pliku bazy danych, a następnie kliknij przycisk Zapisz.
Access 2007
- Wykonaj kopię zapasową oryginalnej bazy danych.
- Spróbuj otworzyć tę bazę danych.
- Po otwarciu bazy danych w formacie pliku .mdb programu Access 97 lub Access 95 program Access wyświetla okno dialogowe Rozszerzenie bazy danych. Zostanie wyświetlony monit o uaktualnienie bazy danych.
- Kliknij przycisk Tak, aby zaktualizować bazę danych do formatu pliku wybranego jako domyślny w programie Access 2007. Po przekonwertowaniu bazy danych można wprowadzić zmiany w projekcie pliku w programie Access 2007. Bazy danych nie można już jednak otworzyć przy użyciu wersji programu Access wcześniejszej niż wersja, na którą przekonwertowano bazę danych.
Metoda nr 2: Odzyskiwanie danych bazy danych i zapytań bazy danych, gdy nie ma oryginalnej niezabezpieczonej bazy danych
Jeśli nie masz kopii oryginalnej niezabezpieczonej bazy danych w oryginalnym formacie i zostały wypróbowane standardowe techniki rozwiązywania problemów z uszkodzeniem, spróbuj odzyskać dane bazy danych i zapytania bazy danych. Aby to zrobić, wykonaj następujące kroki.
Wykonaj kopię zapasową oryginalnej bazy danych.
Wymaga uruchomienia programu Access 2000 lub jego nowszej wersji.
Access 2000, Access 2002 lub Access 2003
- Kliknij pozycję Pusta baza danych programu Access, wpisz nową nazwę bazy danych w polu Nazwa pliku, a następnie kliknij przycisk Utwórz.
Access 2007
- Kliknij przycisk "Office", następnie kliknij pozycję Nowa, kliknij pozycjęPusta baza danych, a następnie kliknij pozycję Utwórz, aby utworzyć nową pustą bazę danych.
Access 2000, Access 2002 lub Access 2003
- W menu Insert (Wstaw) kliknij polecenie Module (Moduł). Zostanie uruchomiony edytor Visual Basic i zostanie utworzony nowy moduł.
Access 2007
- Na karcie Utwórz kliknij strzałkę w dół pod przyciskiem Makro, a następnie kliknij pozycję Moduł. Zostanie uruchomiony edytor Visual Basic i zostanie utworzony nowy moduł.
W menu Narzędzia kliknij polecenie Odwołania.
Na liście Dostępne odwołania znajdź pozycję Biblioteka obiektów platformy Microsoft DAO 3.6, a następnie kliknij, aby zaznaczyć pole wyboru Biblioteka obiektów platformy Microsoft DAO 3.6.
Uwaga
Baza obiektów DAO 3.6 jest również dostępny na system Windows XP Home Edition.
Aby zamknąć okno dialogowe Odwołania, kliknij przycisk OK.
Wklej poniższy kod do nowo utworzonego modułu.
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
Uwaga
Kod ten spróbuje zaimportować wszystkie tabele i wszystkie zapytania z uszkodzonej bazy danych do bieżącej bazy danych. Zamień ścieżkę
C:\My Documents\yourDatabase.mdb
na poprawną ścieżkę i nazwę pliku bazy danych.Aby uruchomić kod, kliknij polecenie Uruchom podformularz/formularz użytkownika w menu Uruchom.
Metoda nr 3: Odzyskiwanie danych bazy danych, jeśli nie masz oryginalnej zabezpieczonej bazy danych
Jeśli nie masz kopii oryginalnej zabezpieczonej bazy danych w oryginalnym formacie i zostały wypróbowane standardowe techniki rozwiązywania problemów z uszkodzeniami, spróbuj odzyskać dane bazy danych. Aby to zrobić, wykonaj następujące kroki.
Wykonaj kopię zapasową oryginalnej bazy danych.
Wymaga uruchomienia programu Access 2000 lub jego nowszej wersji.
Access 2000, Access 2002 lub Access 2003
- Kliknij pozycję Pusta baza danych programu Access, wpisz nową nazwę bazy danych w polu Nazwa pliku, a następnie kliknij przycisk Utwórz.
Access 2007
- Kliknij przycisk Microsoft Office, kliknij pozycję Nowa, kliknij pozycję Pusta baza danych, a następnie kliknij pozycję Utwórz, aby utworzyć nową pustą bazę danych.
Access 2000, Access 2002 lub Access 2003
- W menu Insert (Wstaw) kliknij polecenie Module (Moduł). Zostanie uruchomiony edytor Visual Basic i zostanie utworzony nowy moduł.
Access 2007
- Na karcie Utwórz kliknij strzałkę w dół pod przyciskiem Makro, a następnie kliknij pozycję Moduł. Zostanie uruchomiony edytor Visual Basic i zostanie utworzony nowy moduł.
W menu Narzędzia kliknij polecenie Odwołania.
Na liście Dostępne odwołania znajdź pozycję Biblioteka obiektów platformy Microsoft DAO 3.6, a następnie kliknij, aby zaznaczyć pole wyboru Biblioteka obiektów platformy Microsoft DAO 3.6.
Aby zamknąć okno dialogowe Odwołania, kliknij przycisk OK.
Wklej poniższy kod do nowo utworzonego modułu.
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
Uwaga
Kod ten spróbuje zaimportować wszystkie tabele z uszkodzonej bazy danych do zapasowej bazy danych. Zastąp zmienne w tabeli po kroku nr 10 lokalizacjami plików bazy danych i ustawieniami użytkownika.
Na liście funkcji wybierz pozycję BackupSecureDatabase.
Aby uruchomić kod, kliknij polecenie Uruchom podformularz/formularz użytkownika w menu Uruchom.
Zmienna Opis strSecurePathToDatabase
Lokalizacja zabezpieczonego pliku bazy danych strSecurePathToWorkgroupFile
Lokalizacja pliku grupy roboczej strSecureUser
Zabezpieczona nazwa logowania użytkownika strSecurePwd
Zabezpieczone hasło logowania użytkownika strTempPathToDatabase
Lokalizacja pliku tymczasowej bazy danych strBackupPathToDatabase
Lokalizacja pliku kopii zapasowej bazy danych strLogPath
Lokalizacja pliku dziennika
Stan
Firma Microsoft potwierdziła, że jest to usterka występująca w produktach firmy Microsoft wymienionych w części "Ma zastosowanie do:".
Więcej informacji
Aby uzyskać więcej informacji na temat rozwiązywania problemów z uszkodzeniami bazy danych programu Microsoft Access, zobacz następujący artykuł:
Opinia
https://aka.ms/ContentUserFeedback.
Już wkrótce: w ciągu 2024 r. będziemy stopniowo usuwać problemy z usługą GitHub jako mechanizm opinii na temat zawartości i zastępować go nowym systemem opinii. Aby uzyskać więcej informacji, sprawdź:Prześlij i wyświetl opinię dla