Названия листов вкладки Excel против имен таблиц Visual Basic
Похоже, что Visual Basic не может ссылаться на листы в соответствии с именами, измененными пользователем. На вкладках рабочего листа могут быть изменены их имена, но, похоже, Visual Basic по-прежнему считает имена рабочих листов Sheet1 и т.д., Несмотря на то, что вкладка рабочей книги была изменена на что-то полезное.
У меня есть это:
TABname = rng.Worksheet.Name ' Excel sheet TAB name, not VSB Sheetx name.
но я бы хотел использовать имена листов в подпрограммах Visual Basic. Самое лучшее, что я мог донести до сих пор, - это выбрать "Задать вкладку" Рабочий стол "и имена Visual Basic, что не делает мой день.
Visual Basic должен знать имена Sheet1, Sheet2 и т.д., Имена. Как я могу связать их с именами вкладок Excel, так что мне не нужно поддерживать таблицу поиска, которая меняется при переименовании каждого нового листа или листа?
Заранее благодарю за ваши ответы.
Ответы
Ответ 1
В объектной модели Excel рабочий лист имеет два разных свойства имени:
Рабочий лист .Name
Worksheet.CodeName
Свойство Name используется для чтения/записи и содержит имя, которое отображается на вкладке листа. Он изменен пользователем и VBA.
Свойство CodeName доступно только для чтения
Вы можете ссылаться на конкретный
Рабочие листы ( "Фред" ). Диапазон ( "A1" ), где Fred - это свойство .Name
или как
Sheet1.Range( "A1" ), где Sheet1 является кодовым именем рабочего листа.
Ответ 2
Вы должны иметь возможность ссылаться на листы по предоставленному пользователем имени. Вы уверены, что ссылаетесь на правильную книгу? Если в то время, когда вы ссылаетесь на лист, у вас открыто несколько книг, это может вызвать определенную проблему.
Если это проблема, следует использовать ActiveWorkbook
(текущая рабочая книга) или ThisWorkbook
(рабочая книга, содержащая макрос).
Например,
Set someSheet = ActiveWorkbook.Sheets("Custom Sheet")
Ответ 3
Это приведет к изменению всех имен объектов листа (с точки зрения редактора VBA) в соответствии с именами их листов (с точки зрения Excel):
Sub ZZ_Reset_Sheet_CodeNames()
'Changes the internal object name (codename) of each sheet to it conventional name (based on it sheet name)
Dim varItem As Variant
For Each varItem In ThisWorkbook.VBProject.VBComponents
'Type 100 is a worksheet
If varItem.Type = 100 And varItem.Name <> "ThisWorkbook" Then
varItem.Name = varItem.Properties("Name").Value
End If
Next
End Sub
Важно отметить, что имя объекта (кодовое имя) "(Имя)" переопределяется именем свойства "Имя", поэтому на него должно ссылаться как суб-свойство.
Ответ 4
На самом деле имя объекта/кода "Sheet1" можно изменить. В VBA нажмите "Лист1" в списке "Объекты Excel". В окне свойств вы можете изменить Sheet1, чтобы сказать rng.
Затем вы можете ссылаться на rng как на глобальный объект, не создавая сначала первую переменную. Поэтому debug.print rng.name работает отлично. Больше нет Рабочие листы ( "rng" ). Name.
В отличие от вкладки, имя объекта имеет те же ограничения, что и другие переменные (т.е. пробелы).
Ответ 5
Это очень простое решение (возможно, мне не хватает полной точки вопроса). ActiveSheet.Name будет ВОЗВРАТИТЬ строку текущего имени вкладки (и будет отражать любые будущие изменения пользователя). Я просто вызываю активный лист, задаю переменную, а затем использую ее как объект Worksheets. Здесь я извлекаю данные из таблицы, чтобы настроить отчет для деления. Этот макрос будет работать на любом листе в моей книге, который отформатирован для того же фильтра (критерии и copytorange) - каждое подразделение получает свой собственный лист и может изменять критерии и обновлять, используя этот единственный макрос.
Dim currRPT As String
ActiveSheet.Select
currRPT = (ActiveSheet.Name)
Range("A6").Select
Selection.RemoveSubtotal
Selection.AutoFilter
Range("PipeData").AdvancedFilter Action:=xlFilterCopy, CriteriaRange:=Range _
("C1:D2"), CopyToRange:=Range("A6:L9"), Unique:=True
Worksheets(currRPT).AutoFilter.Sort.SortFields.Clear
Worksheets(currRPT).AutoFilter.Sort.SortFields.Add Key:= _
Range("C7"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _
xlSortNormal
Ответ 6
Есть (по крайней мере) два разных способа добраться до объекта Worksheet
- через коллекции
Sheets
или Worksheets
, как указано DanM
- по именам неквалифицированных объектов
Когда создается новая книга с тремя рабочими листами, существует четыре объекта, к которым вы можете получить доступ через неквалифицированные имена: ThisWorkbook
; Sheet1
; Sheet2
; Sheet3
. Это позволяет писать такие вещи:
Sheet1.Range("A1").Value = "foo"
Хотя это может показаться полезным ярлыком, проблема возникает, когда рабочие листы переименовываются. Неквалифицированное имя объекта остается Sheet1
, даже если рабочий лист переименовывается в нечто совершенно другое.
В этом есть некоторая логика, потому что:
- имена рабочих листов не соответствуют тем же правилам, что и имена переменных
- вы можете случайно замаскировать существующую переменную
Например (протестирован в Excel 2003), создайте новый Workbook
с тремя рабочими листами. Создайте два модуля. В одном модуле объявите это:
Public Sheet4 As Integer
В другом модуле:
Sub main()
Sheet4 = 4
MsgBox Sheet4
End Sub
Запустите это, и поле сообщения должно появиться правильно.
Теперь добавьте четвертый рабочий лист в книгу, которая создаст объект Sheet4
. Попробуйте запустить main снова, и на этот раз вы получите ошибку "Объект не поддерживает это свойство или метод"
Ответ 7
Мне приходилось прибегать к этому, но это имеет проблемы с содержанием.
Function sheet_match(rng As Range) As String ' Converts Excel TAB names to the required VSB Sheetx names.
TABname = rng.Worksheet.Name ' Excel sheet TAB name, not VSB Sheetx name. Thanks, Bill Gates.
' Next, match this Excel sheet TAB name to the VSB Sheetx name:
Select Case TABname 'sheet_match
Case Is = "Sheet1": sheet_match = "Sheet1" ' You supply these relationships
Case Is = "Sheet2": sheet_match = "Sheet2"
Case Is = "TABnamed": sheet_match = "Sheet3" 'Re-named TAB
Case Is = "Sheet4": sheet_match = "Sheet4"
Case Is = "Sheet5": sheet_match = "Sheet5"
Case Is = "Sheet6": sheet_match = "Sheet6"
Case Is = "Sheet7": sheet_match = "Sheet7"
Case Is = "Sheet8": sheet_match = "Sheet8"
End Select
End Function
Ответ 8
Использование кодового имени листа было ответом, который мне также нужен, чтобы остановить падение макросов - ccampj ответить выше зеркал это решение (с экраном фото)