Поврежденная форма - спасение или переделка? - PullRequest
4 голосов
/ 24 августа 2009

Во время моей работы с этим приложением базы данных мне, очевидно, удалось повредить форму в приложении - попытка сохранить любое изменение в любом поле формы приведет к сбою Access, а файл базы данных сообщит, что поврежден при Доступ пытается открыть его.

Я попытался экспортировать всю форму + элементы управления в виде текста, а затем повторно импортировать их с использованием VB-кода (с веб-сайта Аллена Брауна), но он не будет реимпортирован без сбоя Access или сообщения, что форма не импортируется - возможно из-за ошибки (номер ошибки или описание не указаны).

Форма довольно сложная, поэтому я не решаюсь просто переделать ее с нуля, так есть ли способ ее сохранить? Если мне удастся восстановить его, значит ли это, что я должен перенести все в новый файл MDB (в случае каскадного сбоя)?

Если честно, мне никогда раньше не удавалось повредить объект базы данных Access, поэтому я не знаю, сигнализирует ли это о конце этого файла MDB, или что-то, что я могу исправить и продолжить, как раньше.

Ответы [ 6 ]

3 голосов
/ 28 августа 2009

В итоге мне пришлось заново создать форму и копировать элемент за элементом, пока я не обнаружил, что причиной сбоя является само поле со списком strSupplierID. Я воссоздал его с нуля, вручную придав ему те же свойства и заменив VB из сохраненных копий, которые я вырезал и вставил в буфер обмена. Форма теперь работает, и я удалил поврежденную форму и сжал базу данных. Спасибо всем за помощь! :)

3 голосов
/ 26 августа 2009

Другие предоставили вам различные подходы, чтобы, возможно, восстановить вашу испорченную форму. Иногда несущий код объект Access становится безвозвратно поврежденным, и ни один из этих методов не будет работать. В этом случае вам нужно будет посмотреть резервные копии, чтобы найти не поврежденную версию в качестве отправной точки и импортировать ее, а затем вернуться к текущему состоянию объекта.

Я публикую ответ, чтобы предположить, что вам, возможно, придется изменить методы кодирования, если вы столкнулись с повреждением в объектах, несущих код.

  1. Во-первых, вам нужно убедиться, что вы регулярно сохраняете резервные копии и не перезаписываете их. Откат к более ранней версии - это всегда последнее средство.

  2. Всегда выключайте COMPILE ON DEMAND в опциях VBE. Прочитайте статью Майкла Каплана о Реальное предложение по переключению декомпиляции для объяснения причин.

  3. В VBE добавьте кнопку компиляции (и кнопку стека вызовов) на свою обычную панель инструментов VBE, и нажмите эту кнопку компиляции после каждых нескольких строк кода, и сохраните свой код.

  4. Выберите разумный интервал для резервного копирования и декомпиляции вашего приложения. Если вы делаете тяжелый код, вы можете делать это каждый день. Если вы столкнулись с падением Access во время кодирования, вы, вероятно, захотите сделать резервную копию и декомпилировать / перекомпилировать. Конечно, перед распространением среди пользователей вы должны декомпилировать и перекомпилировать свое приложение.

Если вы будете следовать этим правилам, причины повреждения в объектах Access, несущих код, будут максимально сведены к минимуму, при этом у вас также будет множество резервных копий (несколько уровней избыточных резервных копий являются обязательными, потому что при сбоях резервного копирования они почти всегда каскадируются на нескольких уровнях - имеют несколько типов резервного копирования и не зависят от автоматического резервного копирования).

Но ключевой момент:

Часто компилируйте, разумно декомпилируйте, и неприятные вещи никогда не будут накапливаться в p-коде вашего приложения.

2 голосов
/ 25 августа 2009

Декомпиляция - это хорошая вещь, которую стоит попробовать после создания копии базы данных. Вы пытались сохранить форму под другим именем, используя Файл >> Сохранить как? Также попробуйте скопировать и вставить форму с другим именем из окна базы данных.

