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
相关产品推荐
相关产品推荐

