Excel макрос активировать ячейку

Свойство 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.


Хитрости »

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


Все начинающие изучать 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
ссылки
статистика

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

Selecting and Activating Cells

vbaxl10.chm5204866

vbaxl10.chm5204866

excel

bdfead4b-0909-e67d-e478-7fb33aceec79

06/08/2017

high

In Microsoft Excel, you usually select a cell or cells and then perform an action, such as formatting the cells or entering values in them. In Visual Basic, it is usually not necessary to select cells before modifying them.

For example, to enter a formula in cell D6 using Visual Basic, you don’t need to select the range D6. Just return the Range object for that cell, and then set the Formula property to the formula you want, as shown in the following example.

Sub EnterFormula() 
    Worksheets("Sheet1").Range("D6").Formula = "=SUM(D2:D5)" 
End Sub

For more information and examples of using other methods to control cells without selecting them, see How to: Reference Cells and Ranges.

Using the Select Method and the Selection Property

The Select method activates sheets and objects on sheets; the Selection property returns an object that represents the current selection on the active sheet in the active workbook. Before you can use the Selection property successfully, you must activate a workbook, activate or select a sheet, and then select a range (or other object) using the Select method.

The macro recorder will often create a macro that uses the Select method and the Selection property. The following Sub procedure was created using the macro recorder, and it shows how Select and Selection work together.

Sub Macro1() 
    Sheets("Sheet1").Select 
    Range("A1").Select 
    ActiveCell.FormulaR1C1 = "Name" 
    Range("B1").Select 
    ActiveCell.FormulaR1C1 = "Address" 
    Range("A1:B1").Select 
    Selection.Font.Bold = True 
End Sub

The following example performs the same task without activating or selecting the worksheet or cells.

Sub Labels() 
    With Worksheets("Sheet1") 
        .Range("A1") = "Name" 
        .Range("B1") = "Address" 
        .Range("A1:B1").Font.Bold = True 
    End With 
End Sub

Selecting Cells on the Active Worksheet

If you use the Select method to select cells, be aware that Select works only on the active worksheet. If you run your Sub procedure from the module, the Select method will fail unless your procedure activates the worksheet before using the Select method on a range of cells. For example, the following procedure copies a row from Sheet1 to Sheet2 in the active workbook.

Sub CopyRow() 
    Worksheets("Sheet1").Rows(1).Copy 
    Worksheets("Sheet2").Select 
    Worksheets("Sheet2").Rows(1).Select 
    Worksheets("Sheet2").Paste 
End Sub

Activating a Cell Within a Selection

Use the Activate method to activate a cell within a selection. There can be only one active cell, even when a range of cells is selected. The following procedure selects a range and then activates a cell within the range without changing the selection.

Sub MakeActive() 
    Worksheets("Sheet1").Activate 
    Range("A1:D4").Select 
    Range("B2").Activate 
End Sub

[!includeSupport and feedback]

Сделать активной нужную ячейку макросом

Автор Этоопятья, 08.07.2014, 17:52

« назад — далее »

Здравствуйте. Googl меня не понимает, может вы подскажите?
Есть форма календарь, которая запускается кнопкой.
При выборе даты в календаре, заполняется активная ячейка листа, а нужно что бы дата вставлялась в определенную.
Можно в продцедуре календаря изменить

ActiveCell.Value = Calendar1.Value
например на

[A1] = Calendar1.Value
но на листе несколько ячеек, в которые нужно вставлять разные даты.
Поскольку календарь вызывается кнопкой, то мне кажется логичным сделать несколько кнопок (для каждой ячейки с датой своя), которые будут вызывать одну и ту же форму календаря, но при этом активировать нужную ячейку, в которую будет вставлена дата с формы календаря.
Отображение формы запускается так

Private Sub CommandButton1_Click()
    frmCalendar.Show
End Sub

в этот макрос нужно добавить строку, которая будет активировать нужную ячейку.


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


Цитата: gling от 08.07.2014, 19:28
На каждой кнопке макрос — активировать нужную ячейку и запустить общий

так я же это и спрашиваю: как активировать нужную ячейку? А ваш вариант (с кучей кнопок в форме) для моих целей неудобный.



Цитата: Константин Божков от 08.07.2014, 17:52Private Sub CommandButton1_Click()
    frmCalendar.Show
