Когда рабочим листам присваивается свойство.CodeName?
Итак, в процессе моего VBA здесь, в моей книге есть подпрограмма, которая создает лист и динамически добавляет код к этому событию активации новых листов. Это довольно круто на самом деле. Однако у меня возникает проблема с кодовым именем листов, когда новому листу не присваивается кодовое имя, когда я на него ссылаюсь.
Код, используемый для получения ссылки на новый модуль кода листа: With ActiveWorkbook.VBProject.VBComponents(CName).CodeModule
где CName - это кодовое имя листов.
Я получаю CName с: CName = Workbooks(ExcelFormName).Sheets(NewSheetName).CodeName
Где NewSheetName является глобальной константой. Это всегда работает, потому что этот код выполняется в той же функции, что и создание листа, поэтому у пользователя не было возможности переименовать лист.
В ходе тестирования (включая удаление волос) я обнаружил, что при создании листа: Set ws = Sheets.Add(, After:=Sheets(Worksheets.count))
листу не было присвоено кодовое имя, если не было открыто окно vbe.. я использовал debug.print "Test " & ws.codename
чтобы подтвердить, что кодовое имя было пустым - ""
поэтому, когда я попытался сослаться на лист, используя кодовое имя, я получил ошибку. То, что я нашел, я мог сделать, это:
Application.VBE.MainWindow.Visible = True
Application.VBE.MainWindow.WindowState = vbext_ws_Minimize
перед тем, как создать лист, нужно быстро открыть и свернуть окно VBE (позже я его закрываю), которое мне не понравилось, но оно работало. Но сейчас я сталкиваюсь с проблемами, когда у некоторых пользователей есть настройки безопасности, которые не позволяют открывать окно vbe.
Я заметил, только сейчас, если я переберу все vbcomponents в моей книге, даже не выполняя такую обработку, как:
Dim test As VBComponent
For Each test In ActiveWorkbook.VBProject.VBComponents
Next
затем, после этого, на листе есть кодовое имя. Поэтому мне интересно, что я могу сделать, кроме циклического прохождения по таким компонентам, чтобы убедиться, что на новом листе есть кодовое имя, и без этого, когда рабочий лист работает нормально? получить его кодовое имя, если окно VBE не открыто?
редактировать
Изображение результатов вашего предложения siddharth:
Вы можете видеть, я добавил ваше предложение, я получил ошибку 9, ошибка индекса вне диапазона
Edit2
Dim CName As Variant
CName = Workbooks(ExcelFormName).Sheets(NewSheetName).CodeName
With ActiveWorkbook.VBProject.VBComponents(CName).CodeModule
StartLine = .CreateEventProc("Activate", "worksheet") + 1
.InsertLines StartLine, "Dim numRows As Long"
.InsertLines StartLine + 1, "Dim numColumns as long"
.InsertLines StartLine + 2, "numRows = 0"
.InsertLines StartLine + 3, "numColumns = 0"
'mode codez
Я динамически добавляю код в событие активации новых листов. Я бы добавил это нормально, но этот лист удаляется, когда пользователь закрывает книгу. Этот конкретный лист не нужен все время, поэтому я не хочу его там, если это не нужно конкретному пользователю:)
2 ответа
Да, это очень старая проблема. Чтобы получить доступ к кодовому имени, используйте этот
Dim ws As Worksheet
Set ws = Sheets.Add(, After:=Sheets(Worksheets.count))
Msgbox ThisWorkbook.VBProject.VBComponents(ws.Name).Properties("Codename")
Однако, чтобы этот код работал, вы должны проверить Trust access to the VBA-Project Object model
Подводя итог для тех, кто читает еще, после создания листа:
Dim ws As Worksheet
Set ws = Sheets.Add(, After:=Sheets(Worksheets.count))
использовать: ws.name = ThisWorkbook.VBProject.VBComponents(ws.Name).Properties("Codename")
он не должен изменять имя листов, так как перед переименованием нового листа имя совпадает с кодовым именем, но это заставит приложение назначить кодовое имя, а не ждать, пока весь код будет запущен.
если выполнение кода вроде msgbox ws.codename
без предварительного что-то делать с ThisWorkbook.VBProject.VBComponents(ws.Name).Properties("Codename")
затем ws.codename
будет пустым