Excel vba обратиться к именованному диапазону

Хитрости »

27 Июль 2013              306907 просмотров


Полагаю не совру когда скажу, что все кто программирует в VBA очень часто в своих кодах общаются к ячейкам листов. Ведь это чуть ли не основное предназначение VBA в Excel. В принципе ничего сложного в этом нет. Например, чтобы записать в ячейку A1 слово Привет необходимо выполнить код:

Range("A1").Value = "Привет"

Тоже самое можно сделать сразу для нескольких ячеек:

Range("A1:C10").Value = "Привет"

Если необходимо обратиться к именованному диапазону:

Range("Диапазон1").Select

Диапазон1 — это имя диапазона/ячейки, к которому надо обратиться в коде. Указывается в кавычках, как и адреса ячеек.
Но в VBA есть и альтернативный метод записи значений в ячейке — через объект Cells:

Cells(1, 1).Value = "Привет"

Синтаксис объекта Range:
Range(Cell1, Cell2)

  • Cell1 — первая ячейка диапазона. Может быть ссылкой на ячейку или диапазон ячеек, текстовым представлением адреса или имени диапазона/ячейки. Допускается указание несвязанных диапазонов(A1,B10), пересечений(A1 B10).
  • Cell2 — последняя ячейка диапазона. Необязательна к указанию. Допускается указание ссылки на ячейку, столбец или строку.

Синтаксис объекта Cells:
Cells(Rowindex, Columnindex)

  • Rowindex — номер строки
  • Columnindex — номер столбца

Исходя из этого несложно предположить, что к диапазону можно обратиться, используя Cells и Range:

'выделяем диапазон "A1:B10" на активном листе
Range(Cells(1,1), Cells(10,2)).Select

и для чего? Ведь можно гораздо короче:

Иногда обращение посредством Cells куда удобнее. Например для цикла по столбцам(да еще и с шагом 3) совершенно неудобно было бы использовать буквенное обозначение столбцов.
Объект Cells так же можно использовать для указания ячеек внутри непосредственно указанного диапазона. Например, Вам необходимо выделить ячейку в 3 строке и 2 столбце диапазона «D5:F56». Можно пройтись по листу и посмотреть, отсчитать нужное количество строк и столбцов и понять, что это будет «E7». А можно сделать проще:

Range("D5:F56").Cells(3, 2).Select

Согласитесь, это гораздо удобнее, чем отсчитывать каждый раз. Особенно, если придется оперировать смещением не на 2-3 ячейки, а на 20 и более. Конечно, можно было бы применить Offset. Но данное свойство именно смещает диапазон на указанное количество строк и столбцов и придется уменьшать на 1 смещение каждого параметра для получения нужной ячейки. Да и смещает на указанное количество строк и столбцов весь диапазон, а не одну ячейку. Это, конечно, тоже не проблема — можно вдобавок к этому использовать метод Resize — но запись получится несколько длиннее и менее наглядной:

Range("D5:F56").Offset(2, 1).Resize(1, 1).Select

И неплохо бы теперь понять, как значение диапазона присвоить переменной. Для начала переменная должна быть объявлена с типом Range. А т.к. Range относится к глобальному типу Object, то присвоение значения такой переменной должно быть обязательно с применением оператора Set:

Dim rR as Range
Set rR = Range("D5")

если оператор Set не применять, то в лучшем случае получите ошибку, а в худшем(он возможен, если переменной rR не назначать тип) переменной будет назначено значение Null или значение ячейки по умолчанию. Почему это хуже? Потому что в таком случае код продолжит выполняться, но логика кода будет неверной, т.к. эта самая переменная будет содержать значение неверного типа и применение её в коде в дальнейшем все равно приведет к ошибке. Только ошибку эту отловить будет уже сложнее.
Использовать же такую переменную в дальнейшем можно так же, как и прямое обращение к диапазону:

Вроде бы на этом можно было завершить, но…Это как раз только начало. То, что я написал выше знает практически каждый, кто пишет в VBA. Основной же целью этой статьи было пояснить некоторые нюансы обращения к диапазонам. Итак, поехали.

Обычно макрорекордер при обращении к диапазону(да и любым другим объектам) сначала его выделяет, а потом уже изменяет свойство или вызывает некий метод:

'так выглядит запись слова Test в ячейку А1
Range("A1").Select
Selection.Value = "Test"

Но как правило выделение — действие лишнее. Можно записать значение и без него:

'запишем слово Test в ячейку A1 на активном листе
Range("A1").Value = "Test"

Теперь чуть подробнее разберем, как обратиться к диапазону не выделяя его и при этом сделать все правильно. Диапазон и ячейка — это объекты листа. У каждого объекта есть родитель — грубо говоря это другой объект, который является управляющим для дочернего объекта. Для ячейки родительский объект — Лист, для Листа — Книга, для Книги — Приложение Excel. Если смотреть на иерархию зависимости объектов, то от старшего к младшему получится так:
Applicaton => Workbooks => Sheets => Range
По умолчанию для всех диапазонов и ячеек родительским объектом является текущий(активный) лист. Т.е. если для диапазона(ячейки) не указать явно лист, к которому он относится, в качестве родительского листа для него будет использован текущий — ActiveSheet:

'запишем слово Test в ячейку A1 на активном листе
Range("A1").Value = "Test"

Т.е. если в данный момент активен Лист1 — то слово Test будет записано в ячейку А1 Лист1. Если активен Лист3 — в А1 Лист3. Иначе говоря такая запись равносильна записи:

ActiveSheet.Range("A1").Value = "Test"

Поэтому выхода два — либо активировать сначала нужный лист, либо записать без активации.

'активируем Лист2
Worksheets("Лист2").Select
'записываем слово Test в ячейку A1
Range("A1").Value = "Test"

Чтобы не активируя другой лист записать в него данные, необходимо явно указать принадлежность объекта Range именно этому листу:

'запишем слово Test в ячейку A1 на Лист2 независимо от того, какой лист активен
Worksheets("Лист2").Range("A1").Value = "Test"

