2009-08-24 104 views
4

在我关于这个数据库应用程序的工作中,我显然设法破坏了应用程序中的一个窗体 - 尝试将任何编辑保存到窗体上的任何字段都将导致Access崩溃,并且数据库文件报告Access试图重新打开它。我尝试导出整个表单+控件作为文本,然后重新导入它们使用VB代码(从艾伦布朗的网站),但它不会重新导入没有崩溃Access或告诉我表单不是由于错误导入(无错误编号或描述)。腐败形式 - 救援或重建?

形式是相当复杂的,所以我很犹豫,只是从头开始改造它,那么有没有办法救它?如果我设法恢复它,这是否意味着我应该将所有内容都转移到新的MDB文件中(以防它是级联故障效果)?老实说,我从来没有设法破坏过一个Access数据库对象,所以我不知道这是否表示该MDB文件的结尾,或只是我可以纠正和继续像以前一样。

+1

当您声明“将整个表单+控件导出为文本”时,是否指使用SaveAsText函数? – 2009-08-24 22:43:31

+0

是的,使用SaveAsText函数 - 建议在Allen Browne的网站上尝试一下。 – 2009-08-26 21:37:31

回答

3

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

0

有你看了全套的方法来与腐败从艾伦·布朗处理:http://allenbrowne.com/ser-47.html?特别是反编译。

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

+0

如果这不起作用,我会建议将代码保存到记事本中,并将其从记事本中复制回来。那里可能有些不可思议的东西。 – 2009-08-24 22:34:56

2

一旦制作了数据库副本,反编译是一件好事。您是否尝试使用“文件>>另存为”保存另一个名称下的表单?也可以尝试从数据库窗口中复制并粘贴具有不同名称的表单。

另外,据我的经验,一个损坏的表单/报告不会传播到数据库的其余部分。这就是说清理东西不会有什么坏处。紧凑和修复仅修复表和相关数据,如索引和关系。要清理损坏的其他对象,如窗体和报表,您必须将它们导入到新的MDB/ACCDB中。提示:如果有很多对象,请关闭数据库容器窗口。在导入刷新数据库容器窗口期间,Access会浪费很多时间。

+1

导入可以带来腐败的原因。如果你真的想要一个干净的导入,你必须使用Application.SaveAsText/.LoadFromText。 – 2009-08-25 20:04:13

+0

我不记得有这么远。偶尔我有,但它从来没有证明有用。 – 2009-08-26 04:08:40

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 
+0

我已经试过这个副本,当试图将文件转换为Access 2000项目时,它崩溃了Access。 – 2009-08-26 21:42:28

+0

我认为你可能会超越一个简单的修复。抱歉。你可以在设计视图中打开表单吗?如果是这样,您可以突出显示所有控件并将它们复制/粘贴到新窗体上。如果您可以访问代码,请尝试复制/粘贴或从备份重建。 – Praesagus 2009-08-27 17:20:37

3

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

我张贴的答案,建议你可能需要改变你的编码实践,如果你在代码方向对象遇到腐败。

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

  2. 总是关闭VBE选项中的COMPILE ON DEMAND。请阅读迈克尔卡普兰关于The Real Deal on the Decompile Switch的文章以解释原因。

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

  4. 决定合理的时间间隔备份和反编译你的应用程序。如果你正在执行繁重的代码重击,你可能希望每天都这样做。如果您在编码期间遇到了Access崩溃问题,您可能想要进行备份和反编译/重新编译。当然,在发布给用户之前,你应该反编译并重新编译你的应用程序。

如果你遵循这些做法,在代码承载Access对象损坏的原因将被最小化,尽可能,而你也将有大量的备份(冗余备份的多层次是必须的,因为当发生备份故障时,它们几乎总是通过多级级联 - 具有多种类型的备份并且不依赖于自动备份)。

但关键的一点:

编译的时候,反编译合理常和过甜的东西永远不会有机会在应用程序中的p代码积累。

0

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