16

我们有一个用 Access 编写的自定义程序,其中有奇怪的崩溃。我们添加了错误处理,记录并通过电子邮件发送在我们自己的代码内部发生的任何崩溃,这使我们能够修复我们生成的大多数错误,但有时崩溃发生在我们的代码之外。

我们在 2013 年发现新出现的一个示例——我们有一个表单在编辑某个字段中的数据后会崩溃——新条目很好,但创建记录后的任何编辑都会导致完全崩溃,并且关闭 MS Access。我们花了一些时间,最终发现我们的一些代码强制表单移动到下一条记录,该字段是该行的最后一个字段,但 Access 本身也试图移动到下一条记录。这自 2007 年以来一直存在于系统中,但在 2013 年开始导致程序关闭。

有什么方法可以捕获和诊断 MS 访问中的程序级崩溃?
Windows 事件查看器仅显示以下内容:

错误应用程序名称:MSACCESS.EXE,版本:15.0.4454.1501,时间戳:0x50a35ef4 错误模块名称:MSACCESS.EXE,版本:15.0.4454.1501,时间戳:0x50a35ef4 异常代码:0xc0000005 错误偏移量:0x00116452 错误进程 id:0x1398应用程序启动时间:0x01ce6e665043d8be 错误应用程序路径:C:\Program Files (x86)\Microsoft Office\Office15\MSACCESS.EXE 错误模块路径:C:\Program Files (x86)\Microsoft Office\Office15\MSACCESS.EXE 报告 ID: 6cfcb0eb-da62-11e2-8966-842b2b86f028

4

6 回答 6

22

这是一个旧线程,但它是 Google 上的顶级结果之一,所以我想我会给出答案。当您收到“Access 遇到问题需要关闭”时,您可以采取哪些步骤。通常在事件日志中你会看到:

Faulting application name: MSACCESS.EXE, version: 15.0.4869.1000, time stamp: 0x57e12b41
Faulting module name: MSACCESS.EXE, version: 15.0.4869.1000, time stamp: 0x57e12b41
Exception code: 0xc0000005

这些故障排除可能令人沮丧。以下是我采取的行动列表,从侵入性最小到侵入性最大。我不只是发明了这些修复程序——多年来,我亲眼目睹了每个修复程序都解决了这个问题。

反编译数据库

您表示反编译每个版本是政策。好的政策 - 但每次遇到错误后都要明确执行。原因是您可能正在修复核心问题,但由于容器损坏而没有注意到。

  • 我创建了一个使用“/反编译”开关加载数据库的快捷方式。
  • 双击此快捷方式时按住 shift 键,跳过任何自动运行,然后直接进入导航窗口。
  • 加载数据库后,您需要单击“压缩和修复”按钮。重新加载数据库时再次按住 shift 键。
  • 现在去编译代码并保存。这就是我用于反编译的过程。

测试电脑内存

特别是如果崩溃仅限于一台或两台机器 - 这样做。
检查事件查看器。是否有很多描述应用程序崩溃的“错误”消息,并且故障模块不同?如果是这样,那么如果不是损坏的 Windows 安装,那么很有可能您正在查看内存问题。

我相信有很多出色的内存测试仪,但我鼓励您使用适当的测试来捕获丢失的位。MemTest86 是一个老歌,但很好。有当前版本和一些同样好的分叉

开始测试并让它在工作时间运行。我在建筑物中的电源不佳会导致内存错误,因此请保持变量相同。

从表单中删除二进制数据

