更改sheet代号运行-时间错误9:下标超出范围
Changing sheet codename Run-Time Error 9: Subscript out of range
我编写了代码,当我按下一个按钮时,它将向工作簿添加一个新的 sheet 并更改 sheet 的代号,以便以后在我的工作簿中更容易参考代码。
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"
这确实有效 - 但是 - 只有当我打开 "Developer" window 或之前已经打开它时。
如果我在第一次打开 Excel 文档(没有打开 "Developer" window)时单击按钮,它会添加 sheet,但是它会出现出现以下错误,并且不会更改 sheet:
的代号
Run-time error '9': Subscript out of range
只有当我按调试然后运行 "Developer" window 之后的代码再次打开时,它才会添加代号。
有没有什么办法可以让用户不必打开开发人员 window 即可正确 运行?
如果您需要打开 VBE,您可以 "trick" 调试上下文为您完成。这似乎通过强制 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.
@Comintern 已经为您提供了一个可行的解决方案,但此代码不会污染您的即时 Window,并使用隐藏的 _CodeName
属性 来更改 sheet 名称而不是访问 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
另一种强制刷新 VBComponents 集合的简单方法:
PropertyGetDiscard ThisWorkbook.VBProject.VBComponents.Count
Private Sub PropertyGetDiscard(AnyPropertyGet): End Sub
过程PropertyGetDiscard
用于避免污染立即数window或使用多余的变量
解决此类 VBComponent 相关代码问题的一般方法是使用灵活的 为每个可能尚未“VBComponent-initialized”的新打开的工作簿调用多次。
我编写了代码,当我按下一个按钮时,它将向工作簿添加一个新的 sheet 并更改 sheet 的代号,以便以后在我的工作簿中更容易参考代码。
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"
这确实有效 - 但是 - 只有当我打开 "Developer" window 或之前已经打开它时。
如果我在第一次打开 Excel 文档(没有打开 "Developer" window)时单击按钮,它会添加 sheet,但是它会出现出现以下错误,并且不会更改 sheet:
的代号Run-time error '9': Subscript out of range
只有当我按调试然后运行 "Developer" window 之后的代码再次打开时,它才会添加代号。
有没有什么办法可以让用户不必打开开发人员 window 即可正确 运行?
如果您需要打开 VBE,您可以 "trick" 调试上下文为您完成。这似乎通过强制 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.
@Comintern 已经为您提供了一个可行的解决方案,但此代码不会污染您的即时 Window,并使用隐藏的 _CodeName
属性 来更改 sheet 名称而不是访问 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
另一种强制刷新 VBComponents 集合的简单方法:
PropertyGetDiscard ThisWorkbook.VBProject.VBComponents.Count
Private Sub PropertyGetDiscard(AnyPropertyGet): End Sub
过程PropertyGetDiscard
用于避免污染立即数window或使用多余的变量
解决此类 VBComponent 相关代码问题的一般方法是使用灵活的