Таким же образом происходит считывание данных с ячеек — если не указывать лист, данные ячеек которого необходимо считать — считаны будут данные с ячейки активного листа. Чтобы считать данные с Лист2 независимо от того, какой лист активен применяется такой код:

'считываем значение ячейки A1 с Лист2 независимо от того, какой лист активен
MsgBox Worksheets("Лист2").Range("A1").Value

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

'запишем слово Test в ячейку A1 на Лист2 книги Книга2.xlsx независимо от того, какая книга и какой лист активен
Workbooks("Книга2.xlsx").Worksheets("Лист2").Range("A1").Value = "Test"
'считываем значение ячейки A1 с Лист2 книги Книга3.xlsx независимо от того, какой лист активен
MsgBox Workbooks("Книга3.xlsx").Worksheets("Лист2").Range("A1").Value

Важный момент: лучше всегда указать имя книги вместе с расширением(.xlsx, xlsm, .xls и т.д.). Если в настройках ОС Windows(Панель управленияПараметры папок -вкладка ВидСкрывать расширения для зарегистрированных типов файлов) указано скрывать расширения — то указывать расширение не обязательно — Workbooks(«Книга2»). Но и ошибки не будет, если его указать. Однако, если пункт «Скрывать расширения для зарегистрированных типов файлов» отключен, то указание Workbooks(«Книга2») обязательно приведет к ошибке.


Очень часто ошибки обращения к ячейкам листов и книг делают начинающие, особенно в циклах по листам. Вот пример неправильного цикла:

Dim wsSh As Worksheet
For Each wsSh In ActiveWorkbook.Worksheets
    Range("A1").Value = wsSh.Name 'записываем в ячейку А1 имя листа
    MsgBox Range("A1").Value 'проверяем, то ли имя записалось
Next wsSh

MsgBox будет выдавать правильные значения, но сами имена листов будут записываться не на каждый лист, а последовательно в ячейку активного листа. Поэтому на активном листе в ячейке А1 будет имя последнего листа.
А вот так выглядит правильный цикл:
Вариант 1 — активация листа(медленный)

Dim wsSh As Worksheet
For Each wsSh In ActiveWorkbook.Worksheets
    wsSh.Activate 'активируем каждый лист
    Range("A1").Value = wsSh.Name 'записываем в ячейку А1 имя листа
    MsgBox Range("A1").Value 'проверяем, то ли имя записалось
Next wsSh

Вариант 2 — без активации листа(быстрый и более правильный)

Dim wsSh As Worksheet
For Each wsSh In ActiveWorkbook.Worksheets
    wsSh.Range("A1").Value = wsSh.Name 'записываем в ячейку А1 имя листа
    MsgBox wsSh.Range("A1").Value 'проверяем, то ли имя записалось
Next wsSh

Важно: если код записан в модуле листа(правая кнопка мыши на листе-Исходный текст) и для объекта Range или Cells родитель явно не указан(т.е. нет имени листа и книги) — тогда в качестве родителя будет использован именно тот лист, в котором записан код, независимо от того какой лист активный. Иными словами — если в модуле листа записать обращение вроде Range(«A1»).Value = «привет», то слово привет всегда будет записывать в ячейку A1 именно того листа, в котором записан сам код. Это следует учитывать, когда располагаете свои коды внутри модулей листов.

В конструкциях типа Range(Cells(,),Cells(,)) Range является контейнером, в котором указываются ссылки на объекты, из которых и будет создана ссылка на непосредственно конечный объект.
Предположим, что активен «Лист1», а код запущен с листа «Итог».
Если запись будет вида

Sheets("Итог").Range(Cells(1, 1), Cells(10, 1))

это вызовет ошибку «Run-time error ‘1004’: Application-defined or object-defined error». А ошибка появляется потому, что контейнер и объекты внутри него не могут располагаться на разных листах, равно как и:

Sheets("Итог").Range(Cells(1, 1), Sheets("Итог").Cells(10, 1))
'запись ниже так же неверна
Range(Cells(1, 1), Sheets("Итог").Cells(10, 1))

т.к. ссылки на объекты внутри контейнера относятся к разным листам. Cells(1, 1) — к активному листу, а Sheets(«Итог»).Cells(10, 1) — к листу Итог.
А вот такие записи будут правильными:

Sheets("Итог").Range(Sheets("Итог").Cells(1, 1), Sheets("Итог").Cells(10, 1))
Range(Sheets("Итог").Cells(1, 1), Sheets("Итог").Cells(10, 1))

Вторая запись не содержит ссылки на родителя для Range, но ошибки это в большинстве случаев не вызовет — т.к. если для контейнера ссылка не указана, а для двух объектов внутри контейнера родитель один — он будет применен и для самого контейнера. Однако лучше делать как в первой строке — т.е. с обязательным указанием родителя для контейнера и для его составляющих. Т.к. при определенных обстоятельствах(например, если в момент обращения к диапазону активной является книга, открытая в режиме защищенного просмотра) обращение к Range без родителя может вызывать ошибку выполнения.
Если запись будет вида Range(«A1″,»A10»), то указывать ссылку на родителя внутри Range не обязательно — достаточно будет указать эту ссылку перед самим Range — Sheets(«Итог»).Range(«A1″,»A10»), т.к. текстовое представление адреса внутри Range не является объектом(у которого может быть какой-то родительский объект), что обязывает создать ссылку именно на родителя контейнера.

Разберем пример, приближенный к жизненной ситуации. Необходимо на лист Итог занести формулу вычитания, начиная с ячейки А2 и до последней заполненной. На момент записи активен Лист1. Очень часто начинающие записывают так:

Sheets("Итог").Range("A2:A" & Cells(Rows.Count, 1).End(xlUp).Row) _
                                        .FormulaR1C1 = "=RC2-RC11"

