Как ссылаться на именованный диапазон в VBA с неактивного листа? - PullRequest
1 голос
/ 07 октября 2019

Я вижу, что этот вопрос задан и получен ответ, но я что-то упустил! Чтобы использовать именованные диапазоны в моем VBA, я должен активировать лист перед использованием именованного диапазона, в противном случае он получает доступ к «тому же» диапазону на активном листе. Я:

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

Вот кодОн работает нормально, если я возвращаюсь в вызов worksheet.activate, но в противном случае он ссылается на диапазон на неправильном листе (активном).

    Sub UserForm_Initialize()
   ' Application.ScreenUpdating = False

    Dim r1 As Long, c1 As Long, r2 As Long, c2 As Long, rng1 As Range, rng2 As Range, s As Worksheet, initSheet As Worksheet

    Set s = Sheets("NamePlates")
    Set rng1 = s.Range("MasterStoreNamePlates")
    Set initSheet = Application.ActiveSheet

    r1 = rng1.Row
    c1 = rng1.Column
    r2 = r1 + storeCount - 1
    c2 = c1

    's.Activate
    With s
        listBoxStores.RowSource = .Range(.Cells(r1, c1), .Cells(r2, c2)).Address
    End With
    'initSheet.Activate

   ' Application.ScreenUpdating = True

End Sub

Не слишком сложно переключиться на другой лист длябыстрый поиск диапазона, но давай ... какой смысл называть диапазоны и делать имя глобальным, а все сообщения о «убедитесь, что имя установлено глобально», если мне все еще нужно пойти и переключить активный лист?

Заранее спасибо!

Обновление:

Sub UserForm_Initialize()

    Application.ScreenUpdating = False

    Dim rng1 As Range, rng2 As Range, sInd As Long, initSheet As Worksheet, s As Worksheet

    sInd = Sheets("NamePlates").index
    Set s = Sheets(sInd)
    Set rng1 = s.Range("NamePlates!MasterStoreNamePlates")
    Set initSheet = Application.ActiveSheet

       listBoxStores.RowSource = rng1.Range(s.Cells(1, 1), s.Cells(storeCount - 1, 1)).Address

    Application.ScreenUpdating = True

End Sub

Не дает другого результата. Это все еще обращается к активному листу. Если я изменю активный лист перед этим, он извлекает правильные данные, в противном случае он вытягивает диапазон из активного листа.

Я заметил, что s.Range("NamePlates!MasterStoreNamePlates") действительно дает мне правильный диапазон ... но потом, когдаЯ использую этот диапазон и делаю что-то относительно него, я теряю ссылку на лист. Поэтому я думаю, что, возможно, мое решение будет включать динамическое обновление именованного диапазона, и тогда этот метод должен работать. В настоящее время вы можете видеть, что я использую эту константу "storeCount", которая на самом деле не очень хороший способ сделать что-то. Это всего лишь мой хак для того, чтобы все заработало. Все другие предложенные методы терпят неудачу в моем случае по той же причине;даже если они дают хорошую ссылку на правильный диапазон, я теряю эту ссылку на лист, когда начинаю делать все, что определяет нужный диапазон, который на 12 строк длиннее указанного диапазона (таким образом, "storeCount" постоянная).

Если я не могу понять, как сделать динамически изменяемый именованный диапазон, я опубликую новый вопрос, но я видел кое-что об этом, поэтому я смогу заставить это работать, и я опубликую свое решениездесь ... или, если кто-то победит меня, я приму этот ответ, даже если он немного отличается от ОП.

Ответы [ 3 ]

2 голосов
/ 07 октября 2019
ThisWorkbook.Names("NamedRange").RefersToRange

Возвращает объект диапазона именованного диапазона.

1 голос
/ 08 октября 2019

Я добавляю другой ответ, так как исходный вопрос был значительно изменен. мне кажется, что вы слишком усложняете вопрос, который довольно прост, если вы его понимаете.

Прежде чем я объясню дальше, я думаю, что ваш подход заключается в установке ".RowSource" со свойством ".address". диапазона неверен, потому что свойство address не содержит ссылку на родительский лист, поэтому он всегда будет ссылаться на активный лист, даже если вы получили этот адрес из глобального диапазона wb. см. ниже:

enter image description here

Я надеюсь, что ниже будет полезно для вас, чтобы достичь того, что вы хотите. Нет диапазонов! Нет активаций! будь проще. я работаю с vba 12 лет и могу подсчитать в одной руке, сколько раз я использовал .activate & .select

Я инициализировал свою форму с 3 списками (i) статически жестко закодированный диапазон (ii)) именованный диапазон и (iii) динамический именованный диапазон.

Private Sub UserForm_Initialize()

  Dim addr1 As String
  Dim addr2 As String
  Dim addr3 As String

  addr1 = "LB!$A$1:$A$4"
  addr2 = "List.Items" ' named range defined as "=LB!$A$1:$A$3"
  addr3 = "List.Items.Dyn" ' dynamic named range defined as "=OFFSET(LB!$A$1,0,0,COUNTA(LB!$A:$A),1)"

  Me.testListBox1.RowSource = addr1
  Me.testListBox2.RowSource = addr2
  Me.testListBox3.RowSource = addr3

  Debug.Print Me.testListBox1.RowSource
  Debug.Print Me.testListBox2.RowSource
  Debug.Print Me.testListBox3.RowSource

End Sub

вот результат Debug.Print в ближайшем окне

Debug.Print result in immediate window

В моей пользовательской форме у меня заполнены три спискаиз тех же ячеек, но по-разному упоминаются в свойстве .RowSource. Он также работает независимо от того, какой лист является активным.

enter image description here

здесь я инициализирую ту же форму из другого листа

enter image description here

0 голосов
/ 07 октября 2019

почему вы хотите активировать листы, когда вы можете сделать:

listBoxStores.RowSource = s.Range(s.Cells(r1, c1), s.Cells(r2, c2)).Address

вместо:

With s
  listBoxStores.RowSource = .Range(.Cells(r1, c1), .Cells(r2, c2)).Address
End With
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...