Vba excel select или activate

Хитрости »

26 Июль 2015              77781 просмотров


Все начинающие изучать VBA сталкиваются с тем, что записанные через макрорекордер коды пестрят методами Select и Activate.
Если не знакомы с работой макрорекордера — Что такое макрос и где его искать?
Это значительно ухудшает читабельность кода и, как ни странно — быстродействие. Но есть недостатки и куда более критичные. Если код выполняется достаточно долго и он постоянно что-то выделяет — пользователь может заскучать и забыться и начнет тыкать мышкой по листам и ячейкам, выделяя не то, что выделил ранее код. Что повлечет ошибки логики. Т.е. код может и выполнится, но совершенно не так, как ожидалось. Поэтому избавляться от Select и Activate необходимо везде, где это возможно.

Для начала рассмотрим два кода, выполняющие одни те же действия — запись в ячейку А3 листа Лист2 слова «Привет». При этом сам код запускается с Лист1 и после выполнения код Лист1 должен остаться активным. Чтобы сделать эти действия вручную потребуется сначала перейти на Лист2, выделить ячейку А3, записать в неё слово «Привет» и вернуться на Лист1. Поэтому запись макрорекордером этих действий приведет к такому коду:

Sub Макрос1()
    Sheets("Лист2").Select            'выделяем Лист2
    Range("A3").Select                'выделяем ячейку А3
    ActiveCell.FormulaR1C1 = "Привет" 'записываем слово Привет
    Range("A4").Select                'после нажатия Enter автоматически выделяется ячейка А4
    Sheets("Лист1").Select            'возвращаемся на Лист1
End Sub

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

Sub Макрос1()
    Sheets("Лист2").Range("A3").FormulaR1C1 = "Привет"
End Sub

Как видно, вместо 5-ти строк кода получилась одна строка. Которая выполняет ту же задачу, что и код из 5-ти строк.
Прежде чем понять как правильно избавляться от лишнего давайте разберемся зачем же тогда VBA записывает эти Select и Activate? Как ни странно, но здесь все очень просто. VBA просто не знает, что Вы будете делать после того, как выделили Лист2. И когда Вы переходите на Лист2 — VBA записывает именно переход(его активацию, выделение). Когда выделяете ячейку — так же именно это действие записывает VBA. Захотите ли Вы затем выделить еще что-то, или закрасить ячейку, или записать в неё формулу/значение — VBA не знает. Поэтому в дальнейшем VBA работает именно с выделенным объектом Selection на активном листе.
Но при написании кода вручную или при правке записанного рекордером мы уже вольны в выборе и знаем, чего хотели добиться и какие действия нам точно не нужны.
Итак, чтобы записать в ячейку слово «Привет» рекордер предложит нам такой код:

Sub Макрос1()
    Range("A3").Select                'выделяем ячейку А3
    ActiveCell.FormulaR1C1 = "Привет" 'записываем слово Привет
    Range("A4").Select                'после нажатия Enter автоматически выделяется ячейка А4
End Sub

однако выделять ячейку(Range(«A3»).Select) совершенно необязательно. Значит один Select уже лишний. После этого идет обращение к активной ячейке — ActiveCell. .FormulaR1C1 = «Привет» означает запись значения «Привет» в эту ячейку.
Пусть не смущает FormulaR1C1 — VBA всегда так указывает запись и значения и формулы. Т.к. перед словом «Привет» нет знака равно — то это значение.
Т.к. ActiveCell является обращением к выделенной ячейке, а выделили мы до этого А3, значит их можно просто «сократить»:

Sub Макрос1()
    Range("A3").FormulaR1C1 = "Привет"
    Range("A4").Select                'после нажатия Enter автоматически выделяется ячейка А4
End Sub

Теперь у нас код получился короче и понятнее. Однако остался один Select: Range(«A4»).Select. Если нет необходимости выделять ячейку А4 после записи в А3 значения, то надо просто удалить эту строку и после выполнения кода активной будет та ячейка, которая была выделена до выполнения(т.е. выделенная ячейка просто не изменится). Таким образом мы с трех строк сократим код до 1-ой:

Sub Макрос1()
    Range("A3").FormulaR1C1 = "Привет"
End Sub

Теперь несложно догадаться, что с листами все в точности так же. Sheets(«Лист2»).Select — Select хоть и не нужен, но и ActiveSheet после него нет. Здесь необходимо знать некоторую иерархию в Excel. Сначала идет сам Excel — Application, потом книга — Workbook. В книгу входят рабочие листы(Worksheets), а уже в листах — ячейки и диапазоны — Range и Cells(Application ->Workbook ->Worksheet ->Range). Если перед Range или Cells не указывать явно лист: Range(«A3»).FormulaR1C1 = «Привет», то значение будет записано на активный лист. Подробнее можно прочесть в статье: Как обратиться к диапазону из VBA

