Access 365中VBA错误2467:Me关键字在WithEvents事件中异常
Access 365 窗体事件接收间歇性崩溃问题排查
问题场景
frm_Session窗体通过WithEvents声明订阅事件,处理ChangedUnitInSession事件的代码如下:
Private Sub changePublisher_ChangedUnitInSession() Me.UsedTime = SessionUsedTime(getSessionTime) Me.UnitsInSession.Requery End Sub
该代码在Access 2003中运行正常,但迁移至Access 365后出现间歇性崩溃:首次、第三次打开窗体正常,第二次、第四次打开则触发运行时错误2467——「您输入的表达式引用了一个已关闭或不存在的对象」,报错指向Me关键字。
崩溃时即时窗口测试结果
? Me.UsedTime.Value = 错误2467 ? Me.Controls.Count = 错误2467 ? Me.Name = 错误2467 ? isMissing(Me) = False ? isObject(Me) = True ? TypeName(Me) = Form_frm_Session
已尝试的无效方案
- 将数据库从
.mdb格式转换为.accdb,问题仍存在 - 声明私有变量
Private myForm As Form_frm_Session,在Form_Load()中赋值myForm = Me并修改事件代码,仍每隔一次打开就崩溃;此时调用? myForm.Name或? myForm.Form.Name会触发错误5——「无效的过程调用或参数」
2024-09-04 更新信息
changePublisher_ChangedUnitInSession()由多个窗体及子窗体触发,frm_Session需接收所有这些事件。当事件由自身子窗体触发时,将原代码复制到公共子过程:
Public Sub updateSessionForm() ' 复制原事件处理代码,用于子窗体直接调用以规避事件订阅的bug Me.UsedTime.Value = SessionUsedTime(getSessionTime) Me.UnitsInSession.Requery End Sub
子窗体直接调用父窗体的updateSessionForm()时一切正常,Me引用无问题。由此推测问题出在事件的触发、传递与接收流程中。
排查思路
- 检查事件发布者生命周期:确认
changePublisher对象在frm_Session窗体打开/关闭时的创建、销毁逻辑是否正确,是否存在重复实例化或未正确释放的情况——尤其是偶数次打开窗体时,可能存在发布者与窗体实例的绑定关系异常 - 验证事件订阅时机:确保
WithEvents变量的赋值时机(如Form_Load或Form_Open)与窗体生命周期匹配,避免在窗体未完全初始化或已开始销毁时订阅/触发事件 - 对比Access版本事件模型差异:排查Access 2003与365在跨窗体/子窗体事件传递时的上下文差异,比如
Me的作用域、对象引用有效性的判断逻辑变化 - 添加事件上下文日志:在事件发布端和接收端记录日志(如当前窗体实例ID、发布者实例状态、事件触发时间),追踪偶数次崩溃时的上下文变化,定位异常触发的具体场景
- 测试单一路径事件触发:暂时只保留单个窗体/子窗体触发事件,逐步排查是否是某特定发布者的触发逻辑导致绑定异常
- 检查窗体卸载/关闭逻辑:确认frm_Session的
Form_Unload或Form_Close事件中是否有影响Me引用或事件订阅关系的代码,是否存在未清理的引用导致对象残留
内容的提问来源于stack exchange,提问作者Kevin
相关产品推荐
相关产品推荐