Кроме того, по моему опыту, одна поврежденная форма / отчет не распространяется на остальную часть базы данных. Тем не менее, это не больно убирать вещи. Сжатие и восстановление только исправляет таблицы и связанные данные, такие как индексы и отношения. Для очистки поврежденных других объектов, таких как формы и отчеты, вы должны импортировать их в новую MDB / ACCDB. Совет: закройте окно контейнера базы данных, если у вас много объектов. При импорте обновление тратит много времени, обновляя окно контейнера базы данных.

0 голосов
/ 29 ноября 2015

Я обнаружил, что поля со списком из 10 или более столбцов могут привести к повреждению формы доступа. Попробуйте уменьшить количество столбцов или убрать это поле со списком, чтобы увидеть, правильно ли сохраняется форма. Эта проблема была связана с работой в 64-битной операционной системе Win 7 с базами данных Access 2003. При разработке в XP проблем не было, другими словами, формы отлично сохраняются с большим количеством столбцов в комбинированных полях. Надеюсь, что эта информация поможет, поскольку она потратила много времени на то, чтобы считать базу данных поврежденной.

0 голосов
/ 25 августа 2009

Это случалось со мной много раз. Вот пара вещей, которые спасли мой бекон. Я предполагаю, что вы используете Access 2003 или выше. Попробуйте преобразовать базу данных в формат Access 2002 или 2000. Затем преобразуйте эту базу данных обратно в вашу текущую версию.

Вот код, который я создал для борьбы с раздуванием в предыдущих версиях. Это также решило эту проблему для меня 95% времени.

Опция сравнения базы данных Опция Явная

Private Sub cmdCreateDuplicate_Click()
'********************************************************
' Author        Daniel Tweddell
' Revision Date 10/27/05
'
' To Combat bloat, we are recreating the a new database
'********************************************************
On Error GoTo Err_Function
    Dim strNewdb As String
    Dim AppNewDb As New Access.Application 'the new database we're creating to manage the updates
    strNewdb = CurrentProject.Path & "\db1.mdb"
    SysCmd acSysCmdSetStatus, "Creating Database. . ."
    With AppNewDb
        DeleteFile strNewdb 'make sure it's not already there
        .Visible = False 'hear no database see no database
        .NewCurrentDatabase strNewdb 'open it
        ChangeRemoteProperty "StartupShowDbWindow", AppNewDb, , dbBoolean, False
        ChangeRemoteProperty "Auto compact", AppNewDb, , dbBoolean, True
        ImportReferences AppNewDb, Application
        .CloseCurrentDatabase
    End With
    Set AppNewDb = Nothing
    Dim ao As AccessObject
    For Each ao In CurrentData.AllTables
        If Left(ao.Name, 4) <> "msys" Then
            DoCmd.TransferDatabase acExport, "Microsoft Access", strNewdb, acTable, ao.Name, ao.Name
            SysCmd acSysCmdSetStatus, "Exporting " & ao.Name & ". . ."
        End If
    Next
    For Each ao In CurrentData.AllQueries
        DoCmd.TransferDatabase acExport, "Microsoft Access", strNewdb, acQuery, ao.Name, ao.Name
        SysCmd acSysCmdSetStatus, "Exporting " & ao.Name & ". . ."
    Next
    For Each ao In CurrentProject.AllForms
        DoCmd.TransferDatabase acExport, "Microsoft Access", strNewdb, acForm, ao.Name, ao.Name
        SysCmd acSysCmdSetStatus, "Exporting " & ao.Name & ". . ."
    Next
    For Each ao In CurrentProject.AllReports
        DoCmd.TransferDatabase acExport, "Microsoft Access", strNewdb, acReport, ao.Name, ao.Name
        SysCmd acSysCmdSetStatus, "Exporting " & ao.Name & ". . ."
    Next
    For Each ao In CurrentProject.AllMacros
        DoCmd.TransferDatabase acExport, "Microsoft Access", strNewdb, acMacro, ao.Name, ao.Name
        SysCmd acSysCmdSetStatus, "Exporting " & ao.Name & ". . ."
    Next
    For Each ao In CurrentProject.AllModules
        DoCmd.TransferDatabase acExport, "Microsoft Access", strNewdb, acModule, ao.Name, ao.Name
        SysCmd acSysCmdSetStatus, "Exporting " & ao.Name & ". . ."
    Next
    MsgBox "Creation Complete!" & vbCrLf & "Reset Password", vbExclamation, "New Database"