Маленький нюанс: если сокращаем обращение к объектам, то Select-ов быть не должно вообще. Иначе есть шанс получить ошибку «Subscript out of range»:
VBA error 9 - Subscript out of range
буквально это означает, что указанный индекс вне досягаемости. А появляется эта ошибка потому, что нельзя выделить ячейку НЕактивного листа или лист НЕактивной книги. Легко эту ошибку получить например в таком коде:

Sub Макрос2()
    Windows("Книга3").Activate
    'здесь появится ошибка, т.к. пытаемся выделить лист в Книга2 
    'а на данный момент активной является Книга3
    Windows("Книга2").Sheets("Лист3").Select
End Sub

Ошибка обязательно появится, т.к. сначала мы активировали кодом книгу «Книга3», а потом пытаемся активировать лист НЕактивной на этот момент книги «Книга2». А это сделать невозможно без активации той книги, в которой активируемый лист. Т.е. активация должна происходить именно последовательно: Книга ->Лист ->Ячейка. И никак иначе, если мы хотим активировать именно конкретную ячейку конкретного листа в конкретной книге.
И пример с ячейками:

Sub Макрос2()
    Sheets("Лист3").Select
    'здесь появится ошибка, т.к. пытаемся выделить ячейку на листе "Лист1"
    'а на данный момент активным является Лист3
    Sheets("Лист1").Range("C7").Select
End Sub

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

Еще небольшой пример оптимизации:

Sub Макрос2()
    Windows("Книга3").Activate
    Sheets("Лист3").Select
    Range("C7").Select
    ActiveCell.FormulaR1C1 = "Привет"
    Range("C7").Select
    Selection.Font.Bold = True
    With Selection.Interior
        .Pattern = xlSolid
        .PatternColorIndex = xlAutomatic
        .Color = 65535
        .TintAndShade = 0
        .PatternTintAndShade = 0
    End With
End Sub

Этот код записывает в ячейку С7 Лист3 книги «Книга3» слово «Привет», потом делает жирным шрифт и назначает желтый цвет заливке. Убираем активацию книги, листа и ячейки, заменив их прямым обращением:

Workbooks("Книга3").Sheets("Лист3").Range("C7").FormulaR1C1 = "Привет"

далее делаем для ячейки жирный шрифт:

Workbooks("Книга3").Sheets("Лист3").Range("C7").Font.Bold = True

и цвет заливки:

With Workbooks("Книга3").Sheets("Лист3").Range("C7").Interior
    .Pattern = xlSolid
    .PatternColorIndex = xlAutomatic
    .Color = 65535
    .TintAndShade = 0
    .PatternTintAndShade = 0
End With

Тут есть нюанс. Windows необходимо всегда заменять на Workbooks — в кодах я сделал именно так. Если этого не сделать, то получите ошибку 438 — объект не поддерживает данное свойство или метод(object dos’t support this property or metod), т.к. коллекция Windows не содержит определения для Sheets.

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

Вместо Workbooks(«Книга3.xlsx») можно использовать обращение к активной книге или книге, в которой расположен код. Обращение к Лист3 активной книги, когда активен Лист2 или другой:

ActiveWorkbook.Sheets("Лист3").Range("A1").Value = "Привет"

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

ThisWorkbook.Sheets("Лист3").Range("A1").Value = "Привет"

ActiveWorkbook — действия с активной на момент выполнения кода книгой
ThisWorkbook — действия с книгой, в которой записан код

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

Sub NewBook()
    'объявляем переменную для дальнейшего обращения
    Dim wbNewBook As Workbook
    'создаем книгу
    Set wbNewBook = Workbooks.Add
    'теперь можно обращаться к wbNewBook как к любой другой книге
    'но уже не указывая её имя
    wbNewBook.Sheets(1).Range("A1").Value = "Привет"
    'Sheets(1) - обращение к листу по его порядковому номеру
    '(отсчет с начинается с 1 слева)
End Sub
Sub NewSheet()
    'объявляем переменную для дальнейшего обращения
    Dim wsNewSheet As Worksheet
    'добавляем новый лист в активную книгу
    Set wsNewSheet = ActiveWorkbook.Sheets.Add
    'теперь можно обращаться к wsNewSheet как к любому другому листу
    'но уже не указывая его имя или индекс
    wsNewSheet.Range("A1").Value = "Привет"
