腐败形式 - 救援还是重建?

时间:2009-08-24 19:06:08

标签: ms-access forms corruption

在我处理这个数据库应用程序的过程中,我显然设法破坏了应用程序中的表单 - 尝试将任何编辑保存到表单上的任何字段都会导致Access崩溃,并且数据库文件报告损坏时Access尝试重新打开它。

我已经尝试将整个表单+控件导出为文本,然后使用VB代码(来自Allen Browne的网站)重新导入它们但是如果没有崩溃Access或告诉我表单不导入它将不会重新导入 - 由于错误(没有给出错误号或描述)。

表单相当复杂,因此我对从头开始重新制作它犹豫不决,有没有办法保存它?如果我设法恢复它,这是否意味着我应该将所有内容传输到新的MDB文件(如果它是级联故障影响)?

说实话,我以前从未设法破坏Access数据库对象,因此我不知道这是否是表示该MDB文件结束的信号,或者只是我可以像以前一样纠正和继续的事情。

6 个答案:

答案 0 :(得分:3)

其他人为您提供了各种可能恢复损坏形式的方法。有时,带有代码的Access对象将变得无可挽回地损坏,并且这些方法都不会起作用。在这种情况下,你必须查看=在备份中找到一个非腐败版本作为起点并导入它然后将其修改回对象的当前状态。

我发布了一个答案,建议您在代码承载对象中遇到损坏时可能需要更改编码实践。

  1. 首先,您需要确保定期备份并且不要覆盖它们。回滚到早期版本始终是最后的手段。

  2. 始终在VBE选项中关闭COMPILE ON DEMAND。阅读Michael Kaplan关于The Real Deal on the Decompile Switch的文章,了解原因。

  3. 在VBE中,将编译按钮(和调用堆栈按钮)添加到常规VBE工具栏,并在每几行代码后点击该编译按钮,然后保存代码。

  4. 确定合理的间隔来备份和反编译您的应用。如果您正在进行重型代码冲击,您可能希望每天都这样做。如果您在编码期间遇到Access崩溃,则可能需要进行备份和反编译/重新编译。当然,在分发给用户之前,您应该反编译并重新编译您的应用程序。

  5. 如果您遵循这些做法,代码承载Access对象中的损坏原因将尽可能地最小化,同时您还将拥有大量备份(多级冗余备份是必须的,因为当备份失败发生时,它们几乎总是级联多个级别 - 有几种类型的备份,不依赖于自动备份。

    但关键点:

    经常编译,经常反编译,并且icky的东西永远不会有机会累积在你的应用程序的p代码中。

答案 1 :(得分:3)

我最终要做的是重新创建表单,并逐个元素地复制,直到我发现strSupplierID组合框本身是崩溃的原因。我从头开始重新创建它,手动赋予它相同的属性,并从我剪切并粘贴到剪贴板的存储副本中替换VB。表单现在有效,我删除了损坏的表单,并压缩了数据库。感谢大家的帮助! :)

答案 2 :(得分:2)

一旦你制作了数据库的副本,反编译是一件好事。您是否尝试使用文件>>以不同的名称保存表单?另存为?还可以尝试使用与数据库窗口不同的名称复制和粘贴表单。

根据我的经验,一个损坏的表单/报告不会传播到数据库的其余部分。这说清理东西不会有害。压缩和修复仅修复表和索引和关系等相关数据。要清除损坏的其他对象(如表单和报表),必须将它们导入新的MDB / ACCDB。提示:如果有很多对象,请关闭数据库容器窗口。在导入刷新数据库容器窗口期间,Access会浪费大量时间。

答案 3 :(得分:0)

您是否看过Allen Browne处理腐败的全套方法:http://allenbrowne.com/ser-47.html?特别是反编译。

可能值得尝试将控件复制并粘贴到新表单中,然后逐渐添加回代码中。

答案 4 :(得分:0)

我曾多次遇到过这种情况。这里有一些东西可以拯救我的培根。我假设您使用的是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

答案 5 :(得分:0)

我发现包含10个或更多列的组合框可能导致Access窗体损坏。尝试减少列数或删除该组合框以查看表单是否正确保存。此问题与使用Access 2003数据库在Win 7 64位操作系统中工作有关。在XP中进行开发时没有问题,换句话说,表单可以在组合框中保存很好的列数。希望这些信息有所帮助,因为它会浪费很多时间来认为数据库已损坏。