Запись смешанная — и текстовое представление адреса ячейки(«A2:A») и ссылка на объект Cells. В данном случае явную ошибку код не вызовет, но и работать будет не всегда так, как хотелось бы. А это самое плохое, что может случиться при разработке.
Sheets(«Итог»).Range(«A2:A» — создается ссылка на столбец "A" листа Итог. Но далее идет вычисление последней строки первого столбца. И вот как раз это вычисление происходит на основе объекта Cells, который не содержит в себе ссылки на родительский объект. А значит он будет вычислять последнюю строку исключительно для текущего листа(если код записан в стандартном модуле, а не модуле листа) — т.е. для Лист1. Правильно было бы записать так:

Sheets("Итог").Range("A2:A" & Sheets("Итог").Cells(Rows.Count, 1).End(xlUp).Row) _
                                                      .FormulaR1C1 = "=RC2-RC11"

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

lLastRow = Workbooks("Книга3.xls").Sheets("Лист1").Cells(Rows.Count, 1).End(xlUp).Row

с виду все нормально, но есть нюанс. Rows.Count по умолчанию будет относится к активной книге, если записано в стандартном модуле. Приведенный выше код должен работать с книгой формата 97-2003 и вычислить последнюю заполненную ячейку на листе1. В книгах формата Excel 97-2003(.xls) всего 65536 строк. Если в момент выполнения приведенной строки активна книга формата 2007 и выше(форматы .xlsx, .xlsm, .xlsb и пр) — то Rows.Count вернет 1048576, т.к. именно такое количество строк в листах книг версий Excel, начиная с 2007. И т.к. в книге, в которой мы пытаемся вычислить последнюю строку всего 65536 строк — получим ошибку 1004, т.к. не может быть номера строки 1048576 на листе с количеством строк 65536. Поэтому имеет смысл указывать явно откуда считывать Rows.Count:

lLastRow = Workbooks("Книга3.xls").Sheets("Лист1").Cells(Workbooks("Книга3.xls").Sheets("Лист1").Rows.Count, 1).End(xlUp).Row

или применить конструкцию With

With Workbooks("Книга3.xls").Sheets("Лист1")
    lLastRow = .Cells(.Rows.Count, 1).End(xlUp).Row
End With

Также не мешало бы упомянуть возможность выделения несмежного диапазона(часто его называют «рваным»). Это диапазон, который обычно привыкли выделять на листе при помощи зажатой клавиши Ctrl. Что это дает? Это дает возможность выделить одновременно ячейки A1 и B10 и записать значения только в них. Для этого есть несколько способов. Самый очевидный и описанный в справке — метод Union:

Union(Range("A1"), Range("B10")).Value = "Привет"

Однако существует и другой метод:

Range("A1,B10").Value = "Привет"

В чем отличие(я бы даже сказал преимущество) Union: можно применять в цикле по условию. Например, выделить в диапазоне A1:F50 только те ячейки, значение которых больше 10 и меньше 20:

Sub SelOne()
    Dim rCell As Range, rSel As Range
    For Each rCell In Range("A1:F50")
        If rCell.Value > 10 And rCell.Value < 20 Then
            If rSel Is Nothing Then
                Set rSel = rCell
            Else
                Set rSel = Union(rSel, rCell)
            End If
        End If
    Next rCell
    If Not rSel Is Nothing Then rSel.Select
End Sub

Конечно, можно и просто в Range через запятую передать все эти ячейки, сформировав предварительно строку. Но в случае со строкой действует ограничение: длина строки не должна превышать 255 символов.

Надеюсь, что после прочтения данной статьи проблем с обращением к диапазонам и ячейкам у Вас будет гораздо меньше.

Также см.:
Как определить последнюю ячейку на листе через VBA?
Как определить первую заполненную ячейку на листе?
Как из Excel обратиться к другому приложению


Статья помогла? Поделись ссылкой с друзьями!

  Плейлист   Видеоуроки


Поиск по меткам



Access
apple watch
Multex
Power Query и Power BI
VBA управление кодами
Бесплатные надстройки
Дата и время
Записки
ИП
Надстройки
Печать
Политика Конфиденциальности
Почта
Программы
Работа с приложениями
Разработка приложений
Росстат
Тренинги и вебинары
Финансовые
Форматирование
Функции Excel
акции MulTEx
ссылки
статистика

 

Alex_ST

Пользователь

Сообщений: 2746
Регистрация: 22.12.2012

На лицо ужасный, добрый внутри

Создаю в книге, например, на Лист1 именованный диапазон «RngSh1»  
Это по умолчанию получается именованный диапазон УРОВНЯ КНИГИ и ввод его имени в формулу ЛЮБОГО листа означает ссылку на указанный диапазон.  
А почему же в VBA тогда обращение из других модулей книги проходит без ошибки только с указанием имени листа, где расположен именованный диапазон?  
Ну, т.е. Sheets(«Лист1»).Range(«RngSh1»)  
Ведь имя входит в коллекцию Names и уникально в книге?  
Или я просто не правильно обращаюсь к диапазону?  
Вопрос не праздный. Просто лист с именованным диапазоном может быть переименован в процессе доработки таблицы. Не хотелось бы править код.  
Конечно, я могу обращаться к листу и по его CodeName, но это немного не удобно.

С уважением, Алексей (ИМХО: Excel-2003 — THE BEST!!!)
<#0>

 

слэн

Пользователь

Сообщений: 5192
Регистрация: 16.01.2013

 

слэн

Пользователь

Сообщений: 5192
Регистрация: 16.01.2013

или names(«RngSh1»).referstorange

 

Alex_ST

Пользователь

Сообщений: 2746
Регистрация: 22.12.2012

На лицо ужасный, добрый внутри

Круто!  
С Лист2  
[RngSh1].Address — проходит
а вроде бы то же самое  
Range(«RngSh1»).Address даёт ошибку…

С уважением, Алексей (ИМХО: Excel-2003 — THE BEST!!!)
<#0>

 

> А почему же в VBA тогда обращение из других модулей книги проходит без ошибки только с указанием имени листа, где расположен именованный диапазон?  
Ну, т.е. Sheets(«Лист1»).Range(«RngSh1»)  

  Ты имеешь в виду модули листа? Тут дело в том, что в модуле листа  
Range, Cells, Names  
без указания листа относятся к этому листу, т.е. эквивалентны  
Me.Range, Me.Cells, Me.Names.  
Поэтому, например, выражение Range(«Лист1!A1») в модуле Лист2 вызывает ошибку, т.к. означает  
Sheets(«Лист2»).Range(«RngSh1»)  

  Решение: ThisWorkbook.Names(«RngSh1»).RefersToRange

 

Юрий М

Модератор

Сообщений: 60570
Регистрация: 14.09.2012

Контакты см. в профиле

Если обращаюсь из стандартных модулей, то лист не указываю — всё работает.

 

Alex_ST

Пользователь

Сообщений: 2746
Регистрация: 22.12.2012

На лицо ужасный, добрый внутри

С Лист2  
Names(«RngSh1»).RefersToRange.Address даёт ошибку :(

С уважением, Алексей (ИМХО: Excel-2003 — THE BEST!!!)
<#0>

 

Alex_ST

Пользователь

Сообщений: 2746
Регистрация: 22.12.2012

На лицо ужасный, добрый внутри

Да, из стандартных модулей стандартное обращение  
Debug.Print Range(«RngSh1»).Value  
работает нормально.  
А из модулей листов и книги — только    
Debug.Print [RngSh1].Value

  И к стати, а как узнать имя листа, на котором лежит именованный диапазон?

С уважением, Алексей (ИМХО: Excel-2003 — THE BEST!!!)
<#0>

 

> С Лист2  
Names(«RngSh1»).RefersToRange.Address даёт ошибку :(  

  Еще раз: Names без квалификатора в Лист2 это Sheets(«Лист2»).Names, а имя расположено в книге. а не в листе. Поэтому  

  ThisWorkbook.Names(«RngSh1»).RefersToRange

 

Юрий М

Модератор

Сообщений: 60570
Регистрация: 14.09.2012

Контакты см. в профиле

MsgBox Range(«NNN»).Parent.Name

 

> как узнать имя листа, на котором лежит именованный диапазон?  

  ThisWorkbook.Names(«RngSh1»).RefersToRange.parent.name

 

Alex_ST

Пользователь

Сообщений: 2746
Регистрация: 22.12.2012

На лицо ужасный, добрый внутри

Алексей,  
спасибо.  
Просто привык, что практически всегда ThisWorkbook можно опускать…  
Оказывается, что не всегда…

С уважением, Алексей (ИМХО: Excel-2003 — THE BEST!!!)
<#0>

 

Alex_ST

Пользователь

Сообщений: 2746
Регистрация: 22.12.2012

На лицо ужасный, добрый внутри

{quote}{login=Юрий М}{date=14.07.2011 12:37}{thema=}{post}MsgBox Range(«NNN»).Parent.Name{/post}{/quote}  
это работает только из стандартного модуля…  
а вот так:  
MsgBox [RngSh1].Parent.Name
и из модулей других листов

С уважением, Алексей (ИМХО: Excel-2003 — THE BEST!!!)
<#0>

 

Юрий М

Модератор

Сообщений: 60570
Регистрация: 14.09.2012

Контакты см. в профиле

{quote}{login=Alex_ST}{date=14.07.2011 12:44}{thema=Re: }{post}{quote}{login=Юрий М}{date=14.07.2011 12:37}{thema=}{post}MsgBox Range(«NNN»).Parent.Name{/post}{/quote}это работает только из стандартного модуля…  
{/post}{/quote}  
Из из формы тоже :-)  
Алекс, откуда столько вредности (больше чем у меня)? :-))  
Был вопрос: «И к стати, а как узнать имя листа, на котором лежит именованный диапазон?» Был ответ… В вопросе есть указание ОТКУДА спрашивать?

 