End Sub

Не везде Activate лишний
Но есть и такие свойства и методы, которые требуют обязательной активации книги/листа. Одним из таких свойств является свойство окна FreezePanes(Закрепление областей):

Sub Freeze_Panes()
    ThisWorkbook.Activate
    Sheets(2).Activate
    Range("B2").Select
    ActiveWindow.FreezePanes = True
End Sub

В этом коде нельзя убирать Select и Activate, т.к. свойство FreezePanes применяется исключительно к активному листу и активной ячейке, потому что является оно именно методом окна, а не листа или ячейки.
Так же сюда можно отнести свойства: Split, SplitColumn, SplitHorizontal и им подобные. Иными словами все свойства, которые работают исключительно с активным окном приложения, а не с объектами напрямую.

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


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

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


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



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

 

KOT

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

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

Я пробую и так и так а работают у меня одинаково. Тогда зачем их две?

 

Select-ом можно выделить диапазон ячеек, а активной в этом диапазоне можно сделать одну или несколько ячеек.  
Пример:  
Sub SelectVsActivate()  
 [A1:D4].Select
 [B2].Activate
End Sub

 

Активной — не несколько, а одну

 

KOT

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

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

Sub SelectVsActivate()  
 [A1:D4].Select
 [B2].Activate
End Sub  
Странно. Зачем выделять A1:D4 если активируем для работы В2?

 

KOT

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

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

И еще. Если мне нужно работать с одной ячейкой то какая разница будет тогда?

 

Лучше вообще отказаться от этих методов при обработке ячеек, т.к. эти методы (Activate, Select) замедляют работу макроса.    

  Зачем писать так?  

  Sub Макрос1()  
   Range(«A1»).Select  
   ActiveCell = «5»  
End Sub  

  если можно написать так  

  Sub Макрос2()  
   Range(«A1») = «5»  
End Sub

 

Или зачем писать так  

  Sub Макрос1()  
   Sheets(«Лист3»).Select  
   Range(«A1»).Select  
   ActiveCell = «5»  
End Sub  

  если можно так  

  Sub Макрос2()  
   Sheets(«Лист3»).Range(«A1») = «5»  
End Sub

 

KOT

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

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

А если я циклом делаю? Перемещаюсь вниз по столбцу то как мне показать переход на следующую ячейку?

 

А просто не надо выделять ячейку. Надо писать с такой логикой, как пример:  

  «ячейка(номер_строки, номер столбца) = 5»  

  См. пример кода. Сперва определяем последнюю заполненную строку в встолбе А, а затем в цикле от второй стороки до последней обрабатываем ячейки (не выделяя их)  

  Sub Макрос1()  
Dim iLastRow As Long  
   iLastRow = Cells(Rows.Count, 1).End(xlUp).Row ‘последняя заполненная строка в столбца А  
   For i = 2 To iLastRow  
       cells(i,1) = ‘тут что-то делаете с ячейкой  
   Next  
End Sub

 

KOT

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

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

Мне ведь нужно указать начальную позицию. Я делаю  
Range(“A8”).Select  
Do While ActiveCell > 0  
…  
Как я без Select обойдусь? И переход на строку вниз мне нужно сделать потом

 

1) Я не знаю, что вам нужно (вы ещё в этой теме не сказали)  
2) Не надо выделять никаких ячеек  

  Sub Макрос1()  
Dim iLastRow As Long  
   iLastRow = Cells(Rows.Count, 1).End(xlUp).Row ‘последняя заполненная строка в столбца А  
   For i = 8 To iLastRow  
       If IsEmpty(Cells(i, 1)) Then Exit For ‘если ячейка пустая, то выход из цикла  
       Cells(i,1) = ‘вот ваша начальная ячейка при первом цикле  
   Next  
End Sub

 

KOT

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

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

С этим понятно. А если мне нужно такойже цикл по строке? то как быть?  
P.S. Я на одном из формуов видел тоже Pavel55, это клон или все вы?

 

Для столбцов так  

  Sub Макрос1()  
Dim iLastColumn As Long  
Dim i As Long  
   iLastColumn = Cells(1, Columns.Count).End(xlToLeft).Column ‘последний заполненный столбец в 1 ряду  
   For i = 1 To iLastColumn  
       cells(1,i) ‘тут что то делаете  
   Next  
End Sub  

  P.S. Если форумы был посвящён Excel и VBA, то значит был я

 

KOT

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

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

