You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Access中如何在未处理错误后保留组合框自定义类的对象引用

如何在未处理错误后保留组合框的自定义类事件关联

我想创建一个自定义类统一处理所有组合框的事件,同时保留每个组合框自身的独立事件处理逻辑。目前的实现方式是:创建自定义类并添加事件处理程序,将所有组合框初始化到该类中,再把这些自定义对象存入集合。这种方式正常运行时,组合框更新会先执行自身的AfterUpdate/BeforeUpdate事件,再执行自定义类的对应事件。

但问题是,一旦发生未处理错误,存储自定义对象的集合会被销毁,导致组合框和自定义类的关联失效。后续用户操作时,只会触发组合框自身的事件处理程序,自定义类的统一逻辑不再执行。

我试过TempVars、数据库属性和隐藏窗体,但TempVars只能存值不能存对象引用,其他方式也无法存储对象变量。有没有办法在未处理错误后依然保留这些对象引用?


自定义类(TestClass)代码

Option Compare Database
Private WithEvents mCmbo As ComboBox

Public Property Get Combo() As ComboBox
Set Combo = mCmbo
End Property

Public Property Set Combo(ByVal TheCombo As ComboBox)
Set mCmbo = TheCombo
End Property

Public Sub Initialize(TheCombo As ComboBox)
Set Me.Combo = TheCombo
Me.Combo.OnEnter = "[Event Procedure]"
Me.Combo.BeforeUpdate = "[Event Procedure]"
Me.Combo.AfterUpdate = "[Event Procedure]"
End Sub


'------------------------------------------------------ Trap Events --------------------------------------
Private Sub mCmbo_BeforeUpdate(Cancel As Integer)
MsgBox "Before update Trapped in custom class "
End Sub

Private Sub mCmbo_AfterUpdate()
MsgBox "After update Trapped in custom class."
End Sub

窗体初始化代码

Private Sub Form_Load()
Dim ctrl As Control
'Assigning the custom class to the combo box
For Each ctrl In Forms!Form1.Controls
    If ctrl.ControlType = acComboBox Then
        Debug.Print ctrl.Name
        Set CC = New TestClass
        CC.Initialize ctrl
        ccCollection.Add CC
    End If
Next ctrl
End Sub

Private Sub Combo4_AfterUpdate()
MsgBox "Combo update event"
End Sub

Private Sub Combo4_BeforeUpdate(Cancel As Integer)
MsgBox "Combo BeforeUpdate event"
End Sub

解决方法

1. 添加全局错误处理,阻止集合销毁

Access中未处理错误会清除当前作用域的变量(包括窗体模块内的集合),因此必须添加全局错误捕获逻辑,避免错误触发变量重置:

  • 在标准模块中定义全局错误处理程序:
Option Compare Database
Option Explicit

Public Sub GlobalErrorHandler(ByVal procName As String, ByVal errNum As Long, ByVal errDesc As String)
    ' 记录错误信息
    Debug.Print "错误: " & errNum & " - " & errDesc & " | 过程: " & procName
    ' 阻止错误扩散导致的变量销毁
    Resume Next
End Sub
  • 在所有窗体、类模块的每个过程中添加错误捕获,以窗体Form_Load为例:
Private Sub Form_Load()
On Error GoTo ErrorHandler
Dim ctrl As Control
For Each ctrl In Forms!Form1.Controls
    If ctrl.ControlType = acComboBox Then
        Debug.Print ctrl.Name
        Set CC = New TestClass
        CC.Initialize ctrl
        ccCollection.Add CC
    End If
Next ctrl

ExitHandler:
    Exit Sub
ErrorHandler:
    GlobalErrorHandler "Form_Load", Err.Number, Err.Description
    Resume ExitHandler
End Sub

2. 将集合移至全局作用域

把存储自定义类对象的ccCollection定义在标准模块的全局变量中,而非窗体模块内。这样即使窗体模块因错误重置,全局集合仍会保留:

' 标准模块中
Option Compare Database
Option Explicit

Public ccCollection As New Collection

3. 错误后自动重新初始化关联

如果无法完全避免对象丢失,可在全局错误处理中触发重新初始化逻辑:

  • 修改全局错误处理程序,添加重新初始化逻辑:
Public Sub GlobalErrorHandler(ByVal procName As String, ByVal errNum As Long, ByVal errDesc As String)
    Debug.Print "错误: " & errNum & " - " & errDesc & " | 过程: " & procName
    ' 若目标窗体已加载,重新初始化组合框关联
    If CurrentProject.AllForms("Form1").IsLoaded Then
        Forms("Form1").ReInitializeCombos
    End If
    Resume Next
End Sub
  • 在窗体模块中添加重新初始化方法:
Public Sub ReInitializeCombos()
    Dim ctrl As Control
    ' 清空旧对象,避免重复关联
    ccCollection.Clear
    For Each ctrl In Me.Controls
        If ctrl.ControlType = acComboBox Then
            Set CC = New TestClass
            CC.Initialize ctrl
            ccCollection.Add CC
        End If
    Next ctrl
End Sub

内容的提问来源于stack exchange,提问作者Abdul

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 16:55:25