Ошибка «База данных находится в неожиданном состоянии» при открытии базы данных в Access
В этой статье описывается устранение проблемы, возникающей при использовании библиотеки DAO для преобразования базы данных.
Оригинальный номер базы знаний: 888634
Примечание.
Эта статья применима к файлам баз данных Microsoft Access (.mdb) или (.accdb). Требуются базовые навыки работы с кодом, макросами и взаимодействия.
Симптомы
При попытке открыть базу данных с помощью Microsoft Access 2000 или более новой версии, появляется следующее сообщение об ошибке:
База данных находится в неожиданном состоянии
Причина
Эта проблема может возникнуть при использовании библиотеки объектов доступа к данным (DAO) для преобразовании базы данных, созданных в Microsoft Access 97 или более старой версии с помощью методаCompactDatabase
. При использовании метода CompactDatabase
новая база данных может может остаться в частично преобразованном состоянии.
Решение
Для решения этой проблемы воспользуйтесь одним из описанных ниже способов.
Метод 1. Используйте команду «Преобразовать базу данных» при наличии исходной базы данных.
При наличии копии исходной базы данных в начальном формате, используйте командуConvert Database
. Для этого выполните следующие действия:
Access 2000, Access 2002 и Access 2003
Сделайте резервную копию исходной базы данных.
Запустите Access 2000 или более поздней версии.
В меню Инструменты щелкните Служебные программы, выберите Преобразовать базу данных и нажмите В формат Access 2000.
Примечание.
При использовании Access 2000 в меню Преобразовать базу данных отображается только параметр К текущей версии базы данных Access.
В диалоговом окне База данных для преобразования нажмите название файла базы данных, который необходимо преобразовать, и нажмите Преобразовать.
В диалоговом окне Преобразовать базу данных введите название нового файла базы данных и нажмите Сохранить.
Access 2007
- Сделайте резервную копию исходной базы данных.
- Попробуйте открыть эту базу данных.
- При открытии .mdb-файла базы данных Access 97 или Access 95 приложение отображает диалоговое окно Улучшение базы данных. Предлагается обновление базы данных.
- Нажмите Да, чтобы обновить базу данных до файлового формата, выбранного по умолчанию в Access 2007. После преобразования базы данных в Access 2007 можно внести изменения в файл. Однако открыть базу данных с помощью Access более старой версии, чем та, в которую была преобразована база данных, невозможно.
Метод 2. Восстановление базы данных и запросов базы данных при отсутствии исходной незащищенной базы данных
При отсутствии копии исходной незащищенной базы данных в начальном формате и невозможности устранить неполадки, связанные с повреждениями, с помощью стандартных техник, можно попытаться восстановить данные и запросы базы данных. Для этого выполните следующие действия:
Сделайте резервную копию исходной базы данных.
Запустите Access 2000 или более поздней версии.
Access 2000, Access 2002 и Access 2003
- Щелкните Пустая база данных Access, введите название новой базы данных в поле Имя файла и нажмите Создать.
Access 2007
- Нажмите кнопку Office, выберите Создать, щелкните Пустая база данных и выберите Создать, чтобы создать новую пустую базу данных.
Access 2000, Access 2002 и Access 2003
- В меню Вставка выберите пункт Модуль. Откроется редактор Microsoft Visual Basic и создается новый модуль.
Access 2007
- На вкладке Создать щелкните стрелку под Макрос и нажмите Модуль. Откроется редактор Microsoft Visual Basic и создается новый модуль.
В меню Сервис выберите пункт Ссылки.
В списке Доступные ссылки найдите Библиотека объектов Microsoft DAO 3.6, а затем щелкните, чтобы выбрать флажок Библиотека объектов Microsoft DAO 3.6.
Примечание.
DAO 3.6 также поддерживается на системах под управлением Windows XP Home Edition.
Чтобы закрыть диалоговое окно Ссылки, нажмите кнопку ОК.
Вставьте следующий код в созданный модуль.
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
Примечание.
Код попытается импортировать все таблицы и запросы из поврежденной базы данных в новую. Замените
C:\My Documents\yourDatabase.mdb
на правильный путь и имя файла базы данных.Чтобы запустить код, нажмите Запустить подпрограмму/пользовательскую форму в меню Запустить.
Метод 3. Восстановление данных базы данных при отсутствии исходной защищенной базы данных.
При отсутствии копии исходной защищенной базы данных в начальном формате и невозможности устранить неполадки, связанные с повреждением, с помощью стандартных техник, можно попытаться восстановить данные базы данных. Для этого выполните следующие действия:
Сделайте резервную копию исходной базы данных.
Запустите Access 2000 или более поздней версии.
Access 2000, Access 2002 и Access 2003
- Щелкните Пустая база данных Access, введите название новой базы данных в поле Имя файла и нажмите Создать.
Access 2007
- Нажмите кнопку Microsoft Office, выберите Создать, щелкните Пустая база данных и нажмите Создать, чтобы создать новую пустую базу данных.
Access 2000, Access 2002 и Access 2003
- В меню Вставка выберите пункт Модуль. Откроется редактор Microsoft Visual Basic и создается новый модуль.
Access 2007
- На вкладке Создать щелкните стрелку под Макрос и нажмите Модуль. Откроется редактор Microsoft Visual Basic и создается новый модуль.
В меню Сервис выберите пункт Ссылки.
В списке Доступные ссылки найдите Библиотека объектов Microsoft DAO 3.6, а затем щелкните, чтобы выбрать флажок Библиотека объектов Microsoft DAO 3.6.
Чтобы закрыть диалоговое окно Ссылки, нажмите кнопку ОК.
Вставьте следующий код в созданный модуль.
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
Примечание.
Код попытается импортировать все таблицы из поврежденной базы данных в резервную копию базу данных. После 10 шага в таблице необходимо заменить значения переменных, указав расположения файлов базы данных и пользовательские настройки.
В списке функций выберите BackupSecureDatabase.
Чтобы запустить код, нажмите Запустить подпрограмму/пользовательскую форму в меню Запустить.
Переменная Описание strSecurePathToDatabase
Расположение защищенного файла базы данных strSecurePathToWorkgroupFile
Расположение файла рабочей группы strSecureUser
Защищенное имя пользователя для входа в систему strSecurePwd
Защищенный пароль пользователя для входа в систему strTempPathToDatabase
Расположение временного файла базы данных strBackupPathToDatabase
Расположение файла резервной копи базы данных strLogPath
Расположение файла журнала
Состояние
Данное поведение является подтвержденной ошибкой продуктов Майкрософт, перечисленных в разделе «Применимо к».
Дополнительная информация
Дополнительные сведения об устранении неполадок повреждения баз данных Microsoft Access см. в следующей статье:
Обратная связь
https://aka.ms/ContentUserFeedback.
Ожидается в ближайшее время: в течение 2024 года мы постепенно откажемся от GitHub Issues как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделеОтправить и просмотреть отзыв по