Pavel, все понятно объяснили. Одного не пойму. Если мне в столбце А (это предпоследний пример) нужно найти например ячейку содержащую NNN то зачем мне узнавать сначала про последнюю строку? Мне ведь неважно на какой строке она будет найдена и сколько еще осталось после нее. В ваших примерах вы всегда сначала пересчитываете строки/столбцы. Это обязательно? Заче у вас такое «вступление»?

 

KOT

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

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

Если можно обойтись без Activate тогда зачем она нужна? В каком случае без нее не обойтись?

 

Моими примерами выше я показал вам, как можно обрабатывать ячейки без использования методов Activate и Select. Для этого я использовал цикл. Цикл в примерах работал от 2 строки до последней заполнений — это был лишь пример работы цикла.  

  Для поиска NNN в столбце А можно использовать такой код  

  Sub Макрос1()  
Dim iRange As Range  
   Set iRange = Columns(1).Find(what:=»NNN», LookIn:=xlFormulas, lookAt:=xlWhole)  
   If Not iRange Is Nothing Then  
       MsgBox «NNN найдено в ячейке » & iRange.Address(0, 0), 64, «Поиск»  
   Else  
       MsgBox «NNN не найдено в столбце А», 48, «Поиск»  
   End If  
End Sub  

  P.S. Честно, я вообще не понимаю, что вы хотите сделать, то вы про Select спрашиваете, то про поиск, то ещё что-то, может вы выложите пример в файле и скажите, что надо сделать? А то мы так долго вокруг да около можем ходить.

 

KOT

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

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

Pavel, спасибо за исчерпывающий ответ. Примера нет никакого. я просто хочу понять как грамотно строить циклы. Меня сбили с толку эти Select и Activate. Если с Select понятно, что можно выделить диапазон то с Activate так до конца и не понял в чем будет отличие применительно к одной ячейке.

 

KOT

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

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

Еще. Я спрашивал не про поиск. А если циклом перебираю строки до тех пор пока не найду NNN. И вы не ответили о необходимости каждый раз вначале считать к-во строк.

 

Ну, вы же не хотите полностью все строки обрабатывать на листе Excel. Вам надо как-то определить границы вашей таблицы. Начальные строки обычно известны (1 или 2 строка), а вот конечная строка таблицы может меняться, если в таблицу была добавлена новая информация. Я вам показал пример, как можно найти нижнюю границу таблицы (последнюю заполненную строку в столбца А). И тогда вы можете запускать цикл по обработке не всех строк на листе Excel, а например, со 2-ой до последней заполненной строки, т.е.  

  For i = 2 To LastRow  
….  
Next  

  P.S. Это всего лишь примеры, если вы сейчас это не понимаете или это сейчас вам не нужно (циклы например) — не обращайте на эти примеры особого внимания. Когда будет нужно, спросите, вам ответят и всё встанет на свои места.

 

KOT

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

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

Нет. Все понятно! Спасибо. Последнее. Фрагмент вашего кода:  
For i = 2 To iLastRow  
cells(i,1) = ‘тут что-то делаем с ячейкой  
Вот эту найденную строку мне нужно удалить. Я ведь должен ячейку активировать или необязательно?

 

Мы же, вроде, с вами договорились, что ничего не обязательно выделять (Select), для того чтобы обработать ячейки.    

  Если вы всё про поиск NNN и удаление этой строки, то  

  Sub Макрос1()  
Dim iRange As Range  
   Set iRange = Columns(1).Find(what:=»NNN», LookIn:=xlFormulas, lookAt:=xlWhole)  
   If Not iRange Is Nothing Then  
       iRange.EntireRow.Delete  
   Else  
       MsgBox «NNN не найдено в столбце А», 48, «Поиск»  
   End If  
End Sub  

  P.S. Метод Find (поиск) работает быстрее, чем перебор ячеек в цикле.

 

KOT

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

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

Pavel, огромное вам спасибо. Многое для меня прояснилось.

 

Не за что. Надеюсь эта тема поможет и другим на начальных этапах изучения VBA

 

{quote}{login=Kot}{date=29.06.2008 11:49}{thema=}{post}И еще. Если мне нужно работать с одной ячейкой то какая разница будет тогда?{/post}{/quote}  
С одной ячейкой все равно, что select, что activate.  
Разницу между ними — см в 1-м ответе

 

Как пример Select vs Activate  

  Declare Sub Sleep Lib «kernel32» (ByVal dwMS As Long)  
Sub Макрос1()  
Dim iCell As Range  
   Range(«A1:H10»).Select ‘выделяем диапазон  
   For Each iCell In Selection  
       iCell.Activate ‘активируем каждую ячейку  
       Sleep 200  
   Next  