有时崩溃发生在一个表单或报告中。如果它是损坏的二进制数据,那么崩溃应该发生在不同的计算机上,不同的用户。如果是这种情况,请按照以下步骤操作。(仅限高级用户)

  1. 在即时窗口中,将对象另存为文本。

    Application.SaveAsText acForm, "MyForm", CurrentProject.Path & "\MyForm.txt"

  2. 重命名原始表单项(例如重命名为 MyForm_Bak)

  3. 在记事本中打开导出的文件
  4. 删除 "Checksum=" 行(应该在第 3 行)
  5. 清除二进制数据
    • 翻阅文件。
    • 将有以“Parameter = Begin”开头的行,并具有编码的二进制数据行,以由“End”组成的行结束
    • 当您找到这些行之一时,您需要(包括)删除从 Begin 到 End 的所有行。
    • 您应该删除的参数是:NameMap、PrtMip、PrtDevMode、PrtDevNames、PrtDevModeW、PrtDevNamesW
    • 所有这些块都应该出现在您的表单控件定义之前
  6. 当您打开文件时,滚动浏览文件的其余部分并查找任何吸引您眼球的内容,尤其是在底部的 VBA 模块代码中。
  7. 保存文件
  8. 在 Access 的即时窗口中,将表单重新加载到

    Application.LoadFromText acForm, "MyForm", CurrentProject.Path & "\MyForm.txt"

  9. 反编译/压缩修复/重新编译

  10. 打开表格,希望一切都变得更好。

摆脱“OLE 对象”字段

如果您在 Access 本身中存储了图像或其他数据,那么您应该找到更好的方法。OLE数据存储时,根据存储它的计算机上的软件(和软件版本)进行存储。当另一台计算机在表单上显示该 OLE 对象数据,但没有安装确切的软件/版本时 - 您经常会以崩溃告终。

如果您要存储图像数据,那么更好的方法是存储文件名,而不是将图像保存到标准位置。较新版本的访问具有本机控件,使之成为可行的方法。

重建整个数据库

这是很多工作,所以当你用尽所有其他选项时,我会保存它。仅当所有用户都出现问题时,您才需要执行此操作。如果不是所有用户都发生这种情况,那么它不是损坏的数据库。

与删除二进制数据的步骤类似,您将从头开始重建数据库。当我到达这一步时,我处于完全的偏执模式。也许它有点仪式化,但我一丝不苟地做每一件事,没有捷径,并且非常小心地不通过直接复制或导入/导出来“保留”腐败。作为我的最后立场,我认为这从来没有解决过这个问题。谢天谢地,自从 Access 2000 以来,我就不必这样做了。

  • 创建一个新的访问数据库容器。
  • 不要使用导入/导出功能
  • 表:
    • 对于旧访问容器中的每个表,在新容器中创建一个新表。从设计视图中,复制/粘贴字段定义。
    • 将旧数据导出为 XML 或 CSV,然后从那里导入。
  • 查询:
    • 进入原始查询中的 SQL 视图,将 SQL 文本复制并粘贴到新数据库的查询中。
  • 表格/报告:
    • 使用 Application.SaveAsText 函数导出表单/报告
    • 从表单中删除二进制数据并查看
    • 使用 Application.LoadFromText 函数重新导入它们
    • 重新创建宏。
    • 在 Access 2007 和更新版本中,使用新的宏系统,您只需打开宏,全选 (Control + A) 并粘贴到空白记事本文档中。再次从记事本复制并粘贴到新访问容器中的空白宏中
  • 模块
    • 选择所有代码 (Control + A) 并粘贴 (Control + V) 到新的数据库容器中
  • 数据宏
    • 自从数据宏问世以来,我不必这样做,但是您可以使用 SaveAsText / LoadFromText 函数将数据宏从表中导出。

当一切都说完了 - 你应该有一个非常干净的数据库容器。

从测试中删除其他变量

网络腐败

不要从网络加载客户端。将它放在本地驱动器上并从那里运行它。

企业建设

如果您在使用“计算机构建”的公司环境中,并且在反编译、测试内存和剥离二进制数据方面没有成功 - 然后拒绝进行进一步测试,直到 IT 团队可以为用户提供具有仅安装了 Windows、Office 和 Service Pack。我通常更喜欢自己安装,所以我知道我可以信任它。所有软件和更新都应手动安装,不得使用无人值守安装。不要在这台机器上安装防病毒软件。

我已经让 IT 部门出于纯粹的 FUD 和不合理而拒绝了这个 - 如果这是您遇到的情况,那么请在“帮助我帮助您”的情况下洗手。

坏功率

