繁体   English   中英

更改工作表代号运行时错误 9:下标超出范围

[英]Changing sheet codename Run-Time Error 9: Subscript out of range

我编写了代码,当我按下按钮时,会将新工作表添加到工作簿并更改工作表的代号,以便稍后在我的代码中更容易引用。

Dim wbk As Workbook
Dim wks As Worksheet

Set wbk = ThisWorkbook

wbk.Sheets.Add.Name = "Admin - Save Log"
Set wks = wbk.Worksheets("Admin - Save Log")
wks.Parent.VBProject.VBComponents(wks.CodeName).Name = "wksAdminSaveLog"

这确实有效 - 但是 - 仅当我打开“开发人员”窗口或以前打开它时。

如果我在第一次打开 Excel 文档(尚未打开“开发人员”窗口)时单击该按钮,它会添加工作表,但是会出现以下错误并且不会更改工作表的代号:

运行时错误“9”:下标超出范围

只有当我按下 Debug 并在“Developer”窗口再次打开后运行代码时,它才会添加代号。

有什么办法可以解决这个问题,这样用户就不必打开开发人员窗口就可以正常运行吗?

@Comintern 已经为您提供了一个有效的解决方案,但此代码不会污染您的立即窗口,并使用隐藏的_CodeName属性来更改工作表名称,而不是访问vbComponents集合。

它还使用早期绑定的Worksheet分配给wks ,然后使用With块,因为它正在访问wks 1 个以上成员。

有趣的是,VBProject 成员使用的位置很重要。

Dim wbk As Workbook
Dim wks As Worksheet

Set wbk = ThisWorkbook
Set wks = wbk.Worksheets.Add

'Oddly, this statement MUST appear AFTER the Worksheets.add
Debug.Assert wbk.VBProject.Name <> vbNullString 'Don't pollute the Immediate window

With wks
  .Name = "Admin - Save Log"
  .[_CodeName] = "wksAdminSaveLog"
End With

如果您需要打开 VBE,您可以“欺骗”调试上下文为您执行此操作。 这似乎通过强制VBE.MainWindow存在来完成项目需要更新其索引的任何事情:

Dim wbk As Workbook
Dim wks As Worksheet

Set wbk = ThisWorkbook

Set wks = wbk.Sheets.Add
wks.Name = "Admin - Save Log"
Debug.Print wbk.VBProject.VBE.MainWindow.Caption   '<--Force the VBE to exist.
wbk.VBProject.VBComponents(wks.CodeName).Name = "wksAdminSaveLog"

编辑:

似乎简单地获得对VBE.MainWindow的引用就足够了(见评论)。 这也有效:

Dim editor As Object
Set editor = wbk.VBProject.VBE.MainWindow   '<--Force the VBE to exist.

另一种强制刷新 VBComponents 集合的简单方法:

PropertyGetDiscard ThisWorkbook.VBProject.VBComponents.Count

Private Sub PropertyGetDiscard(AnyPropertyGet): End Sub

过程PropertyGetDiscard用于避免污染立即窗口或使用多余的变量

解决此类依赖于VBComponent 的代码问题的一般方法是使用此处给出VbeInit过程,该过程可以灵活地为每个可能尚未“ VBComponent初始化”的新打开的工作簿调用多次。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM