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

强颜欢笑 提交于 2019-12-19 05:45:12

问题


I've code which, when I press a button, will add a new sheet to a workbook and change the codename of the sheet to make it easier to refer to later in my code.

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"

This does work - HOWEVER - only when I have the "Developer" window open or have previously had it open.

If I click the button when I first open the Excel document (having not opened the "Developer" window) it adds the sheet, however it comes up with the following error and does not change the codename of the sheet:

Run-time error '9': Subscript out of range

It is only when I press Debug and then run the code after the "Developer" window is open again that it adds the codename.

Is there any way around this so that the user does not have to have the developer window open in order for it to run correctly?


回答1:


@Comintern already got you a working solution, but this code doesn't pollute your Immediate Window, and uses the hidden _CodeName property to change the sheet name instead of accessing the vbComponents collection.

It also uses an early-bound Worksheet assignment to wks, and then a With block because it is accessing more than 1 member of wks.

Interestingly, the placement of the VBProject member usage is important.

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



回答2:


If you need the VBE to have been opened, you can "trick" the debugging context into doing it for you. This seems to do whatever the project needs to update its indexing by forcing the VBE.MainWindow into existence:

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"

Edit:

It seems that simply obtaining the reference to the VBE.MainWindow is enough (see the comments). This also works:

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



回答3:


Another simple method to force refreshing of the VBComponents Collection:

PropertyGetDiscard ThisWorkbook.VBProject.VBComponents.Count

 

Private Sub PropertyGetDiscard(AnyPropertyGet): End Sub

The procedure PropertyGetDiscard is used to avoid polluting the Immediate window or using a superfluous variable




回答4:


A general approach to solve such VBComponent-dependent code problems is to use the VbeInit procedure given here that is flexible to be called multiple times for each newly opened workbook that may not yet be "VBComponent-initialized".



来源:https://stackoverflow.com/questions/41022319/changing-sheet-codename-run-time-error-9-subscript-out-of-range

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!