如内存部分所述 - 电源波动会导致计算机错误。如果数据库位于工业建筑中 - 然后尝试使用提供清洁电源的电源调节器或 UPS(关闭电池,而不是关闭通过金属氧化物压敏电阻的主电源)

此外,请检查插入电源条或插座的电源线。确保仪表和电压规格足够。我这样说是因为 IT 部门经常将电源线插在工作站上,然后移除机器。多年后,他们使用了更强大的电源,但没有关闭电缆。它有所作为。如有疑问,请带上一根新的、更粗的电缆。

附录

自从最初发布这篇文章以来,我遇到了一些新的。移动到 Access 2016 时多次打击我的是 ODBC 驱动程序。如果您的数据库在 Access 2013 下运行良好,但在 Access 2016 中非常可靠地崩溃,那么问题可能出在 ODBC 驱动程序上。跳下,尝试找出是否有更新的驱动程序。如果没有成功,则通过创建新数据库并在 VBS 中进行 ODBC 调用来确认是否是 ODBC 驱动程序。如果您遇到相同的崩溃-它的驱动程序。如果没有更新的驱动程序,您只需将其保留在 2013 年。我在使用带有几个数据库的 PostGreSQL ODBC 驱动程序时遇到了这个问题。

于 2016-11-30T20:23:14.113 回答
3

每个 Access 数据库中每个表单上的每个函数都应具有如下所示的流程:

Private Sub btnMyButton_Click()
Dim MyVar as String
On Error GoTo ErrorHappened

'Do some stuff here...

ExitNow:
    Exit Sub

ErrorHappened:
    MsgBox Err.Description
    Resume ExitNow
End Sub

在 ErrorHappened 部分,您可以让它写入跟踪错误的表。如果您将所有的 Subs 和 Functions 更改为像这样流动,您应该能够捕获数据库存在的每一个问题。也许写出 Err.Number 以及 Err.Description。

于 2013-06-25T13:05:31.910 回答
1

For anyone else who stumbles across this thread in Google here are another couple of causes for random Access crashes:

Just for background, I have a form with a subform on it, loading data from linked tables on a server.

  • If you have "_Enter" events on the fields on the parent form this may cause Access to go into an endless loop, repeatedly firing these events. This occurred when I was on the subform, and pressed a button on the parent form. I replaced all these with "_GotFocus" events instead which fixed the problem.

  • Do not reference the subform in the onLoad even of the parent form. This one was random, the form would load fine and then the next time you went into the same form, with the same record, it would cause Access to crash. So I removed all references to the subform in the onLoad event of the parent form and it now seems to work fine. I especially noticed this when my internet connection was slow, it appeared that the main form was loading before the subform and so when it referenced it it hadn't loaded and so caused all sorts of issues with Access, which invariable ended in a random crash of Access.

于 2017-07-07T03:45:27.780 回答
1

2020 年更新和附加答案。在我试图升级到 2019 Pro 的最初于 2010 年构建的应用程序上,我遇到了同样的“打开宏时崩溃”随机问题。这是解决问题并帮助自己解决问题的简单方法...清理应用程序。将您的访问应用程序从早期版本升级到 2019 Pro 或更高版本时,删除任何和所有开发表、查询、宏、表单,以及您在应用程序中不使用的任何内容......旧的、过时的等等,检查您应用程序中的所有位置和摆脱它!问题解决了,您的应用程序现在不再那么杂乱,更易于维护……非常适合我们的升级情况。

于 2020-12-08T14:46:55.353 回答
0

我使用 Access 2010。我通过转到文件 -> 将对象另存为 -> 表格名称作为报告来制作报告(给定表格的真实副本)。在设计视图中打开报表并进行一些更改后,我尝试保存更改。访问不断崩溃。经过很多小时终于,我发现报告中有一些按钮。当我用控制箱替换这些时。就是这样。一切都很好。希望这可以节省一些人宝贵的时间,并且没有迹象表明要寻找什么。

于 2018-09-09T15:29:15.363 回答
0

检查 str() 函数调用。从 2010->2019 更新后,有时会因此调用而崩溃。

于 2020-09-30T08:31:59.883 回答