Alex_ST

Пользователь

Сообщений: 2746
Регистрация: 22.12.2012

На лицо ужасный, добрый внутри

Спасибо, ребята, здорово помогли.    
А то затык был в табличке на работе: не хотел привязываться в коде к конкретной ячейке с обращением по её адресу. Ячейка могла переместиться, а лист переименоваться по ходу доработки под хотелки начальства.  
Сделал именованный диапазон, а обращаться к нему без ошибок получалось только с того же листа…  
Теперь дело пошло!  
Сейчас чуть допилю и пошлю начальству табличку «на поругание» :)

С уважением, Алексей (ИМХО: Excel-2003 — THE BEST!!!)
<#0>

 

VovaK

Пользователь

Сообщений: 1716
Регистрация: 01.01.1970

{quote}{login=Alex_ST}{date=14.07.2011 12:39}{thema=}{post}Алексей,  
спасибо.  
Просто привык, что практически всегда ThisWorkbook можно опускать…  
Оказывается, что не всегда…{/post}{/quote}  

  Алекс, если пишешь надстройку, то ThisWorkbook надо не нигде не забывать. Если конечно не обращаешься на активную книгу…

 

Alex_ST

Пользователь

Сообщений: 2746
Регистрация: 22.12.2012

На лицо ужасный, добрый внутри

#17

15.07.2011 08:36:51

Володя, спасибо за совет.  
Но надстройки я не пишу почему-то, хотя дело вообще-то не хитрое. Но предпочитаю делать макросы, хранящиеся в файлах у меня в копилке.  
Но там всё равно ведь при работе с данными, лежащими в другом обрабатываемом файле, приходится писАть Activeworkbook. Так что я об этом всегда помню когда работаю с данными внешних файлов. Но тут-то у меня затык встал с внутренними данными книги. Коллекция Names ведь одна на все листы книги. Вот я и пытался обращаться к её элементам напрямую, не указывая книгу.

С уважением, Алексей (ИМХО: Excel-2003 — THE BEST!!!)
<#0>

Вступление

Тема должна включать информацию, конкретно связанную с именованными диапазонами в Excel, включая методы создания, изменения, удаления и доступа к определенным именованным диапазонам.

Определить именованный диапазон

Использование именованных диапазонов позволяет описать значение содержимого ячейки (я) и использовать это определенное имя вместо фактического адреса ячейки.

