Chyba „databáze je v neočekávaném stavu“ při otevření databáze v aplikaci Access
Tento článek řeší problém, ke kterému dochází při použití knihovny DAO k převodu databáze.
Původní číslo KB: 888634
Poznámka
Tento článek se týká souboru databáze Microsoft Access (MDB) nebo souboru databáze Microsoft Access (.accdb). Vyžaduje základní dovednosti v oblasti maker, kódování a vzájemné spolupráce.
Příznaky
Při pokusu o otevření databáze v aplikaci Microsoft Access 2000 nebo novější verzi se zobrazí následující chybová zpráva:
Databáze je v neočekávaném stavu.
Příčina
K tomuto problému může dojít při použití knihovny Data Access Object (DAO) k převodu databáze vytvořené v aplikaci Microsoft Access 97 nebo dřívější verzi pomocí metodyCompactDatabase
. Metoda CompactDatabase
může ponechat novou databázi v částečně převedeném stavu.
Řešení
Pro vyřešení tohoto problému použijte jednu z následujících metod:
Metoda 1: Použijte příkaz Převést databázi, pokud máte původní databázi
Pokud stále máte kopii původní databáze v původním formátu, použijte příkazConvert Database
. Postupujte takto:
Access 2000, Access 2002 nebo Access 2003
Vytvořte záložní kopii původní databáze.
Spusťte Access 2000 nebo novější verzi.
V nabídce Nástroje klikněte na Správa databáze, klikněte na Převést databázi a poté klikněte na Do formátu souboru aplikace Access 2000.
Poznámka
Pokud používáte Access 2000, v nabídce Převést databázi se zobrazí pouze Na databázi aktuální verze aplikace Access.
V dialogovém okně Zdrojová databáze pro převod klikněte na název souboru databáze, který chcete převést, a poté klikněte na Převést.
V dialogovém okně Převést databázi na zadejte nový název souboru databáze a klikněte na tlačítko Uložit.
Access 2007
- Vytvořte záložní kopii původní databáze.
- Zkuste tuto databázi otevřít.
- Když otevřete databázi ve formátu souboru aplikace Access 97 nebo Access 95 .mdb, Access zobrazí dialogové okno Zlepšení databáze. Zobrazí se výzva k upgradu databáze.
- Kliknutím na Ano upgradujete databázi na libovolný formát souboru, který jste vybrali jako výchozí formát souboru v aplikaci Access 2007. Po převedení databáze můžete v aplikaci Access 2007 provést změny návrhu souboru. Databázi však již nemůžete otevřít pomocí starší verze aplikace Access, než na kterou jste databázi převedli.
Metoda 2: Obnovení dat databáze a databázových dotazů, pokud nemáte původní nezabezpečenou databázi
Pokud nemáte kopii původní nezabezpečené databáze v původním formátu a vyzkoušeli jste standardní techniky odstraňování problémů s poškozením, pokuste se obnovit data databáze a databázové dotazy. Postupujte takto:
Vytvořte záložní kopii původní databáze.
Spusťte Access 2000 nebo novější verzi.
Access 2000, Access 2002 nebo Access 2003
- Klikněte na Prázdná databáze aplikace Access, zadejte název nové databáze do pole Název souboru a poté klikněte na Vytvořit.
Access 2007
- Klikněte na tlačítko Office, klikněte na Nový, klikněte na Prázdná databáze a poté kliknutím na Vytvořit vytvořte novou prázdnou databázi.
Access 2000, Access 2002 nebo Access 2003
- V nabídce Vložit klikněte na položku Modul. Spustí se Visual Basic Editor a vytvoří se nový modul.
Access 2007
- Na kartě Vytvořit klikněte na šipku dolů pod položkou Makro a poté klikněte na Modul. Spustí se Visual Basic Editor a vytvoří se nový modul.
V nabídce Nástroje klikněte na Odkazy.
V seznamu Dostupné odkazy vyhledejte Microsoft DAO 3.6 Object Library a poté kliknutím zaškrtněte políčko Microsoft DAO 3.6 Object Library.
Poznámka
DAO 3.6 je k dispozici také v systému Windows XP Home Edition.
Chcete-li zavřít dialogové okno Odkazy, klikněte na tlačítko OK.
Do nového modulu, který jste vytvořili, vložte následující kód.
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
Poznámka
Kód se pokusí importovat všechny tabulky a všechny dotazy z poškozené databáze do aktuální databáze. Nahraďte
C:\My Documents\yourDatabase.mdb
správnou cestou a názvem souboru vaší databáze.Pro spuštění kódu klikněte na Spustit Sub/UserForm v nabídce Spustit.
Metoda 3: Obnovení dat databáze, pokud nemáte původní zabezpečenou databázi
Pokud nemáte kopii původní zabezpečené databáze v původním formátu a vyzkoušeli jste standardní techniky odstraňování problémů s poškozením, pokuste se obnovit data databáze. Postupujte takto:
Vytvořte záložní kopii původní databáze.
Spusťte Access 2000 nebo novější verzi.
Access 2000, Access 2002 nebo Access 2003
- Klikněte na Prázdná databáze aplikace Access, zadejte název nové databáze do pole Název souboru a poté klikněte na Vytvořit.
Access 2007
- Klikněte na tlačítko Microsoft Office, klikněte na Nový, poté na Prázdná databáze a poté kliknutím na Vytvořit vytvořte novou prázdnou databázi.
Access 2000, Access 2002 nebo Access 2003
- V nabídce Vložit klikněte na položku Modul. Spustí se Visual Basic Editor a vytvoří se nový modul.
Access 2007
- Na kartě Vytvořit klikněte na šipku dolů pod položkou Makro a poté klikněte na Modul. Spustí se Visual Basic Editor a vytvoří se nový modul.
V nabídce Nástroje klikněte na Odkazy.
V seznamu Dostupné odkazy vyhledejte Microsoft DAO 3.6 Object Library a poté kliknutím zaškrtněte políčko Microsoft DAO 3.6 Object Library.
Chcete-li zavřít dialogové okno Odkazy, klikněte na tlačítko OK.
Do nového modulu, který jste vytvořili, vložte následující kód.
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
Poznámka
Kód se pokusí importovat všechny tabulky z poškozené databáze do záložní databáze. Proměnné v tabulce nahraďte po kroku 10 umístěním souborů databáze a uživatelským nastavením.
V seznamu funkcí vyberte BackupSecureDatabase.
Pro spuštění kódu klikněte na Spustit Sub/UserForm v nabídce Spustit.
Proměnná Popis strSecurePathToDatabase
Umístění zabezpečeného souboru databáze strSecurePathToWorkgroupFile
Umístění souboru pracovní skupiny strSecureUser
Zabezpečené přihlašovací jméno uživatele strSecurePwd
Zabezpečené přihlašovací heslo uživatele strTempPathToDatabase
Umístění dočasného souboru databáze strBackupPathToDatabase
Umístění záložního souboru databáze strLogPath
Umístění souboru protokolu
Stav
Společnost Microsoft potvrzuje, že se jedná o problém v produktech této společnosti, které jsou uvedeny v části Informace v tomto článku jsou určeny pro produkt.
Další informace
Další informace o řešení potíží s poškozením databáze aplikace Microsoft Access najdete v následujícím článku:
Váš názor
https://aka.ms/ContentUserFeedback.
Připravujeme: V průběhu roku 2024 budeme postupně vyřazovat problémy z GitHub coby mechanismus zpětné vazby pro obsah a nahrazovat ho novým systémem zpětné vazby. Další informace naleznete v tématu:Odeslat a zobrazit názory pro