Access中标签Click事件触发SetFocus运行时错误的求助
问题原因分析
这是因为标签属于非焦点控件,Access处理点击标签的事件流程和点击文本框、命令按钮这类焦点控件完全不同:
- 当点击焦点控件时,Access会先完成当前控件(myTextBox)的校验事件(BeforeUpdate/AfterUpdate),再将焦点转移到目标控件并执行其事件,流程清晰无冲突;
- 当点击标签时,Access会先触发myTextBox的Exit/AfterUpdate事件,紧接着执行标签的Click事件。此时你的校验代码里先强制将焦点移到
differentTextBox再切回myTextBox,而标签的Click事件又要把焦点移去differentTextBox,两个焦点操作在同一个事件周期内冲突,直接触发2110错误。
另外你的校验代码里differentTextBox.SetFocus完全是多余的——既然最终要把焦点留在myTextBox,没必要多此一举先移去其他控件,这也是加剧冲突的原因。
解决方案
方案1:优化校验代码(最简修复)
直接移除校验代码中多余的焦点跳转,同时用Nz处理空值避免Len(Null)报错:
Private Sub myTextBox_AfterUpdate() If Len(Nz(myTextBox, "")) <> 7 Then MsgBox "Entry must be 7 characters long" myTextBox.Undo myTextBox = Null myTextBox.SetFocus End If End Sub
方案2:用BeforeUpdate事件规范校验(推荐)
BeforeUpdate是Access控件校验的标准事件,通过Cancel=True可以直接取消值更新并保留焦点,完全避免焦点冲突:
Private Sub myTextBox_BeforeUpdate(Cancel As Integer) If Len(Nz(Me.myTextBox.Value, "")) <> 7 Then MsgBox "Entry must be 7 characters long" Cancel = True ' 取消当前更新操作 Me.myTextBox.Undo ' 恢复控件原有值 End If End Sub
用这个方法后,当用户输入不合法时,Access会自动把焦点锁定在myTextBox,标签的Click事件根本不会被触发(因为焦点无法离开myTextBox),从根源解决问题。
方案3:修改标签的Click事件逻辑
如果必须保留原有校验逻辑,可在标签点击时先检查myTextBox的合法性,避免无效的焦点跳转:
Private Sub myLabel_Click() If Len(Nz(myTextBox, "")) = 7 Then myLabel.Visible = False differentTextBox.SetFocus Else MsgBox "Entry must be 7 characters long" myTextBox.SetFocus End If End Sub
内容的提问来源于stack exchange,提问作者Jeremy
相关产品推荐
相关产品推荐

