Excel VBA - косвенная ссылка на лист по его CodeName - PullRequest
2 голосов
/ 01 мая 2020

Есть ли способ косвенно ссылаться на лист по его CodeName, не просматривая каждый лист для проверки его CodeName? Например,

Метод 1: Следующий код не работает (хотя было бы идеально):

Dim ws As Worksheet

Set ws = "mySheet" & myVar

Метод 2: Но это работает (если вы жестко закодировали CodeName в):

Dim ws As Worksheet

Set ws = mySheetExample

Метод 3: И это работает (для динамического подхода c):

Dim ws As Worksheet

For Each sh In ThisWorkbook.Worksheets
    If sh.CodeName = "mySheet" & myVar Then
        'do something
    End If
Next

, который является действительно многословным способом ведения дел, что подводит меня к моему вопросу, почему первый метод не работает?

Ответы [ 2 ]

4 голосов
/ 01 мая 2020

Это не сработает, потому что вы пытаетесь присвоить строку объекту листа. Select Case - это путь к go. ИЛИ

Попробуйте это

Set ws = Sheets(ThisWorkbook.VBProject.VBComponents("mySheet" & myVar).Properties("Name").Value)

Более сложный пример

Option Explicit

Sub Sample()
    Dim ws As Worksheet
    Dim myVar As Long
    Dim shName As String

    myVar = 1

    shName = "Sheet" & myVar
    Set ws = Sheets(ThisWorkbook.VBProject.VBComponents(shName).Properties("Name").Value)

    Debug.Print ws.CodeName
End Sub

Чтобы это работало, включите "Доверительный доступ к проект VBA "

  1. Запустите Microsoft Excel.
  2. Открыть рабочую книгу.
  3. Нажмите Файл, а затем Параметры.
  4. На панели навигации выберите Центр управления безопасностью.
  5. Нажмите Настройки центра управления безопасностью ....
  6. На панели навигации выберите Настройки макроса.
  7. Убедитесь, что проверен доверительный доступ к объектной модели проекта VBA.
  8. Нажмите OK.

Если вы не знаете, что такое Доверяющий доступ к объектной модели проекта VBA , вы можете прочитать об этом в Включить или отключить макросы в файлах Office

2 голосов
/ 01 мая 2020

Вы упускаете точку свойства кодового имени.

Идея состоит в том, что он дает вам время компиляции , глобальный программный идентификатор проекта c, который вы можете использовать всякий раз, когда вам нужно обратиться к конкретному указанному c рабочему листу в ThisWorkbook (рабочая книга, содержащая ваш код VBA).

  • Метод 1 не работает, поскольку выражение "mySheet" & myVar оценивает значение String, и вы пытаетесь Set -присвоить эту строку в ссылку на объект Worksheet. VBA не может прочитать ваши мысли здесь, он видит строку с правой стороны, переменную Worksheet с левой стороны и не знает, что это значит.

  • Method2 создает локальную копию идентификатора, который уже является глобальным для проекта: он полностью избыточен и бесполезно сбивает с толку косвенное обращение, не делайте этого.

  • Method3 было бы лучше реализован как функция:

    Public Function GetSheetByCodeName(ByVal value As String) As Worksheet
        Dim sheet As Worksheet
        For Each sheet In ThisWorkbook.Worksheets
            If sheet.CodeName = value Then
                Set GetSheetByCodeName = sheet
                Exit Function
            End If
        Next
        Err.Raise 9 '"subscript out of range", specified name was not found.
    End Function
    

Тем не менее, принимая что-то, что проверено во время компиляции, и делая это во время выполнения, чувствует себя задом наперед. Это многогранный способ сделать что-то, потому что вы должны использовать этот идентификатор как .. идентификатор:

Sheet1.Range("SomeRange").Value = 42

Рабочие таблицы, которые существуют во ThisWorkbook во время компиляции, не должны Нужны любые сложные логи c для извлечения - они прямо там .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...