VBA修改UserForm属性报错:_VBComponent对象Properties方法失败
我之前也碰到过一模一样的问题,尤其是在打开过UserForm的设计视图后,再运行修改属性的代码就会触发权限拒绝,甚至在出过问题的工作簿里新建UserForm也会中招。结合你的场景,我整理了几个靠谱的解决办法:
一、先搞清楚问题根源
当你在VBE里右键UserForm选择「查看对象」(也就是打开设计视图)时,Excel会锁定这个UserForm对应的VBComponent,防止设计操作和代码操作冲突。有时候即使你关闭了设计视图,这个锁定状态也没有被正确释放,尤其是在已经出过错误的工作簿里,可能存在VBProject的状态缓存异常,这时候再运行修改属性的代码就会触发"Permission Denied"。另外那个焦点错误也是设计视图打开后,控件处于设计状态导致的冲突,进而引发后续的权限问题。
二、具体解决方案
1. 强制关闭UserForm的设计视图再运行代码
运行修改属性的代码前,先确保UserForm的设计窗口是关闭的,甚至可以用代码自动检测并关闭:
Sub CloseUserFormDesignView() Dim vbComp As VBComponent Set vbComp = ThisWorkbook.VBProject.VBComponents("UserForm1") ' 检查设计视图是否打开,是就关闭 If vbComp.DesignMode Then On Error Resume Next ' 防止窗口已经被手动关闭的情况 Application.VBE.Windows(vbComp.Name).Close On Error GoTo 0 End If End Sub Sub myTest() ' 先关闭设计视图 CloseUserFormDesignView ' 再修改属性 ThisWorkbook.VBProject.VBComponents("UserForm1").Properties("Caption") = "myCaption" ThisWorkbook.VBProject.VBComponents("UserForm1").Properties("Width") = 300 ThisWorkbook.VBProject.VBComponents("UserForm1").Properties("Height") = 200 End Sub
2. 改用操作UserForm实例的方式(更稳定)
直接修改VBComponent的属性太容易受设计视图影响,不如通过操作UserForm的运行时实例来修改属性——如果你的需求是调整运行时显示效果,这种方式完全不受设计视图的限制:
Sub myTest() ' 先卸载已加载的UserForm实例 Dim uf As UserForm For Each uf In UserForms If uf.Name = "UserForm1" Then Unload uf Exit For End If Next uf ' 实例化UserForm并修改属性 Dim myUF As UserForm1 Set myUF = New UserForm1 myUF.Caption = "myCaption" myUF.Width = 300 myUF.Height = 200 ' 如果需要显示UserForm就取消下面的注释 ' myUF.Show ' 释放对象 Set myUF = Nothing End Sub
如果是要修改设计时的默认属性,那还是用第一种方法,但一定要确保设计视图是关闭的。
3. 修复出过问题的工作簿
对于那些已经"染病"的工作簿,单纯删UserForm重建可能没用,因为VBProject的状态已经损坏,你可以试试:
- 把原工作簿里的所有模块、UserForm、工作表内容,全部复制到一个全新的空白工作簿里,保存后再测试代码;
- 或者导出所有VB组件(右键组件选择「导出文件」),然后删除原工作簿里的这些组件,再重新导入导出的文件,修复可能的损坏。
4. 养成良好的操作习惯
运行修改UserForm属性的代码前,不要打开它的设计视图;如果不小心打开了,一定要彻底关闭设计窗口,再回到Excel界面运行代码,不要在VBE里直接运行。
内容的提问来源于stack exchange,提问作者Ryszard Jędraszyk

