访问在加载用户表单时崩溃

Access crashed on loading userform

我已经构建了我的应用程序,但出现了一个问题,我无法理解 - 我的应用程序还没有 autoexec,所以我打开访问并双击我的用户窗体将其打开。

打开用户窗体时,Access 崩溃并关闭

但是,如果我先将用户窗体放在设计视图中,然后在窗体视图中打开窗体,它就可以正常工作。

怎么会这样?

不可能是表单加载编码,否则从设计视图转到表单视图时仍然会崩溃。

我将包含我的表单加载编码以防万一:

Me.LastImport.Value = DLast("LastImport", "tbl_Import_Export_logger")
Me.Text42.Value = Date
Me.Text44.Value = Date - Weekday(Date, 3)

'Compliance Reporting
Me.Text68 = DCount("[CustomerAccountNumber]", "Q_HealthChecksOverdue") 'Overdue Health Checks
Me.Text76 = DCount("[CustomerAccountNumber]", "Q_HealthChecksdue") ' Due Health Checks
Me.Text74 = DCount("[CustomerAccountNumber]", "Q_HealthChecksCompleted") ' Completed Health Checks
Me.Text72 = DCount("[LettersDueStatus]", "Q_LettersSent_Query") 'Count number of letters sent

(最初写在 Stack Overflow 文档上)

如何解决 Access 崩溃问题

当您收到错误:"Microsoft Access has encountered a problem and needs to close" 时,通常没有很多信息可以帮助您确定错误原因。以下是您可以采取的一系列步骤来排查错误原因。

反编译数据库

这应该始终是您的初始修复。一个好的策略是在每次发布之前反编译数据库。

  1. 创建反编译快捷方式.

    这会使用“/反编译”开关加载数据库。

    1. 右键单击您的数据库文件。 Select复制
    2. 右键单击资源管理器 window 和 select "Paste Shortcut"
    3. 右键单击快捷方式并 select "Properties"
    4. 在目标框中,转到行尾并添加 /decompile
    5. 点击确定关闭快捷方式
  2. 使用 Shift 打开数据库。

    双击此快捷方式时按住 Shift 键。 这可以防止任何自动 运行s 在数据库中执行。 你应该直接去导航window.

  3. 压缩并修复数据库。

    加载数据库后,您需要单击“压缩和修复”按钮。

  4. 工具功能区找到压缩和修复数据库按钮。

  5. 按住 Shift 键。单击 压缩和修复 按钮时按住它。

  6. 重新编译数据库

  7. 进入VBAwindow(Control + G)

  8. Select 从菜单调试 -> 编译

这是完整的反编译过程。一般来说,它应该可以修复 99% 的所有 Access 崩溃或奇怪的表单行为。

重建整个数据库

这项工作量很大,所以在用尽所有其他选项后,不得已才这样做。只有当问题发生在不同用户、不同机器上时,您才需要这样做。如果不是所有用户都发生这种情况,那么它很可能不是损坏的数据库容器。

与删除二进制数据的步骤类似,您将从头开始重建数据库。这个过程有点仪式化,但如果小心翼翼地完成,不要 "preserve" 任何可能的腐败,那么这个过程是非常有效的。

创建新的访问数据库容器。

  • 在 Access 的“文件”选项卡上,您可以 select "New"。以 ACCDB 格式创建一个新的空数据库。

将所有对象移动到新容器

不要使用 Access 中的导入/导出功能移动对象,不要简单地单击和拖动。这样做可以将损坏的项目复制到新容器中。

表:

  • 对于旧访问容器中的每个 table,在新容器中创建一个新的 table。
  • 从设计角度来看,copy/paste 字段定义。
  • 检查 table 属性以确保它们在两个数据库中匹配
  • 同时移动任何数据宏(有关如何执行此操作,请参阅宏部分)
  • 要移动数据,请将旧数据导出为 XML 或 CSV,然后从该格式导入。

查询:

  • 将每个查询加载到 SQL 视图中。
  • 复制/粘贴 SQL 文本。
  • 粘贴到新数据库中。
  • 比较查询属性以确保它们匹配。

表格/报告:

  • 对于每个表格/报告,使用 Application.SaveAsText 函数将 forms/reports 导出到文本文件。
  • 删除二进制数据(请参阅 从表单中删除二进制数据 文档以熟悉此过程)
  • 使用Application.LoadFromText函数将对象重新导入新数据库

您有三种移动宏的方法。

  1. 在新的数据库容器中手动重新创建每个宏。
  2. 使用带有 acMacro 参数的 Application.SaveAsText / Application.LoadFromText 方法。
  3. Copy/Paste 每个宏的宏定义
    • Select 所有 (Control + A) 到 select 所有宏元素。然后复制(Control + C)。
    • 打开一个空白记事本文档并粘贴 (Control + V) 宏 XML。
    • 在新的数据库容器中创建一个新的空白宏。
    • 在记事本中,Select 所有文本(Control + A)。然后复制(Control + C)
    • 在空白宏中,粘贴 (Control + V)。宏应该出现。保存。

模块

  • 对于每个模块,select 所有代码 (Control + A) 并粘贴 (Control + V) 到新的数据库容器中。
  • 一定要检查数据库属性(在 VBA Window 中,转到工具 -> 客户端属性)