Например, формулу =A5*B5 можно заменить на =Width*Height чтобы упростить чтение и понимание формулы.

Чтобы определить новый именованный диапазон, выберите ячейку или ячейки для имени, а затем введите новое имя в поле «Имя» рядом с панелью формул.

введите описание изображения здесь


Примечание. Именованные диапазоны по умолчанию относятся к глобальной области, что означает, что к ним можно получить доступ из любой точки книги. Старые версии Excel позволяют дублировать имена, поэтому необходимо избегать дублирования имен глобальной области, иначе результаты будут непредсказуемыми. Используйте вкладку «Диспетчер имен» на вкладке «Формулы», чтобы изменить область действия.

Создайте новый именованный диапазон под названием «MyRange», назначенный ячейке A1

ThisWorkbook.Names.Add Name:="MyRange", _
    RefersTo:=Worksheets("Sheet1").Range("A1")

Удалить определенный именованный диапазон по имени

ThisWorkbook.Names("MyRange").Delete

Доступ к именованному диапазону по имени

Dim rng As Range
Set rng = ThisWorkbook.Worksheets("Sheet1").Range("MyRange")
Call MsgBox("Width = " & rng.Value)

Доступ к названию диапазона с ярлыком

Как и любой другой диапазон , именованные диапазоны могут быть доступны напрямую с помощью ярлыка, который не требует создания объекта Range . Три строки из выдержки из вышеприведенного кода могут быть заменены одной строкой:

Call MsgBox("Width = " & [MyRange])

Примечание. Свойством по умолчанию для диапазона является его значение, поэтому [MyRange] совпадает с [MyRange].Value

Вы также можете вызвать методы в диапазоне. Следующий выбирает MyRange :

[MyRange].Select

Примечание. Одно предостережение состоит в том, что нотация ярлыка не работает со словами, которые используются в другом месте библиотеки VBA. Например, диапазон с именем Width не будет доступен как [Width] но будет работать, как ожидалось, при доступе через ThisWorkbook.Worksheets("Sheet1").Range("Width")

Управление именованным диапазоном (диапазонами) с помощью диспетчера имен

Вкладка «Формулы»> «Определенная группа имен»> «Диспетчер имен»

Именованный менеджер позволяет:

  1. Создайте или измените имя
  2. Создать или изменить ссылку на ячейку
  3. Создать или изменить область действия
  4. Удалить существующий именованный диапазон

введите описание изображения здесь


Named Manager предоставляет полезный быстрый поиск неработающих ссылок.

введите описание изображения здесь

Именованные массивы диапазонов

Примерный лист

введите описание изображения здесь


Код

Sub Example()
    Dim wks As Worksheet
    Set wks = ThisWorkbook.Worksheets("Sheet1")
    
    Dim units As Range
    Set units = ThisWorkbook.Names("Units").RefersToRange
    
    Worksheets("Sheet1").Range("Year_Max").Value = WorksheetFunction.Max(units)
    Worksheets("Sheet1").Range("Year_Min").Value = WorksheetFunction.Min(units)
End Sub

Результат

введите описание изображения здесь

title keywords f1_keywords ms.prod ms.assetid ms.date ms.localizationpriority

Refer to Named Ranges

vbaxl10.chm5204437

vbaxl10.chm5204437

excel

74119715-2208-b932-f47c-7fad334c3fc6

06/08/2017

high

Ranges are easier to identify by name than by A1 notation. To name a selected range, click the name box at the left end of the formula bar, type a name, and then press ENTER.

Note There are two types of named ranges: Workbook Named Range and WorkSHEET Specific Named Range.

Workbook Named Range

A Workbook Named Range references a specific range from anywhere in the workbook (it applies globally).

How to Create a Workbook Named Range:

As explained above, it is usually created entering the name into the name box to the left end of the formula bar. Note that no spaces are allowed in the name.

WorkSHEET Specific Named Range

A WorkSHEET Specific Named Range refers to a range in a specific worksheet, and it is not global to all worksheets within a workbook. Refer to this named range by just the name in the same worksheet, but from another worksheet you must use the worksheet name including «!» the name of the range (example: the range «Name» «=Sheet1!Name»).

The benefit is that you can use VBA code to generate new sheets with the same names for the same ranges within those sheets without getting an error saying that the name is already taken.

How to Create a WorkSHEET Specific Named Range:

  1. Select the range you want to name.
  2. Click on the «Formulas» tab on the Excel Ribbon at the top of the window.
  3. Click «Define Name» button in the Formula tab.
  4. In the «New Name» dialogue box, under the field «Scope» choose the specific worksheet that the range you want to define is located (i.e. «Sheet1»)- This makes the name specific to this worksheet. If you choose «Workbook» then it will be a WorkBOOK name).

Example, of WorkSHEET Specific Named Range: Selected range to name are A1:A10

Chosen name of range is «name» within the same worksheet refer to the named name mere by entering the following in a cell «=name», from a different worksheet refer to the worksheet specific range by included the worksheet name in a cell «=Sheet1!name».

Referring to a Named Range

The following example refers to the range named «MyRange» in the workbook named «MyBook.xls.»

Sub FormatRange() 
    Range("MyBook.xls!MyRange").Font.Italic = True 
End Sub

The following example refers to the worksheet-specific range named «Sheet1!Sales» in the workbook named «Report.xls.»

Sub FormatSales() 
    Range("[Report.xls]Sheet1!Sales").BorderAround Weight:=xlthin 
End Sub

To select a named range, use the GoTo method, which activates the workbook and the worksheet and then selects the range.

Sub ClearRange() 
    Application.Goto Reference:="MyBook.xls!MyRange" 
    Selection.ClearContents 
End Sub

The following example shows how the same procedure would be written for the active workbook.

Sub ClearRange() 
    Application.Goto Reference:="MyRange" 
    Selection.ClearContents 
End Sub

Sample code provided by: Dennis Wallentin, VSTO & .NET & Excel

This example uses a named range as the formula for data validation. This example requires the validation data to be on Sheet 2 in the range A2:A100. This validation data is used to validate data entered on Sheet 1 in the range D2:D10.

