Хитрости »
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»:
буквально это означает, что указанный индекс вне досягаемости. А появляется эта ошибка потому, что нельзя выделить ячейку НЕактивного листа или лист НЕактивной книги. Легко эту ошибку получить например в таком коде: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 |
Я пробую и так и так а работают у меня одинаково. Тогда зачем их две? |
Select-ом можно выделить диапазон ячеек, а активной в этом диапазоне можно сделать одну или несколько ячеек. |
|
Активной — не несколько, а одну |
|
KOT Пользователь Сообщений: 68 |
Sub SelectVsActivate() |
KOT Пользователь Сообщений: 68 |
И еще. Если мне нужно работать с одной ячейкой то какая разница будет тогда? |
Лучше вообще отказаться от этих методов при обработке ячеек, т.к. эти методы (Activate, Select) замедляют работу макроса. Зачем писать так? Sub Макрос1() если можно написать так Sub Макрос2() |
|
Или зачем писать так Sub Макрос1() если можно так Sub Макрос2() |
|
KOT Пользователь Сообщений: 68 |
А если я циклом делаю? Перемещаюсь вниз по столбцу то как мне показать переход на следующую ячейку? |
А просто не надо выделять ячейку. Надо писать с такой логикой, как пример: «ячейка(номер_строки, номер столбца) = 5» См. пример кода. Сперва определяем последнюю заполненную строку в встолбе А, а затем в цикле от второй стороки до последней обрабатываем ячейки (не выделяя их) Sub Макрос1() |
|
KOT Пользователь Сообщений: 68 |
Мне ведь нужно указать начальную позицию. Я делаю |
1) Я не знаю, что вам нужно (вы ещё в этой теме не сказали) Sub Макрос1() |
|
KOT Пользователь Сообщений: 68 |
С этим понятно. А если мне нужно такойже цикл по строке? то как быть? |
Для столбцов так Sub Макрос1() P.S. Если форумы был посвящён Excel и VBA, то значит был я |
|
KOT Пользователь Сообщений: 68 |
Pavel, все понятно объяснили. Одного не пойму. Если мне в столбце А (это предпоследний пример) нужно найти например ячейку содержащую NNN то зачем мне узнавать сначала про последнюю строку? Мне ведь неважно на какой строке она будет найдена и сколько еще осталось после нее. В ваших примерах вы всегда сначала пересчитываете строки/столбцы. Это обязательно? Заче у вас такое «вступление»? |
KOT Пользователь Сообщений: 68 |
Если можно обойтись без Activate тогда зачем она нужна? В каком случае без нее не обойтись? |
Моими примерами выше я показал вам, как можно обрабатывать ячейки без использования методов Activate и Select. Для этого я использовал цикл. Цикл в примерах работал от 2 строки до последней заполнений — это был лишь пример работы цикла. Для поиска NNN в столбце А можно использовать такой код Sub Макрос1() P.S. Честно, я вообще не понимаю, что вы хотите сделать, то вы про Select спрашиваете, то про поиск, то ещё что-то, может вы выложите пример в файле и скажите, что надо сделать? А то мы так долго вокруг да около можем ходить. |
|
KOT Пользователь Сообщений: 68 |
Pavel, спасибо за исчерпывающий ответ. Примера нет никакого. я просто хочу понять как грамотно строить циклы. Меня сбили с толку эти Select и Activate. Если с Select понятно, что можно выделить диапазон то с Activate так до конца и не понял в чем будет отличие применительно к одной ячейке. |
KOT Пользователь Сообщений: 68 |
Еще. Я спрашивал не про поиск. А если циклом перебираю строки до тех пор пока не найду NNN. И вы не ответили о необходимости каждый раз вначале считать к-во строк. |
Ну, вы же не хотите полностью все строки обрабатывать на листе Excel. Вам надо как-то определить границы вашей таблицы. Начальные строки обычно известны (1 или 2 строка), а вот конечная строка таблицы может меняться, если в таблицу была добавлена новая информация. Я вам показал пример, как можно найти нижнюю границу таблицы (последнюю заполненную строку в столбца А). И тогда вы можете запускать цикл по обработке не всех строк на листе Excel, а например, со 2-ой до последней заполненной строки, т.е. For i = 2 To LastRow P.S. Это всего лишь примеры, если вы сейчас это не понимаете или это сейчас вам не нужно (циклы например) — не обращайте на эти примеры особого внимания. Когда будет нужно, спросите, вам ответят и всё встанет на свои места. |
|
KOT Пользователь Сообщений: 68 |
Нет. Все понятно! Спасибо. Последнее. Фрагмент вашего кода: |
Мы же, вроде, с вами договорились, что ничего не обязательно выделять (Select), для того чтобы обработать ячейки. Если вы всё про поиск NNN и удаление этой строки, то Sub Макрос1() P.S. Метод Find (поиск) работает быстрее, чем перебор ячеек в цикле. |
|
KOT Пользователь Сообщений: 68 |
Pavel, огромное вам спасибо. Многое для меня прояснилось. |
Не за что. Надеюсь эта тема поможет и другим на начальных этапах изучения VBA |
|
{quote}{login=Kot}{date=29.06.2008 11:49}{thema=}{post}И еще. Если мне нужно работать с одной ячейкой то какая разница будет тогда?{/post}{/quote} |
|
Как пример Select vs Activate Declare Sub Sleep Lib «kernel32» (ByVal dwMS As Long) |
|
KOT Пользователь Сообщений: 68 |
Pavel, а как в вашем примере не удалить текущую строку а остаться на найденной ячейке? |
Попробуйте понять этот пример Sub Макрос1() |
|
См. Но если очень-очень хочется именно выделить найденную ячейку, то iRange.Select |
|
KOT Пользователь Сообщений: 68 |
|
слэн Гость |
#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
90.1k7 gold badges110 silver badges148 bronze badges
asked Aug 24, 2011 at 17:52
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
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 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
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
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
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?”
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.
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")).SelectWorksheets("Sheet3").Activate
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.ActivateWorkbooks("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.
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
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.
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
- Type the keyword “ActiveCell”.
- Type a dot (.) to get the list properties and methods.
- Select the property or method that you want to use.
- 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.