End Sub

 

KOT

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

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

Pavel, а как в вашем примере не удалить текущую строку а остаться на найденной ячейке?  
Sub Макрос1()  
Dim iRange As Range  
Set iRange = Columns(1).Find(what:=»NNN», LookIn:=xlFormulas, lookAt:=xlWhole)  
If Not iRange Is Nothing Then  
‘iRange.EntireRow.Delete  
Else  
MsgBox «NNN не найдено в столбце А», 48, «Поиск»  
End If  
End Sub

 

Попробуйте понять этот пример  

  Sub Макрос1()  
Dim iRange As Range  
   Set iRange = Columns(1).Find(what:=»NNN», LookIn:=xlFormulas, lookAt:=xlWhole)  
   If iRange Is Nothing Then  
       MsgBox «NNN не найдено в столбце А», 48, «Поиск»  
       Exit Sub  
   End If  
   MsgBox «NNN найдено в:    » & Chr(13) & _  
       «Строка: » & iRange.Row & Chr(13) & _  
       «Столбец: » & iRange.Column & Chr(13) & _  
       «Адрес: » & iRange.Address(0, 0), , «Поиск»  
End Sub

 

См. Но если очень-очень хочется именно выделить найденную ячейку, то    

  iRange.Select

 

KOT

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

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

 

слэн

Гость

#30

30.06.2008 12:09:34

только не паникуйте..  

  но есть еще и метод application.goto    

  :)

What is the difference between the VBA code wb.Sheets(1).Cells.Select and wb.Sheets(1).Activate?

Fionnuala's user avatar

Fionnuala

90.1k7 gold badges110 silver badges148 bronze badges

asked Aug 24, 2011 at 17:52

Bruno's user avatar

1

Difference between select is that you can select several objects at once. Objects that are selected are also placed in the Selection object which you can use methods on. Unless you are selecting multiple objects, selecting (say, a cell) activates the object.

Activate just simply makes the object the active object.
Best way to think of it is «many cells can be selected, but only one may be the active cell at any given time

Note: They both have one thing in common — they are rarely ever needed and they do generally don’t do anything but slow your code down. You can work directly on an object without selecting or activating it and it’s best practice not to use these unless needed.

answered Aug 25, 2011 at 5:58

Gaijinhunter's user avatar

GaijinhunterGaijinhunter

14.5k4 gold badges50 silver badges57 bronze badges

3

The first selects all cells on the first sheet of the workbook wb. It will fail if the sheet is not active.

The second just activates the first sheet of the workbook wb. It does not alter the selection or activecell on that sheet, and in some cases there may be no selected range or activecell (eg. if there’s an object on the sheet which is currently selected).

answered Aug 24, 2011 at 18:24

Tim Williams's user avatar

Tim WilliamsTim Williams

150k8 gold badges96 silver badges124 bronze badges

1

Select — «Selects» Cell(s)

Activate — «Activates» a sheet (kind of like saying to focus on a sheet)

Sometimes u need to specifically ACTIVATE the sheet, in order to make a SELECT

answered Aug 25, 2011 at 10:22

waqasahmed's user avatar

waqasahmedwaqasahmed

3,4876 gold badges30 silver badges52 bronze badges

I found this question while searching, I had the same question. Here is something I noticed:

 Sub Transfer(x As Long)
   Dim Rng, ID as Range
   Dim i, j, n As Long

 Worksheets(5).Activate
 n = Worksheets(5).Range(Range("I88"), Range("I88").End(xlToRight)).Count

Worksheets(x).Select
 Set Rng = Worksheets(3).UsedRange.Find("Element", LookIn:=xlValues).Offset(1, 1)
 Set ElemID = Range(ElemRng.Offset(0, -1), ElemRng.Offset(0, -1).End(xlDown))
 Set ElemRng = Worksheets(3).Range(ElemRng, ElemRng.End(xlToRight))
End Sub

I found that I HAD to put the worksheet.activate (or select) in or the code would run into:


Run-time error: ‘1004’
Application-defined or object-defined error


answered Dec 20, 2017 at 5:19

Reverus's user avatar

Activate is often used for Sheets for Example.
The Active sheet wil be shown on the screen… therfore there can only be one active sheet

Select though is can be used for multiple Cells for Example.
Range(A1:B3).Select will select multiple cell which is’nt possible with activate

answered Oct 20, 2015 at 8:08

Cornelis's user avatar

CornelisCornelis

4473 gold badges11 silver badges27 bronze badges

Bottom line: Learn the difference between these two commonly used methods in VBA.

Skill level: Intermediate