Sub Add_Data_Validation_From_Other_Worksheet()
'The current Excel workbook and worksheet, a range to define the data to be validated, and the target range
'to place the data in.
Dim wbBook As Workbook
Dim wsTarget As Worksheet
Dim wsSource As Worksheet
Dim rnTarget As Range
Dim rnSource As Range

'Initialize the Excel objects and delete any artifacts from the last time the macro was run.
Set wbBook = ThisWorkbook
With wbBook
    Set wsSource = .Worksheets("Sheet2")
    Set wsTarget = .Worksheets("Sheet1")
    On Error Resume Next
    .Names("Source").Delete
    On Error GoTo 0
End With

'On the source worksheet, create a range in column A of up to 98 cells long, and name it "Source".
With wsSource
    .Range(.Range("A2"), .Range("A100").End(xlUp)).Name = "Source"
End With

'On the target worksheet, create a range 8 cells long in column D.
Set rnTarget = wsTarget.Range("D2:D10")

'Clear out any artifacts from previous macro runs, then set up the target range with the validation data.
With rnTarget
    .ClearContents
    With .Validation
        .Delete
        .Add Type:=xlValidateList, _
             AlertStyle:=xlValidAlertStop, _
             Formula1:="=Source"
        
'Set up the Error dialog with the appropriate title and message
        .ErrorTitle = "Value Error"
        .ErrorMessage = "You can only choose from the list."
    End With
End With

End Sub

Looping Through Cells in a Named Range

The following example loops through each cell in a named range by using a For Each…Next loop. If the value of any cell in the range exceeds the value of Limit, the cell color is changed to yellow.

Sub ApplyColor() 
    Const Limit As Integer = 25 
    For Each c In Range("MyRange") 
        If c.Value > Limit Then 
            c.Interior.ColorIndex = 27 
        End If 
    Next c 
End Sub

About the Contributor

Dennis Wallentin is the author of VSTO & .NET & Excel, a blog that focuses on .NET Framework solutions for Excel and Excel Services. Dennis has been developing Excel solutions for over 20 years and is also the coauthor of «Professional Excel Development: The Definitive Guide to Developing Applications Using Microsoft Excel, VBA and .NET (2nd Edition).»

[!includeSupport and feedback]

Содержание

  1. excel-vba Именованные диапазоны
  2. Вступление
  3. Определить именованный диапазон
  4. Использование именных диапазонов в VBA
  5. Управление именованным диапазоном (диапазонами) с помощью диспетчера имен
  6. Ссылка на именованные диапазоны
  7. Именованный диапазон книги
  8. Именованный диапазон определенного листа
  9. Ссылка на именованный диапазон
  10. Циклический переход по ячейкам в именованном диапазоне
  11. Об участнике
  12. Поддержка и обратная связь
  13. Refer to Named Ranges
  14. Workbook Named Range
  15. WorkSHEET Specific Named Range
  16. Referring to a Named Range
  17. Looping Through Cells in a Named Range
  18. About the Contributor
  19. Support and feedback
  20. Именованные диапазоны

excel-vba
Именованные диапазоны

Вступление

Определить именованный диапазон

Использование именованных диапазонов позволяет описать значение содержимого ячейки (я) и использовать это определенное имя вместо фактического адреса ячейки.

Например, формулу =A5*B5 можно заменить на =Width*Height чтобы упростить чтение и понимание формулы.

Чтобы определить новый именованный диапазон, выберите ячейку или ячейки для имени, а затем введите новое имя в поле «Имя» рядом с панелью формул.

Примечание. Именованные диапазоны по умолчанию относятся к глобальной области, что означает, что к ним можно получить доступ из любой точки книги. Старые версии Excel позволяют дублировать имена, поэтому необходимо избегать дублирования имен глобальной области, иначе результаты будут непредсказуемыми. Используйте вкладку «Диспетчер имен» на вкладке «Формулы», чтобы изменить область действия.

Использование именных диапазонов в VBA

Создайте новый именованный диапазон под названием «MyRange», назначенный ячейке A1

Удалить определенный именованный диапазон по имени

Доступ к именованному диапазону по имени

Доступ к названию диапазона с ярлыком

Как и любой другой диапазон , именованные диапазоны могут быть доступны напрямую с помощью ярлыка, который не требует создания объекта Range . Три строки из выдержки из вышеприведенного кода могут быть заменены одной строкой:

Примечание. Свойством по умолчанию для диапазона является его значение, поэтому [MyRange] совпадает с [MyRange].Value

Вы также можете вызвать методы в диапазоне. Следующий выбирает MyRange :

Примечание. Одно предостережение состоит в том, что нотация ярлыка не работает со словами, которые используются в другом месте библиотеки VBA. Например, диапазон с именем Width не будет доступен как [Width] но будет работать, как ожидалось, при доступе через ThisWorkbook.Worksheets(«Sheet1»).Range(«Width»)

Управление именованным диапазоном (диапазонами) с помощью диспетчера имен

Вкладка «Формулы»> «Определенная группа имен»> «Диспетчер имен»

Именованный менеджер позволяет:

  1. Создайте или измените имя
  2. Создать или изменить ссылку на ячейку
  3. Создать или изменить область действия
  4. Удалить существующий именованный диапазон

Named Manager предоставляет полезный быстрый поиск неработающих ссылок.

Источник

Ссылка на именованные диапазоны

Диапазоны легче идентифицировать по имени, чем с помощью нотации A1. Чтобы присвоить имя выбранному диапазону, щелкните поле имени с левой стороны строки формул, введите имя и нажмите клавишу ВВОД.

Примечание Существует два типа именованных диапазонов: именованный диапазон книги и именованный диапазон для таблицы.

Именованный диапазон книги

Именованный диапазон книги относится к определенному диапазону в любом месте книги (применяется глобально).

Как создать именованный диапазон книги:

Как указано выше, обычно он создается путем ввода имени в поле «Имя» с левой стороны строки формул. Обратите внимание, что имя не может содержать пробелов.

