VBA用For Each遍历UserForm控件结束后报438错误如何解决?
问题根因
438错误由VBA的And运算符不支持短路逻辑导致:
VBA执行If A And B判断时,会同时计算A和B两个条件的结果,不会因为A已经不成立就跳过B的计算。
你的代码中,当遍历到Label、CommandButton这类没有Value属性的控件时,哪怕TypeName(ctrl) = "TextBox"已经判断为假,程序还是会强制执行Not ctrl.Value = ""的判断,调用不存在的Value属性就触发了报错。
修复方案
把单层条件判断拆为两层嵌套If,先校验控件类型,类型匹配后再判断控件值:
Private Sub SetCD_Click() Dim ctrl As Control For Each ctrl In Me.Controls ' 先判断控件类型,只有文本框才会进入下一层判断 If TypeName(ctrl) = "TextBox" Then If Not ctrl.Value = "" Then MsgBox ctrl.Value ' 原注释的业务逻辑可以放在这里 'Dim cell As Range 'For Each cell In inputws.Range("F:F") ' If cell.Value = ctrl.Value Then cell.Offset(0, 2).Value = CDDate.Value 'Next End If End If Next Unload Me End Sub
可选优化建议
- 可以用
TypeOf ctrl Is TextBox替代TypeName(ctrl) = "TextBox",判断控件类型的稳定性更高,不会因为类名拼写问题出错 - 原注释中遍历整列
F:F的逻辑效率很低,数据量大时建议用Range.Find方法匹配目标值,减少循环次数
内容的提问来源于stack exchange,提问作者Carlos Andres
相关产品推荐
相关产品推荐