One question I hear often from new members of our VBA Pro Course is, “What’s the difference between Select and Activate? It seems like they do the same thing?”

Select vs Activate in VBA for Excel

The short answer is that Select and Activate can perform the same action, but the differences are:

  • Select can be used to select multiple objects (sheets, ranges, shapes, etc.) at the same time.
  • Activate can be used to active one object within the selection.

Let’s take a look at an example to see how this works.

Which Method Should I Use?

First, it’s important to note that both methods can be used on many different types of objects in Excel. This includes sheets, ranges, cells, shapes, charts, slicers, etc. We’ll use worksheets in this example.

The use case for each method depends on the scenario. And as I explain below, it’s usually best to use neither. 😲

When to use the Select Method

The Select method is typically the one we’re most familiar with because the macro recorder uses it when generating code.

Select allows us to select a single object OR multiple objects.

The following line of VBA code selects a single worksheet.

  Worksheets("Sheet2").Select

We can also use Select to select multiple objects. Here is an example of selecting multiple ranges.

Range("A1:B10,D1:F10,J1:K10").Select

Here is an example of selecting multiple sheets. The Array function is used to reference the sheets. This same technique can be used for shapes.

  Worksheets(Array("Sheet2", "Sheet3", "Sheet5")).Select

When that line of code is run, the first item in the array is activated. That means that Sheet2 will be the active sheet that the user sees.

VBA Select Method First Object in Array is Active

What if we want to keep the three sheets selected, but have the user view Sheet3 instead? This is where the Activate method comes into play.

When to use the Activate Method

The Activate method allows us to select a single object. This can be a single object within a selection, if multiple objects are already selected.

The following lines would select the three sheets, then make Sheet3 the active sheet that the user sees.

Worksheets(Array("Sheet2", "Sheet3", "Sheet5")).Select

Worksheets("Sheet3").Activate

VBA Active vs Select Methods Multiple Sheets Selected

If you do not have a group of objects selected, then Activate will just select a single object. It does NOT add to the current selection and will work the same way that Select works.

Be Careful with Activate

You might not always know which objects are selected in the workbook. Therefore, you can’t always use Activate to select a single object.

For example, let’s say you have a line of code in your macro to activate Sheet1.

If the user has Sheet1 to Sheet3 selected before the macro is runs, then all three sheets will remain selected. You might not want this if your next line of code modifies a cell on Sheet1. Depending on how the code is written, all three sheets could be modified, causing unwanted results. 😬

If you activate an object that is NOT in the selection, then that single object will be selected and the previously selected objects will no longer be selected. For example, if the user has Sheet1 to Sheet3 selected and your code activates Sheet4, then only Sheet4 will be selected.

The main takeaway here is that there are a lot of potential unwanted outcomes when using Activate to select a single object. So, it’s best to use Select for selecting single objects.

Activate for Workbooks

The Activate method is also used when activating Workbooks and Windows. There is no Select method for these objects.

ThisWorkbook.Activate

Workbooks("Book3.xlsx").Activate

Windows("Book3.xlsx").Activate

Avoid Select and Activate Whenever Possible

It’s great to know the difference between these two methods, but you might not need them as often as you think. Especially if you are just starting out with VBA and using the macro recorder a lot.

The macro recorder code contains a lot of lines with the Select method because it is generating code for every action we take. However, we do NOT need to select an object before we take actions on it. This can slow down our code and make it more prone to errors.

The Select Method is Like Using a TV without a Remote Control

Here is an article on How to Avoid the Select Method in VBA & Why that explains more.

Conclusion

It’s best to use Select when you want to select a single object or multiple objects. Activate should be used when you want to activate (view/select) an object within an existing selection. Activate is also used to select Workbooks, as there is not Select method for that object.

Did I miss anything? Please leave a comment below with questions or suggestions. Thank you! 🙂

  • #1

Hi all,

I’m a newbie to VBA, and I was hoping someone could explain to me the difference between Select and Activate. For example, all four of the following do the same thing:

Code:

Sub test()

Range("B2").Select
Range("B2").Copy Destination:=Selection.Offset(0, 1)

End Sub

Code:

Sub test()

Range("B2").Activate
Range("B2").Copy Destination:=ActiveCell.Offset(0, 1)

End Sub

Code:

Sub test()

Range("B2").Select
Range("B2").Copy Destination:=ActiveCell.Offset(0, 1)

End Sub

Code:

Sub test()

Range("B2").Activate
Range("B2").Copy Destination:=Selection.Offset(0, 1)

End Sub

Could someone please explain if there is any reason to use one or the other (or neither)?