数据宏

对于每个数据宏,使用 SaveAsText / LoadFromText 方法。

  1. 进入VBA立即Window(Control + G)
  2. 键入 Application.SaveAsText acTableDataMacro, "MyTableName", CurrentProject.Path & "\MyTableName.txt"(将 MyTableName 替换为包含数据宏的 table 的名称)
  3. 检查文件是否有任何损坏迹象
  4. 在新的数据库容器中,使用 Application.LoadFromText acTableDataMacro, "MyTableName", CurrentProject.Path & "\MyTableName.txt"
  5. 加载定义

如前所述,这是一项 LOT 的工作,但它有结果。将 Access 97 数据库迁移到 2000 或将 Access 2000 数据库迁移到 2003 时也应使用此方法。

删除 "OLE Object" 个字段

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

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

从表单中删除二进制数据

有时崩溃在单个表单或报表中不断发生,或者仅在打印时发生。表格/报告中的二进制数据可能已损坏。

将表单/报表对象保存为文本

有两个未记录的函数。 Application.SaveAsText 和 Application.LoadFromText。您可以使用这些函数导出 form/report 定义,清理定义,然后再次导入。

  1. 在继续之前备份您的数据库
  2. 转到VBA立即Window(Control + G)
  3. 键入 Application.SaveAsText acForm, "MyForm", CurrentProject.Path & "\MyForm.txt"(将 MyForm 替换为表格/报告的名称。如果它是您正在修复的损坏报告,请使用 acReport)
  4. 重命名数据库中的原始表单项(例如重命名为 MyForm.Bak)Window

清理表单/报告定义文件

  1. 在记事本中打开导出的文件(例如MyForm.txt)
  2. 删除"Checksum="行(应该在第3行)
  3. 清除二进制数据
    1. 识别二进制数据块。查看文件,您会看到以 "Parameter = Begin" 开头的行。在这些行之后,您将获得编码二进制数据行。最后,二进制块将以仅包含 "End" 的行结尾。二进制数据块包括第一行(使用 Begin 语句)和直到并包括最后一行的所有行(使用 End 语句)。 注意:所有这些块都应出现在您的表单控件定义之前
    2. 删除以下参数的二进制数据块:
      • 名称地图
      • PrtMip
      • PrtDevMode
      • PrtDevNames
      • PrtDevModeW
      • PrtDevNamesW
  4. 寻找其他问题。当您打开文件时,滚动浏览文件的其余部分并寻找任何引起您注意的内容,尤其是底部的 VBA 模块代码。您将寻找任何与众不同的东西,并且可能是腐败。
  5. 保存文件。

将表单/报告加载回 Access and Test

  1. 将表单加载回 Access。

    • 在 Access 中,转到立即 window (Control + G)
    • 类型Application.LoadFromText acForm, "MyForm", CurrentProject.Path & "\MyForm.txt"
    • 反编译/紧凑修复/重新编译(参见文档中的其他示例)
    • 打开表格/报告进行测试。希望现在一切正常。
    • 删除旧的损坏表格(例如MyForm.bak)

防止将来出现这种损坏

报告/表单中二进制数据损坏的最常见原因是多台计算机/用户使用相同的数据库客户端文件,而不是拥有自己的单独副本。这就是为什么每个用户都应该在他们的桌面上有自己的客户端文件,他们 运行.

测试计算机内存

如果您的崩溃是随机的或偶发的,请执行此步骤。如果您每次 运行 数据库时都发生崩溃,那么此步骤将无法解决问题(尽管内存不足可能是首先发生损坏的原因)。

使用在操作系统之外启动的内存测试器,运行s 多次通过。两个流行的选择是 MemTest86 (Commercial) and MemTest86+(开源)

开始测试,让它在工作时间运行。这样做的原因是因为建筑物中的其他因素,例如电源电路上的噪音会导致内存错误,因此您要尽量保持变量不变。

如果您有内存错误,那么您需要确定是由于计算机内存错误还是其他一些因素。然而,这超出了本文档的范围。

备注

确保在测试时从等式中删除其他变量

网络损坏

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

企业建筑

如果您在使用 "computer builds" 的公司环境中,但反编译、测试内存或剥离二进制数据均未成功 - 请拒绝进行进一步测试,直到 IT 团队可以向用户提供使用仅安装了 Windows、Office 和服务包的测试机。

所有软件和更新都应手动安装,不要使用无人值守安装。请勿在此机器上安装杀毒软件进行测试。

了解许多 IT 部门只是尝试对构建采用一种放之四海而皆准的方法,并且他们的构建都是基于彼此的。随着时间的推移,软件冲突会直接导致 Access 崩溃或运行异常。

电源不好

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

另外,检查插入电源板或插座的电源线。确保量规和电压规格足够。 IT 部门经常将电源线插在工作站上,然后直接卸下机器。多年后,他们使用的是更强大的电源,但还没有换掉电缆。它有所作为。如有疑问,请带一根新的、更粗的电缆。

谢谢大家的回复。大家提到的建议我都没有去测试。

就我而言,在 VB 中,我 运行 调试并突出显示了我代码中的 2 个问题,因此我对它们进行了排序,现在它运行良好。

谢谢大家