End Sub
в этот макрос нужно добавить строку, которая будет активировать нужную ячейку.

Здравствуйте

Private Sub CommandButton1_Click()
    [c2].Activate
    frmCalendar.Show
End Sub


Serge 007 Да! Спасибо большое!


Константин Божков а если кнопка рядом с ячейкой, не лучше ли сразу при активации ячейки мышкой чтобы вызывался календарь. Зачем плодить кнопки? Или у Вас кнопка на одном листе а ячейка на другом, а рядом они только в примере?


Это бланк коммерческого предложения для пользования всеми сотрудниками компании. В нем вводится дата отгрузки и дата заказа.
Не всегда вводятся обе даты (при предварительном просчете). Если сначала выделять ячейку, а потом жать кнопку, то это во-первых +1 действие, которого можно избежать. Во-вторых, если случайно мышкой не попадешь в нужную ячейку или просто забудешь клацнуть на нужную ячейку, то дата вообще вставится неизвестно где (например, на цене какой нибудь позиции) и это может больно ударить по карману. Такие удобства никому не нужны.
А в вашем варианте вообще куча ненужных кликов которые забирают очень много времени (особенно в спешке).


Согласен много ненужных кликов. Потому что не понял правильность задачи

Цитироватькоторая запускается кнопкой.

а у Вас на листе их две, думал что это ошибка. А то что написал Serge 007 написано в форме на действие кнопок. Если бы туда заглянули можно было это перенести на кнопки листа не дожидаясь 100% решения от Serge 007.


  • Профессиональные приемы работы в Microsoft Excel

  • Обмен опытом

  • Microsoft Excel

  • Сделать активной нужную ячейку макросом

 

Добрий день!

Прошу помочь с макросом, нужно активировать  первую пустую ячейку в  видимом диапазоне(после применения фильтра) с разривами в диапазоне vba
нужно активировать ячейку между 2 и 3
1
2

3
4

5

 

kuklp

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

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

E-mail и реквизиты в профиле.

304 сообщения, а

Правил

не удосужились прочесть. Пример где?

Я сам — дурнее всякого примера! …

 

пример

Прикрепленные файлы

  • primer.xls (37.5 КБ)

 

Sanja

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

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

#4

14.06.2017 17:17:43

Код
Sub FirstBlankSelect()
    ActiveSheet.UsedRange.SpecialCells(12).SpecialCells(4)(1).Select
End Sub

Только для чего ее АКТИВИРОВАТЬ? Может сразу с ней сделать то, ради чего она активируется?

Изменено: Sanja14.06.2017 17:32:58

Согласие есть продукт при полном непротивлении сторон.

 

немного непровильно описал прозсбу.
нужно найти  первую пустую ячейку в  видимом диапазоне(после применения фильтра)(колонка В) с разривами в диапазоне и активировать соседнюю ячейку(Колонка А) с лева
(ето по примеру), а в робочем файле искать нужнов колонке U, а активировать в колонке F

 

Sanja

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

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

#6

14.06.2017 17:34:19

Цитата
sergey2303 написал: соседнюю ячейку слева
Код
Sub FirstBlankSelect()
    ActiveSheet.UsedRange.SpecialCells(12).SpecialCells(4)(1).Offset(, -1).Select
End Sub

Согласие есть продукт при полном непротивлении сторон.

 
Sanja

как осоществить поиск по колонке U, пропустив первие две строки

 

Sanja

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

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

#8

14.06.2017 20:23:07

Цитата
sergey2303 написал: поиск по колонке U, пропустив первие две строки

В Вашем примере, который Вы видимо составили после прочтения Правил форума (на 4-й сотне сообщений на форуме) в колонке U нет никаких фильтров. там ВСЕ ячейки пустые, и первая из них, т.е. U1, и будет та, которую Вы ищите

Код
Sub FirstBlankSelect()
    Range("U3:U" & Cells(Rows.Count, "U").End(xlUp).Row).SpecialCells(12).SpecialCells(4)(1).Offset(, -1).Select
End Sub

Изменено: Sanja14.06.2017 20:49:49

Согласие есть продукт при полном непротивлении сторон.

 

sergey2303

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

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

#9

15.06.2017 09:08:15

Sanja

большое спасибо. код работает

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