Thanks,
Bill

Can Excel fill bagel flavors?

You can teach Excel a new custom list. Type the list in cells, File, Options, Advanced, Edit Custom Lists, Import, OK

  • #2

Hi Bill,

In all honesty, my advice would be to use neither, if you remove the line with the select or Activate on and run it you will see that it still does what you ask it without the inefficiency of having to Select/Activate the cell.

  • #3

I’m also interested in the answer to the question..

  • #4

Select can select multiple objects.

Activate can activate only one object.

Code:

Sub example()
Range("a1:a10").Select
MsgBox "Selection.Address = " & Selection.Address & vbLf & _
           "ActiveCell.Address = " & ActiveCell.Address
End Sub

  • #5

Thanks for the replies. Mikey B — I’ve read a few threads that also discuss omitting the Select or Activate to improve efficiency. My question then is what is the most efficient way to have the copied cell be pasted in a position relative to the copied cell? That is, if I don’t select or activate in the first line then Selection.Offset(0,1) won’t work. What would you recommend?

Thanks,
Bill

  • #6

If your code is not dependent on your user making their own selection and then executing your subroutine, you could use something like

Code:

With Range("B2")
    .Copy Destination:=.Offset(0, 1)
    ' Other stuff you want to do with Range("B2")
End With

RoryA

RoryA

MrExcel MVP, Moderator


  • #7

Code:

Sub test()
 
Range("B2").Activate
Range("B2").Copy Destination:=Selection.Offset(0, 1)
 
End Sub

Could someone please explain if there is any reason to use one or the other (or neither)?

Thanks,
Bill

You need to be very careful when using Activate on a range — it is better to use Select if you must actually select it. Try running the above in the following two situations and see what happens:
1. Select A1 then run the code.
2. Select a1:C10 then run the code.

Totally different scenarios!!
HTH

  • #8

gauntletxg — thanks for the tip; I have changed some code to mimic your example. rorya — thanks for the example. I tried it and completely see your point…a good demonstration.

Thanks,
Bill

  • #10

Thanks guruxcel…nice explanation.

HaHoBe

Home / VBA / How to use ActiveCell in VBA in Excel

In VBA, the active cell is a property that represents the cell that is active at the moment. When you select a cell or navigate to a cell and that green box covers that cell you can use ACTIVECELL property to refer to that cell in a VBA code. There are properties and methods that come with it.

Use the Active Cell Property

  1. Type the keyword “ActiveCell”.
  2. Type a dot (.) to get the list properties and methods.
  3. Select the property or method that you want to use.
  4. Run the code to perform the activity to the active cell.

Important Points

  • When you use the active cell property VBA refers to the active cell of the active workbook’s active sheet’s, irrespective of how many workbooks are open at the moment.
  • ActiveCell is ultimately a cell that comes with all the properties and methods that a normal cell comes with.

Activate a Cell from the Selected Range

To activate a cell using a VBA code there are two ways that you can use one “Activate” method and “Select” method.

Sub vba_activecell()

'select and entire range
Range("A1:A10").Select

'select the cell A3 from the selected range
Range("A3").Activate

'clears everything from the active cell
ActiveCell.Clear

End Sub

The above code, first of all, selects the range A1:A10 and then activates the cell A3 out of that and in the end, clears everything from the active cell i.e., A3.

Return Value from the Active Cell

The following code returns the value from the active cell using a message box.

MsgBox ActiveCell.Value

Or if you want to get the value from the active cell and paste it into a separate cell.

Range("A1") = ActiveCell.Value

Set Active Cell to a Variable

You can also set the active cell to the variable, just like the following example.

Sub vba_activecell()

'declares the variable as range
Dim myCell As Range

'set active cell to the variable
Set myCell = ActiveCell

'enter value in the active cell
myCell.Value = Done

End Sub

Get Row and Column Number of the ActiveCell

With the active cell there comes a row and column property that you can use to get the row and column number of the active cell.

MsgBox ActiveCell.Row

MsgBox ActiveCell.Column

Get Active Cell’s Address

You can use the address property to get the address of the active cell.

MsgBox ActiveCell.Address

When you run the above code, it shows you a message box with the cell address of the active cell of the active workbook’s active sheet (as I mentioned earlier).

Move from the Active Cell using Offset

With offset property, you can move to a cell which is a several rows and columns away from the active cell.

ActiveCell.Offset(2, 2).Select

Select a Range from the Active Cell

And you can also select a range starting from the active cell.

Range(ActiveCell.Offset(1, 1), ActiveCell.Offset(5, 5)).Select