Exit Sub
Err_Function:
    ErrHandler Err.Number, Err.Description, Me.Name & " cmdCreateDuplicate_Click()"
End Sub


Function DeleteFile(ByVal strPathAndFile As String) As Boolean
'***********************************************************************************
' Author        Daniel Tweddell
' Revision Date 04/14/03
'
' Deletes a file
'***********************************************************************************
On Error GoTo Err_Function
    DeleteFile = True                   'default to true
    If UncDir(strPathAndFile) <> "" Then   'make sure the file is there
        Kill strPathAndFile             'delete a file
    End If
Exit Function
Err_Function:
    ErrHandler Err.Number, Err.Description, "DeleteFile()", bSilent
    DeleteFile = False                  'if there is a problem, false
End Function

Public Sub ChangeRemoteProperty(strPropName As String, _
                                appToDB As Access.Application, Optional appFromDB As Access.Application, _
                                Optional vPropType As Variant, Optional vPropValue As Variant)
'********************************************************************************
' Author        Daniel Tweddell
' Revision Date 01/13/04
'
' Changes/adds a database property in one db to match another
'********************************************************************************
On Error GoTo Err_Function
    Dim ToDB As DAO.Database
    Dim FromDB As DAO.Database
    Dim prpTest As DAO.Property
    Dim bPropertyExists As Boolean
    Set ToDB = appToDB.CurrentDb
    If Not appFromDB Is Nothing Then Set FromDB = appFromDB.CurrentDb
    bPropertyExists = False 'flag to see if we found the property
    For Each prpTest In ToDB.Properties 'first see if the property exists so we don't error
        If prpTest.Name = strPropName Then
            If IsMissing(vPropValue) Then vPropValue = FromDB.Properties(strPropName) 'in case we want to assign it a specific value
            ToDB.Properties(strPropName) = vPropValue 'if it does set it and get out or the loop
            bPropertyExists = True
            Exit For
        End If
    Next
    If Not bPropertyExists Then ' Property not found.
        Dim prpChange As DAO.Property
        If IsMissing(vPropValue) Then
            With FromDB.Properties(strPropName)
                vPropValue = .Value 'in case we want to assign it a specific value
                vPropType = .Type
            End With
        End If
        Set prpChange = ToDB.CreateProperty(strPropName, vPropType, vPropValue) 'add it
        ToDB.Properties.Append prpChange
    End If
Exit Sub
Err_Function:
    ErrHandler Err.Number, Err.Description, "ChangeRemoteProperty()", bSilent
End Sub

Public Sub ImportReferences(AppNewDb As Access.Application, appUpdateDB As Access.Application, Optional iStatus As Integer)
'********************************************************************************
' Author        Daniel Tweddell
' Revision Date 01/13/04
'
' Copies the current references from the one database to another we're building
'********************************************************************************
On Error GoTo Err_Function
    Dim rNewRef As Reference
    Dim rUpdateRef As Reference
    Dim bReferenceExists As Boolean
    Dim rToAdd As Reference
    Dim sReference As String
    If iStatus <> 0 Then ProgressBarUpdate iStatus, "Referencing Visual Basic Libraries. . ."
    For Each rUpdateRef In appUpdateDB.References
        bReferenceExists = False
        For Each rNewRef In AppNewDb.References
            sReference = rNewRef.Name
            If rUpdateRef.Name = sReference Then
                bReferenceExists = True
                Exit For
            End If
        Next
        If Not bReferenceExists Then
            With rUpdateRef
                Set rToAdd = AppNewDb.References.AddFromGuid(.Guid, .Major, .Minor)
            End With
        End If
    Next
Exit Sub
Err_Function:
    ErrHandler Err.Number, Err.Description, "ImportReferences(" & sReference & ")", bSilent
    Resume Next
End Sub
0 голосов
/ 24 августа 2009

Рассматривали ли вы полный набор методов борьбы с коррупцией от Аллена Брауна: http://allenbrowne.com/ser-47.html? В частности, декомпилировать.

Возможно, стоит попробовать скопировать элементы управления в новую форму и постепенно добавлять их обратно в код.

...