Именованный диапазон определенного листа

Именованный диапазон определенного листа относится к диапазону конкретного листа и не является глобальным для всех листов в книге. Ссылайтесь на этот именованный диапазон только по имени на том же листе, но на другом листе необходимо использовать имя листа, включая «!», имя диапазона (например: «Имя» «=Лист1! Имя»).

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

Как создать именованный диапазон определенного листа:

  1. Выделите диапазон, которому нужно присвоить имя.
  2. Перейдите на вкладку «Формулы» на ленте Excel в верхней части окна.
  3. Нажмите кнопку «Присвоить имя» на вкладке формул.
  4. В диалоговом окне «Создание имени» в поле «Область» выберите конкретный лист, где расположен диапазон, которому нужно присвоить имя (например, «Лист1»), чтобы связать имя с этим листом. Если выбрать вариант «Книга», это будет имя книги.

Пример из worksheet Specific Именованный диапазон: выбранный диапазон для имени A1:A10

Выбранное имя диапазона — «Имя». В пределах одного листа ссылайтесь на именованный диапазон, просто введя в ячейку «=Имя». Из другого листа ссылайтесь на диапазон определенного листа, указав в ячейке имя листа: «= Лист1!Имя».

Ссылка на именованный диапазон

В следующем примере выполняется ссылка на диапазон с именем MyRange в книге с именем MyBook.xls.

В следующем примере выполняется ссылка на диапазон определенного листа с именем Sheet1!Sales в книге с именем Report.xls.

Чтобы выбрать именованный диапазон, используйте метод GoTo, который активирует книгу и лист, а затем выбирает диапазон.

В следующем примере показано, как можно написать эту же процедуру для активной книги.

Пример кода, предоставляемый: Деннис Валлентин(Dennis Wallentin), VSTO & .NET & Excel

В этом примере в качестве формулы для проверки данных используется именованный диапазон. В этом примере данные проверки должны быть на листе 2 в диапазоне A2:A100. Они используются для проверки данных, введенных на листе 1 в диапазоне D2:D10.

Циклический переход по ячейкам в именованном диапазоне

В приведенном ниже примере выполняется циклический переход по каждой ячейке именованного диапазона с помощью цикла For Each. Next. Если значение любой ячейки в диапазоне превышает значение Limit , цвет ячейки изменяется на желтый.

Об участнике

Деннис Валлентин является автором блога VSTO & .NET & Excel, в который основное внимание уделяется решениям платформа .NET Framework для Excel и службы Excel. Деннис разрабатывает решения Excel более 20 лет и также является соавтором книги «Professional Excel Development: The Definitive Guide to Developing Applications Using Microsoft Excel, VBA, and .NET (2nd Edition)».

Поддержка и обратная связь

Есть вопросы или отзывы, касающиеся Office VBA или этой статьи? Руководство по другим способам получения поддержки и отправки отзывов см. в статье Поддержка Office VBA и обратная связь.

Источник

Refer to Named Ranges

Ranges are easier to identify by name than by A1 notation. To name a selected range, click the name box at the left end of the formula bar, type a name, and then press ENTER.

Note There are two types of named ranges: Workbook Named Range and WorkSHEET Specific Named Range.

Workbook Named Range

A Workbook Named Range references a specific range from anywhere in the workbook (it applies globally).

How to Create a Workbook Named Range:

As explained above, it is usually created entering the name into the name box to the left end of the formula bar. Note that no spaces are allowed in the name.

WorkSHEET Specific Named Range

A WorkSHEET Specific Named Range refers to a range in a specific worksheet, and it is not global to all worksheets within a workbook. Refer to this named range by just the name in the same worksheet, but from another worksheet you must use the worksheet name including «!» the name of the range (example: the range «Name» «=Sheet1!Name»).

The benefit is that you can use VBA code to generate new sheets with the same names for the same ranges within those sheets without getting an error saying that the name is already taken.

How to Create a WorkSHEET Specific Named Range:

  1. Select the range you want to name.
  2. Click on the «Formulas» tab on the Excel Ribbon at the top of the window.
  3. Click «Define Name» button in the Formula tab.
  4. In the «New Name» dialogue box, under the field «Scope» choose the specific worksheet that the range you want to define is located (i.e. «Sheet1»)- This makes the name specific to this worksheet. If you choose «Workbook» then it will be a WorkBOOK name).

Example, of WorkSHEET Specific Named Range: Selected range to name are A1:A10

Chosen name of range is «name» within the same worksheet refer to the named name mere by entering the following in a cell «=name», from a different worksheet refer to the worksheet specific range by included the worksheet name in a cell «=Sheet1!name».

Referring to a Named Range

The following example refers to the range named «MyRange» in the workbook named «MyBook.xls.»

The following example refers to the worksheet-specific range named «Sheet1!Sales» in the workbook named «Report.xls.»

To select a named range, use the GoTo method, which activates the workbook and the worksheet and then selects the range.

The following example shows how the same procedure would be written for the active workbook.

Sample code provided by: Dennis Wallentin, VSTO & .NET & Excel

This example uses a named range as the formula for data validation. This example requires the validation data to be on Sheet 2 in the range A2:A100. This validation data is used to validate data entered on Sheet 1 in the range D2:D10.

Looping Through Cells in a Named Range

The following example loops through each cell in a named range by using a For Each. Next loop. If the value of any cell in the range exceeds the value of Limit , the cell color is changed to yellow.

About the Contributor

Dennis Wallentin is the author of VSTO & .NET & Excel, a blog that focuses on .NET Framework solutions for Excel and Excel Services. Dennis has been developing Excel solutions for over 20 years and is also the coauthor of «Professional Excel Development: The Definitive Guide to Developing Applications Using Microsoft Excel, VBA and .NET (2nd Edition).»

Support and feedback

Have questions or feedback about Office VBA or this documentation? Please see Office VBA support and feedback for guidance about the ways you can receive support and provide feedback.

Источник

Именованные диапазоны