More Tutorials

    • Count Rows using VBA in Excel
    • Excel VBA Font (Color, Size, Type, and Bold)
    • Excel VBA Hide and Unhide a Column or a Row
    • Excel VBA Range – Working with Range and Cells in VBA
    • Apply Borders on a Cell using VBA in Excel
    • Find Last Row, Column, and Cell using VBA in Excel
    • Insert a Row using VBA in Excel
    • Merge Cells in Excel using a VBA Code
    • Select a Range/Cell using VBA in Excel
    • SELECT ALL the Cells in a Worksheet using a VBA Code
    • Special Cells Method in VBA in Excel
    • UsedRange Property in VBA in Excel
    • VBA AutoFit (Rows, Column, or the Entire Worksheet)
    • VBA ClearContents (from a Cell, Range, or Entire Worksheet)
    • VBA Copy Range to Another Sheet + Workbook
    • VBA Enter Value in a Cell (Set, Get and Change)
    • VBA Insert Column (Single and Multiple)
    • VBA Named Range | (Static + from Selection + Dynamic)
    • VBA Range Offset
    • VBA Sort Range | (Descending, Multiple Columns, Sort Orientation
    • VBA Wrap Text (Cell, Range, and Entire Worksheet)
    • VBA Check IF a Cell is Empty + Multiple Cells

    ⇠ Back to What is VBA in Excel

    Helpful Links – Developer Tab – Visual Basic Editor – Run a Macro – Personal Macro Workbook – Excel Macro Recorder – VBA Interview Questions – VBA Codes

    Свойство ActiveCell объекта Application, применяемое в VBA для возвращения активной ячейки, расположенной на активном листе в окне приложения Excel.

    Свойство ActiveCell объекта Application возвращает объект Range, представляющий активную ячейку на активном листе в активном или указанном окне приложения Excel. Если окно не отображает лист, применение свойства Application.ActiveCell приведет к ошибке.

    Если свойство ActiveCell применяется к активному окну приложения Excel, то идентификатор объекта (Application или ActiveWindow) можно в коде VBA Excel не указывать. Следующие выражения, скопированные с сайта разработчиков, являются эквивалентными:

    ActiveCell

    Application.ActiveCell

    ActiveWindow.ActiveCell

    Application.ActiveWindow.ActiveCell

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

    Sub Primer1()

        With Windows(«Книга2.xlsx»)

            .ActiveCell = 325

            MsgBox .ActiveCell.Address

            MsgBox .ActiveCell.Value

        End With

    End Sub

    Программно сделать ячейку активной в VBA Excel можно с помощью методов Activate и Select.

    Различие методов Activate и Select

    Выберем программно диапазон «B2:E6» методом Select и выведем адрес активной ячейки:

    Sub Primer2()

        Range(«B2:E6»).Select

        ActiveCell = ActiveCell.Address

    End Sub

    Результат:

    Как видим, активной стала первая ячейка выбранного диапазона, расположенная слева вверху. Если мы поменяем местами границы диапазона (Range("E6:B2").Select), все равно активной станет та же первая ячейка.

    Теперь сделаем активной ячейку «D4», расположенную внутри выделенного диапазона, с помощью метода Activate:

    Sub Primer3()

        Range(«E6:B2»).Select

        Range(«D4»).Activate

        ActiveCell = ActiveCell.Address

    End Sub

    Результат:

    Как видим, выбранный диапазон не изменился, а активная ячейка переместилась из первой ячейки выделенного диапазона в ячейку «D4».

    И, наконец, выберем ячейку «D4», расположенную внутри выделенного диапазона, с помощью метода Select:

    Sub Primer4()

        Range(«E6:B2»).Select

        Range(«D4»).Select

        ActiveCell = ActiveCell.Address

    End Sub

    Результат:

    Как видим, ранее выбранный диапазон был заменен новым, состоящим из одной ячейки «D4». Такой же результат будет и при активации ячейки, расположенной вне выбранного диапазона, методом Activate:

    Sub Primer5()

        Range(«E6:B2»).Select

        Range(«A3»).Activate

        ActiveCell = ActiveCell.Address

    End Sub

    Аналогично ведут себя методы Activate и Select при работе с выделенной группой рабочих листов.

    Свойство Application.ActiveCell используется для обращения к одной ячейке, являющейся активной, а для работы со всеми ячейками выделенного диапазона используется свойство Application.Selection.


    Понравилась статья? Поделить с друзьями:
  • Vba excel select from access
  • Vba excel select cell value
  • Vba excel select case пример
  • Vba excel select case или
  • Vba excel select case and or