Для чего вообще нужны именованные диапазоны? Обращение к именованному диапазону гораздо удобнее, чем прописывание адреса в формулах и VBA:

  • Предположим, что в формуле мы ссылаемся на диапазон A1:C10 (возможно даже не один раз). Для примера возьмем простую функцию СУММ(суммирует значения указанных ячеек):
    =СУММ( A1:C10 ; F1:K10 )
    Затем нам стало необходимо суммировать другие данные(скажем вместо диапазона A1:C10 в диапазоне D2:F11 ). В случае с обычным указанием диапазона нам придется искать все свои формулы и менять там адрес диапазона на новый. Но если назначить своему диапазону A1:C10 имя(к примеру ДиапазонСумм ), то в формуле ничего менять не придется — достаточно будет просто изменить ссылку на ячейки в самом имени один раз. Я привел пример с одной формулой — а что, если таких формул 10? 30?
    Примерно такая же ситуация и с использованием в кодах: указав имя диапазона один раз не придется каждый раз при изменении и перемещении этого диапазона прописывать его заново в коде.
  • Именованный диапазон не просто так называется именованным. Если взять пример выше — то отображение в формуле названия ДиапазонСумм куда нагляднее, чем A1:C10 . В сложных формулах куда проще будет ориентироваться по именам, чем по адресам. Почему удобнее: если сменить стиль отображения ссылок (подробнее про стиль), то диапазон A1:C10 будет выглядеть как-то вроде этого: R1C1:R10C3 . А если назначить имя — то оно как было ДиапазонСумм , так им и останется.
  • При вводе формулы/функции в ячейку, можно не искать нужный диапазон, а начать вводить лишь первые буквы его имени и Excel предложит его ко вводу:

    Данный метод доступен лишь в версиях Excel 2007 и выше

Как обратиться к именованному диапазону
Обращение к именованному диапазону из VBA

MsgBox Range(«ДиапазонСумм»).Address MsgBox [ДиапазонСумм].Address

Обращение к именованному диапазону в формулах/функциях

Если при указании диапазона в формуле выделить именованный диапазон, то его имя автоматически подставится в формулу вместо фактического адреса ячеек:

Ограничения, накладываемые на создание имен

  • В качестве имени диапазона не могут быть использованы словосочетания, содержащие пробел. Вместо него лучше использовать нижнее подчеркивание _ или точку: Name_1, Name.1
  • Первым символом имени должна быть буква, знак подчеркивания (_) или обратная косая черта (). Остальные символы имени могут быть буквами, цифрами, точками и знаками подчеркивания
  • Нельзя в качестве имени использовать зарезервированные в Excel константы — R, C и RC(как прописные, так и строчные). Связано с тем, что данные буквы используются самим Excel для адресации ячеек при использовании стиля ссылок R1C1 (читать подробнее про стили ссылок)
  • Нельзя давать именам названия, совпадающие с адресацией ячеек: B$100, D2(для стиля ссылок А1) или R1C1, R7(для стиля R1C1). И хотя при включенном стиле ссылок R1C1 допускается дать имени название вроде A1 или D130 — это не рекомендуется делать, т.к. если впоследствии стиль отображения ссылок для книги будет изменен — то Excel не примет такие имена и предложит их изменить. И придется изменять названия всех подобных имен. Если очень хочется — можно просто добавить нижнее подчеркивание к имени: _A1
  • Длина имени не может превышать 255 символов

Создание именованного диапазона
Способ первый
обычно при создании простого именованного диапазона я использую именно его. Выделяем ячейку или группу ячеек, имя которым хотим присвоить -щелкаем левой кнопкой мыши в окне адреса и вписываем имя, которое хотим присвоить. Жмем Enter:

Способ второй
Выделяем ячейку или группу ячеек. Жмем правую кнопку мыши для вызова контекстного меню ячеек. Выбираем пункт:

  • Excel 2007: Имя диапазона (Range Name)
  • Excel 2010: Присвоить имя (Define Name)


либо:
Жмем Ctrl + F3
либо:

  • 2007-2016 Excel : вкладка Формулы (Formulas)Диспетчер имен (Name Manager)Создать (New) (либо на той же вкладке сразу — Присвоить имя (Define Name) )
  • 2003 Excel : ВставкаИмяПрисвоить

Появляется окно создания имени

Имя (Name) — указывается имя диапазона. Необходимо учитывать ограничения для имен, которые я описывал в начале статьи.
Область (Scope) — указывается область действия создаваемого диапазона — Книга , либо Лист1 :

  • Лист1 (Sheet1) — созданный именованный диапазон будет доступен только из указанного листа. Это позволяет указать разные диапазоны для разных листов, но указав одно и тоже имя диапазона
  • Книга (Workbook) — созданный диапазон можно будет использовать из любого листа данной книги

Примечание (Comment) — здесь можно записать пометку о созданном диапазоне, например для каких целей планируется его использовать. Позже эту информацию можно будет увидеть из диспетчера имен ( Ctrl + F3 )
Диапазон (Refers to) — при данном способе создания в этом поле автоматически проставляется адрес выделенного ранее диапазона. Его можно при необходимости тут же изменить.

Изменение диапазона
Чтобы изменить имя Именованного диапазона, либо ссылку на него необходимо всего лишь вызывать диспетчер имен( Ctrl + F3 ), выбрать нужное имя и нажать кнопку Изменить (Edit. ) .
Изменить можно имя диапазона (Name) , ссылку (RefersTo) и Примечание (Comment) . Область действия (Scope) изменить нельзя, для этого придется удалить текущее имя и создать новое, с новой областью действия.

Удаление диапазона
Чтобы удалить Именованный диапазон необходимо вызывать диспетчер имен( Ctrl + F3 ), выбрать нужное имя и нажать кнопку Удалить (Delete. ) .

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

Статья помогла? Поделись ссылкой с друзьями!

Источник

Понравилась статья? Поделить с друзьями:
  • Excel vba масштаб листа
  • Excel vba обозначение пустой ячейки
  • Excel vba массивы списки
  • Excel vba обновление сводной таблицы
  • Excel vba массивы сортировка