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.


Всё о работе с ячейками в Excel-VBA: обращение, перебор, удаление, вставка, скрытие, смена имени.

Содержание:

Table of Contents:

  • Что такое ячейка Excel?
  • Способы обращения к ячейкам
    • Выбор и активация
    • Получение и изменение значений ячеек
      • Ячейки открытой книги
      • Ячейки закрытой книги 
    • Перебор ячеек
    • Перебор в произвольном диапазоне
  • Свойства и методы ячеек
    • Имя ячейки
    • Адрес ячейки
    • Размеры ячейки
  • Запуск макроса активацией ячейки

2 нюанса:

  1. Я почти везде стараюсь использовать ThisWorkbook (а не, например, ActiveWorkbook) для обращения к текущей книге, в которой написан этот код (считаю это наиболее безопасным для новичков способом обращения к книгам, чтобы случайно не внести изменения в другие книги). Для экспериментов можете вставлять этот код в модули, коды книги, либо листа, и он будет работать только в пределах этой книги. 
  2. Я использую английский эксель и у меня по стандарту листы называются Sheet1, Sheet2 и т.д. Если вы работаете в русском экселе, то замените Thisworkbook.Sheets(«Sheet1») на Thisworkbook.Sheets(«Лист1»). Если этого не сделать, то вы получите ошибку в связи с тем, что пытаетесь обратиться к несуществующему объекту. Можно также заменить на Thisworkbook.Sheets(1), но это менее безопасно.

Что такое ячейка Excel?

В большинстве мест пишут: «элемент, образованный пересечением столбца и строки». Это определение полезно для людей, которые не знакомы с понятием «таблица». Для того, чтобы понять чем на самом деле является ячейка Excel, необходимо заглянуть в объектную модель Excel. При этом определения объектов «ряд», «столбец» и «ячейка» будут отличаться в зависимости от того, как мы работаем с файлом.

Объекты в Excel-VBA. Пока мы работаем в Excel без углубления в VBA определение ячейки как «пересечения» строк и столбцов нам вполне хватает, но если мы решаем как-то автоматизировать процесс в VBA, то о нём лучше забыть и просто воспринимать лист как «мешок» ячеек, с каждой из которых VBA позволяет работать как минимум тремя способами:

  1. по цифровым координатам (ряд, столбец),
  2. по адресам формата А1, B2 и т.д. (сценарий целесообразности данного способа обращения в VBA мне сложно представить)
  3. по уникальному имени (во втором и третьем вариантах мы будем иметь дело не совсем с ячейкой, а с объектом VBA range, который может состоять из одной или нескольких ячеек). Функции и методы объектов Cells и Range отличаются. Новичкам я бы порекомендовал работать с ячейками VBA только с помощью Cells и по их цифровым координатам и использовать Range только по необходимости.

Все три способа обращения описаны далее

Как это хранится на диске и как с этим работать вне Excel? С точки зрения хранения и обработки вне Excel и VBA. Сделать это можно, например, сменив расширение файла с .xls(x) на .zip и открыв этот архив.

Пример содержимого файла Excel:

Далее xl -> worksheets и мы видим файл листа

Содержимое файла:

 То же, но более наглядно:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="x14ac xr xr2 xr3" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac" xmlns:xr="http://schemas.microsoft.com/office/spreadsheetml/2014/revision" xmlns:xr2="http://schemas.microsoft.com/office/spreadsheetml/2015/revision2" xmlns:xr3="http://schemas.microsoft.com/office/spreadsheetml/2016/revision3" xr:uid="{00000000-0001-0000-0000-000000000000}">
	<dimension ref="B2:F6"/>
	<sheetViews>
		<sheetView tabSelected="1" workbookViewId="0">
			<selection activeCell="D12" sqref="D12"/>
		</sheetView>
	</sheetViews>
	<sheetFormatPr defaultRowHeight="14.4" x14ac:dyDescent="0.3"/>
	<sheetData>
		<row r="2" spans="2:6" x14ac:dyDescent="0.3">
			<c r="B2" t="s">
				<v>0</v>
			</c>
		</row>
		<row r="3" spans="2:6" x14ac:dyDescent="0.3">
			<c r="C3" t="s">
				<v>1</v>
			</c>
		</row>
		<row r="4" spans="2:6" x14ac:dyDescent="0.3">
			<c r="D4" t="s">
				<v>2</v>
			</c>
		</row>
		<row r="5" spans="2:6" x14ac:dyDescent="0.3">
			<c r="E5" t="s">
				<v>0</v></c>
		</row>
		<row r="6" spans="2:6" x14ac:dyDescent="0.3">
			<c r="F6" t="s"><v>3</v>
		</c></row>
	</sheetData>
	<pageMargins left="0.7" right="0.7" top="0.75" bottom="0.75" header="0.3" footer="0.3"/>
</worksheet>

Как мы видим, в структуре объектной модели нет никаких «пересечений». Строго говоря рабочая книга — это архив структурированных данных в формате XML. При этом в каждую «строку» входит «столбец», и в нём в свою очередь прописан номер значения данного столбца, по которому оно подтягивается из другого XML файла при открытии книги для экономии места за счёт отсутствия повторяющихся значений. Почему это важно. Если мы захотим написать какой-то обработчик таких файлов, который будет напрямую редактировать данные в этих XML, то ориентироваться надо на такую модель и структуру данных. И правильное определение будет примерно таким: ячейка — это объект внутри столбца, который в свою очередь находится внутри строки в файле xml, в котором хранятся данные о содержимом листа.

Способы обращения к ячейкам

Выбор и активация

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

  1. Это лишь имитация действий пользователя, которая замедляет выполнение программы. Работать с объектами книги можно напрямую без использования методов Select и Activate.
  2. Это усложняет код и может приводить к неожиданным последствиям. Каждый раз перед использованием Select необходимо помнить, какие ещё объекты были выбраны до этого и не забывать при необходимости снимать выбор. Либо, например, в случае использования метода Select в самом начале программы может быть выбрано два листа вместо одного потому что пользователь запустил программу, выбрав другой лист.

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

Отменить выбор  ячеек можно методом Unselect:

Selection.Unselect

Отличие выбора от активации — активировать можно только один объект из раннее выбранных. Выбрать можно несколько объектов.

Если вы записали и редактируете код макроса, то лучше всего заменить Select и Activate на конструкцию With … End With. Например, предположим, что мы записали вот такой макрос:

Sub Macro1()
' Macro1 Macro
    Range("F4:F10,H6:H10").Select 'выбрали два несмежных диапазона зажав ctrl
    Range("H6").Activate          'показывает только то, что я начал выбирать второй диапазон с этой ячейки (она осталась белой). Это действие ни на что не влияет
    With Selection.Interior       
        .Pattern = xlSolid
        .PatternColorIndex = xlAutomatic
        .Color = 65535            'залили желтым цветом, нажав на кнопку заливки на верхней панели
        .TintAndShade = 0
        .PatternTintAndShade = 0
    End With
End Sub

Почему макрос записался таким неэффективным образом? Потому что в каждый момент времени (в каждой строке) программа не знает, что вы будете делать дальше. Поэтому в записи выбор ячеек и действия с ними — это два отдельных действия. Этот код лучше всего оптимизировать (особенно если вы хотите скопировать его внутрь какого-нибудь цикла, который должен будет исполняться много раз и перебирать много объектов). Например, так:

Sub Macro11()
'
' Macro1 Macro
    Range("F4:F10,H6:H10").Select '1. смотрим, что за объект выбран (что идёт до .Select)
    Range("H6").Activate
    With Selection.Interior       '2. понимаем, что у выбранного объекта есть свойство interior, с которым далее идёт работа
        .Pattern = xlSolid
        .PatternColorIndex = xlAutomatic
        .Color = 65535
        .TintAndShade = 0
        .PatternTintAndShade = 0
    End With
End Sub



Sub Optimized_Macro()
    With Range("F4:F10,H6:H10").Interior '3. переносим объект напрямую в конструкцию With вместо Selection
' ////// Здесь я для надёжности прописал бы ещё Thisworkbook.Sheet("ИмяЛиста") перед Range,
' ////// чтобы минимизировать риск любых случайных изменений других листов и книг
' ////// With Thisworkbook.Sheet("ИмяЛиста").Range("F4:F10,H6:H10").Interior
        .Pattern = xlSolid               '4. полностью копируем всё, что было записано рекордером внутрь блока with
        .PatternColorIndex = xlAutomatic
        .Color = 55555                   '5. здесь я поменял цвет на зеленый, чтобы было видно, работает ли код при поочерёдном запуске двух макросов
        .TintAndShade = 0
        .PatternTintAndShade = 0
    End With
End Sub

Пример сценария, когда использование Select и Activate оправдано:

Допустим, мы хотим, чтобы во время исполнения программы мы одновременно изменяли несколько листов одним действием и пользователь видел какой-то определённый лист. Это можно сделать примерно так:

Sub Select_Activate_is_OK()
Thisworkbook.Worksheets(Array("Sheet1", "Sheet3")).Select 'Выбираем несколько листов по именам
Thisworkbook.Worksheets("Sheet3").Activate 'Показываем пользователю третий лист
'Далее все действия с выбранными ячейками через Select будут одновременно вносить изменения в оба выбранных листа

'Допустим, что тут мы решили покрасить те же два диапазона:
Range("F4:F10,H6:H10").Select
    Range("H6").Activate
    With Selection.Interior       
        .Pattern = xlSolid
        .PatternColorIndex = xlAutomatic
        .Color = 65535
        .TintAndShade = 0
        .PatternTintAndShade = 0
    End With

End Sub

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

Получение и изменение значений ячеек

Значение ячеек можно получать/изменять с помощью свойства value. 

'Если нужно прочитать / записать значение ячейки, то используется свойство Value
a = ThisWorkbook.Sheets("Sheet1").Cells (1,1).Value 'записать значение ячейки А1 листа "Sheet1" в переменную "a"
ThisWorkbook.Sheets("Sheet1").Cells (1,1).Value = 1  'задать значение ячейки А1 (первый ряд, первый столбец) листа "Sheet1"

'Если нужно прочитать текст как есть (с форматированием), то можно использовать свойство .text:
ThisWorkbook.Sheets("Sheet1").Cells (1,1).Text = "1" 
a = ThisWorkbook.Sheets("Sheet1").Cells (1,1).Text

'Когда проявится разница:
'Например, если мы считываем дату в формате "31 декабря 2021 г.", хранящуюся как дата
a = ThisWorkbook.Sheets("Sheet1").Cells (1,1).Value 'эапишет как "31.12.2021"
a = ThisWorkbook.Sheets("Sheet1").Cells (1,1).Text  'запишет как "31 декабря 2021 г."

Ячейки открытой книги

К ячейкам можно обращаться:

'В книге, в которой хранится макрос (на каком-то из листов, либо в отдельном модуле или форме)
ThisWorkbook.Sheets("Sheet1").Cells(1,1).Value        'По номерам строки и столбца
ThisWorkbook.Sheets("Sheet1").Cells(1,"A").Value      'По номерам строки и букве столбца
ThisWorkbook.Sheets("Sheet1").Range("A1").Value       'По адресу - вариант 1
ThisWorkbook.Sheets("Sheet1").[A1].Value              'По адресу - вариант 2
ThisWorkbook.Sheets("Sheet1").Range("CellName").Value 'По имени ячейки (для этого ей предварительно нужно его присвоить)

'Те же действия, но с использованием полного названия рабочей книги (книга должна быть открыта)
Workbooks("workbook.xlsm").Sheets("Sheet1").Cells(1,1).Value 'По номерам строки и столбца
Workbooks("workbook.xlsm").Sheets("Sheet1").Cells(1,"A").Value                'По номерам строки и букве столбца
Workbooks("workbook.xlsm").Sheets("Sheet1").Range("A1").Value                 'По адресу - вариант 1
Workbooks("workbook.xlsm").Sheets("Sheet1").[A1].Value                        'По адресу - вариант 2
Workbooks("workbook.xlsm").Sheets("Sheet1").Range("CellName").Value           'По имени ячейки (для этого ей предварительно нужно его присвоить)

Ячейки закрытой книги

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

Workbooks.Open Filename:="С:closed_workbook.xlsx"    'открыть книгу (она становится активной)
a = ActiveWorkbook.Sheets("Sheet1").Cells(1,1).Value  'достать значение ячейки 1,1
ActiveWorkbook.Close False                            'закрыть книгу (False => без сохранения)

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

Код из файла:

Option Explicit
Sub get_value_from_closed_wb() 'достать значение из закрытой книги
Dim a, wb_path, wsh As String
wb_path = ThisWorkbook.Sheets("Sheet1").Cells(2, 3).Value 'get path to workbook from sheet1
wsh = ThisWorkbook.Sheets("Sheet1").Cells(3, 3).Value
Workbooks.Open Filename:=wb_path
a = ActiveWorkbook.Sheets(wsh).Cells(3, 3).Value
ActiveWorkbook.Close False
ThisWorkbook.Sheets("Sheet1").Cells(4, 3).Value = a
End Sub

Sub record_value_to_closed_wb() 'записать значение в закрытую книгу
Dim wb_path, b, wsh As String
wsh = ThisWorkbook.Sheets("Sheet1").Cells(3, 3).Value
wb_path = ThisWorkbook.Sheets("Sheet1").Cells(2, 3).Value 'get path to workbook from sheet1
b = ThisWorkbook.Sheets("Sheet1").Cells(5, 3).Value 'get value to record in the target workbook
Workbooks.Open Filename:=wb_path
ActiveWorkbook.Sheets(wsh).Cells(4, 4).Value = b 'add new value to cell D4 of the target workbook
ActiveWorkbook.Close True
End Sub

Перебор ячеек

Перебор в произвольном диапазоне

Скачать файл со всеми примерами

Пройтись по всем ячейкам в нужном диапазоне можно разными способами. Основные:

  1. Цикл For Each. Пример:
    Sub iterate_over_cells()
    
    For Each c In ThisWorkbook.Sheets("Sheet1").Range("B2:D4").Cells
    MsgBox (c)
    Next c
    
    End Sub​

    Этот цикл выведет в виде сообщений значения ячеек в диапазоне B2:D4 по порядку по строкам слева направо и по столбцам — сверху вниз. Данный способ можно использовать для действий, в который вам не важны номера ячеек (закрашивание, изменение форматирования, пересчёт чего-то и т.д.).

  2. Ту же задачу можно решить с помощью двух вложенных циклов — внешний будет перебирать ряды, а вложенный — ячейки в рядах. Этот способ я использую чаще всего, потому что он позволяет получить больше контроля над исполнением: на каждой итерации цикла нам доступны координаты ячеек. Для перебора всех ячеек на листе этим методом потребуется найти последнюю заполненную ячейку. Пример кода:
    Sub iterate_over_cells()
    
    Dim cl, rw As Integer
    Dim x As Variant
    
    'перебор области 3x3
    For rw = 1 To 3 ' цикл для перебора рядов 1-3
    
        For cl = 1 To 3 'цикл для перебора столбцов 1-3
            x = ThisWorkbook.Sheets("Sheet1").Cells(rw + 1, cl + 1).Value
            MsgBox (x)
        Next cl
    Next rw
    
    
    
    'перебор всех ячеек на листе. Последняя ячейка определена с помощью UsedRange
    'LastRow = ActiveSheet.UsedRange.Row + ActiveSheet.UsedRange.Rows.Count - 1
    'LastCol = ActiveSheet.UsedRange.Column + ActiveSheet.UsedRange.Columns.Count - 1
    'For rw = 1 To LastRow 'цикл перебора всех рядов
    '    For cl = 1 To LastCol 'цикл для перебора всех столбцов
    '        Действия 
    '    Next cl
    'Next rw
    
    
    End Sub​
  3. Если нужно перебрать все ячейки в выделенном диапазоне на активном листе, то код будет выглядеть так:
    Sub iterate_cell_by_cell_over_selection()
        Dim ActSheet As Worksheet
        Dim SelRange As Range
        Dim cell As Range
        
     
        Set ActSheet = ActiveSheet
        Set SelRange = Selection
        
        'if we want to do it in every cell of the selected range
        For Each cell In Selection
        MsgBox (cell.Value)
        
        Next cell
    
    End Sub​

    Данный метод подходит для интерактивных макросов, которые выполняют действия над выбранными пользователем областями.

  4. Перебор ячеек в ряду
    Sub iterate_cells_in_row()
        Dim i, RowNum, StartCell As Long
        
        RowNum = 3 'какой ряд
        StartCell = 0 ' номер начальной ячейки (минус 1, т.к. в цикле мы прибавляем i)
        
        For i = 1 To 10 ' 10 ячеек в выбранном ряду
        ThisWorkbook.Sheets("Sheet1").Cells(RowNum, i + StartCell).Value = i '(i + StartCell) добавляет 1 к номеру столбца при каждом повторении
        Next i
    
    End Sub
  5. Перебор ячеек в столбце
    Sub iterate_cells_in_column()
        Dim i, ColNum, StartCell As Long
        
        ColNum = 3 'какой столбец
        StartCell = 0 ' номер начальной ячейки (минус 1, т.к. в цикле мы прибавляем i)
        
        For i = 1 To 10 ' 10 ячеек
        ThisWorkbook.Sheets("Sheet1").Cells(i + StartCell, ColNum).Value = i ' (i + StartCell) добавляет 1 к номеру ряда при каждом повторении
        Next i
    
    End Sub​

Свойства и методы ячеек

Имя ячейки

Присвоить новое имя можно так:

Thisworkbook.Sheets(1).Cells(1,1).name = "Новое_Имя"

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

ActiveWorkbook.Names("Старое_Имя").Delete

Пример кода для переименования ячеек:

Sub rename_cell()

old_name = "Cell_Old_Name"
new_name = "Cell_New_Name"

ActiveWorkbook.Names(old_name).Delete
ThisWorkbook.Sheets(1).Cells(2, 1).Name = new_name
End Sub

Sub rename_cell_reverse()

old_name = "Cell_New_Name"
new_name = "Cell_Old_Name"

ActiveWorkbook.Names(old_name).Delete
ThisWorkbook.Sheets(1).Cells(2, 1).Name = new_name
End Sub

Адрес ячейки

Sub get_cell_address() ' вывести адрес ячейки в формате буква столбца, номер ряда
  '$A$1 style
  txt_address = ThisWorkbook.Sheets(1).Cells(3, 2).Address
  MsgBox (txt_address)
End Sub

Sub get_cell_address_R1C1()' получить адрес столбца в формате номер ряда, номер столбца
  'R1C1 style
  txt_address = ThisWorkbook.Sheets(1).Cells(3, 2).Address(ReferenceStyle:=xlR1C1)
  MsgBox (txt_address)
End Sub

  'пример функции, которая принимает 2 аргумента: название именованного диапазона и тип желаемого адреса 
  '(1- тип $A$1 2- R1C1 - номер ряда, столбца)
Function get_cell_address_by_name(str As String, address_type As Integer)
  '$A$1 style
  Select Case address_type
    Case 1
      txt_address = Range(str).Address
    Case 2
      txt_address = Range(str).Address(ReferenceStyle:=xlR1C1)
    Case Else
      txt_address = "Wrong address type selected. 1,2 available"
    End Select
  get_cell_address_by_name = txt_address
End Function

'перед запуском нужно убедиться, что в книге есть диапазон с названием, 
'адрес которого мы хотим получить, иначе будет ошибка
Sub test_function() 'запустите эту программу, чтобы увидеть, как работает функция
  x = get_cell_address_by_name("MyValue", 2)
  MsgBox (x)
End Sub

Размеры ячейки

Ширина и длина ячейки в VBA меняется, например, так:

Sub change_size()
Dim x, y As Integer
Dim w, h As Double

'получить координаты целевой ячейки
x = ThisWorkbook.Sheets("Sheet1").Cells(2, 2).Value
y = ThisWorkbook.Sheets("Sheet1").Cells(3, 2).Value

'получить желаемую ширину и высоту ячейки
w = ThisWorkbook.Sheets("Sheet1").Cells(6, 2).Value
h = ThisWorkbook.Sheets("Sheet1").Cells(7, 2).Value

'сменить высоту и ширину ячейки с координатами x,y
ThisWorkbook.Sheets("Sheet1").Cells(x, y).RowHeight = h
ThisWorkbook.Sheets("Sheet1").Cells(x, y).ColumnWidth = w


End Sub

Прочитать значения ширины и высоты ячеек можно двумя способами (однако результаты будут в разных единицах измерения). Если написать просто Cells(x,y).Width или Cells(x,y).Height, то будет получен результат в pt (привязка к размеру шрифта). 

Sub get_size()
Dim x, y As Integer
'получить координаты ячейки, с которой мы будем работать
x = ThisWorkbook.Sheets("Sheet1").Cells(2, 2).Value
y = ThisWorkbook.Sheets("Sheet1").Cells(3, 2).Value

'получить длину и ширину выбранной ячейки в тех же единицах измерения, в которых мы их задавали
ThisWorkbook.Sheets("Sheet1").Cells(2, 6).Value = ThisWorkbook.Sheets("Sheet1").Cells(x, y).ColumnWidth
ThisWorkbook.Sheets("Sheet1").Cells(3, 6).Value = ThisWorkbook.Sheets("Sheet1").Cells(x, y).RowHeight

'получить длину и ширину с помощью свойств ячейки (только для чтения) в поинтах (pt)
ThisWorkbook.Sheets("Sheet1").Cells(7, 9).Value = ThisWorkbook.Sheets("Sheet1").Cells(x, y).Width
ThisWorkbook.Sheets("Sheet1").Cells(8, 9).Value = ThisWorkbook.Sheets("Sheet1").Cells(x, y).Height

End Sub

Скачать файл с примерами изменения и чтения размера ячеек

Запуск макроса активацией ячейки

Для запуска кода VBA при активации ячейки необходимо вставить в код листа нечто подобное:

3 важных момента, чтобы это работало:

1. Этот код должен быть вставлен в код листа (здесь контролируется диапазон D4)

2-3. Программа, ответственная за запуск кода при выборе ячейки, должна называться Worksheet_SelectionChange и должна принимать значение переменной Target, относящейся к триггеру SelectionChange. Другие доступные триггеры можно посмотреть в правом верхнем углу (2).

Скачать файл с базовым примером (как на картинке)

Скачать файл с расширенным примером (код ниже)

Option Explicit

Private Sub Worksheet_SelectionChange(ByVal Target As Range)

        ' имеем в виду, что триггер SelectionChange будет запускать эту Sub после каждого клика мышью (после каждого клика будет проверяться:
          '1. количество выделенных ячеек и 
          '2. не пересекается ли выбранный диапазон с заданным в этой программе диапазоном.
        ' поэтому в эту программу не стоит без необходимости писать никаких других тяжелых операций

    If Selection.Count = 1 Then 'запускаем программу только если выбрано не более 1 ячейки


    'вариант модификации - брать адрес ячейки из другой ячейки:
    'Dim CellName as String
    'CellName = Activesheet.Cells(1,1).value 'брать текстовое имя контролируемой ячейки из A1 (должно быть в формате Буква столбца + номер строки)
    'If Not Intersect(Range(CellName), Target) Is Nothing Then
    'для работы этой модификации следующую строку надо закомментировать/удалить



        If Not Intersect(Range("D4"), Target) Is Nothing Then 
        'если заданный (D4) и выбранный диапазон пересекаются 
        '(пересечение диапазонов НЕ равно Nothing)

        'можно прописать диапазон из нескольких ячеек:
        'If Not Intersect(Range("D4:E10"), Target) Is Nothing Then
        'можно прописать несколько диапазонов:
        'If Not Intersect(Range("D4:E10"), Target) Is Nothing or Not Intersect(Range("A4:A10"), Target) Is Nothing Then

            Call program 'выполняем программу
        End If
    End If
End Sub

Sub program()

MsgBox ("Program Is running") 'здесь пишем код того, что произойдёт при выборе нужной ячейки


End Sub

Как определить адрес активной ячейки.

Q: Как в макросе узнать и использовать текущее положение курсора (не мышиного, естественно)?

A:Очень просто! :-) ActiveCell.Row и ActiveCell.Column — покажут координаты активной ячейки.

[ Назад ]
[ Оглавление ]
[ Далее ]

Оставить комментарий

Комментарий:

можно использовать BB-коды

Максимальная длина комментария — 4000 символов.

 

Комментарии

1.

Мне нравитсяМне не нравится

17 апреля 2013, 22:49:22

Спасибо, освежило память))

2.

64K

28 сентября 2010 года

Vladlen70

0 / / 28.09.2010

Мне нравитсяМне не нравится

28 сентября 2010, 16:25:13

А не проще ли использовать — ActiveCell.Address или Activecell.AddressLocal?

Добрый день, хотелось бы написать макрос, который реагирует на изменение данных в ячейке, то есть если в одном листе excel-евского файла в какой-то ячейке ввести число например 543 то макрос переходит не визуально, а в памяти, на другой лист файла, а там таблица из нескольких столбцов с числами, так вот макрос находит в определенном солбце это (543) число, далее сравнивает рядом с ним стоящее в одной строке число с нулем, если оно меньше нуля то макрос возвращает в ту ячейку куда вводили число 543 значение того отрицательного числа которое стоит рядом в одной строке с числом 543. Ну а если число которое стоит в таблице рядом с 543 больше нуля то макрос ни чего не делает, а оператор вводит данные в другую ячейку. Ну в общем-то как сравнивать числа и выводить число в какую-то ячейку с этим я сам справлюсь, а вот как написать чтобы макрос начинал работу после введения данных в ячейку — вот это я не знаю. Кто знает подскажите пожалуйста?  
Привожу примерый макрос НО без начала  

    Sub сравнение()  
‘  
‘ сравнение Макрос  
‘ Макрос записан 13.02.2010 (ккк)  
‘  
‘ Сочетание клавиш: Ctrl+s  
‘  
Dim a As Integer ‘ — это номер строки в таблице где происходит сравнение  
Dim n As Integer ‘ — это переменная которой присваивается значение числа после того как его ввели  
Dim x As Integer ‘ — это номер строки на которой находиться ячейка в которую вводиться число  
Dim y As Integer ‘ — это номер столбца в котором находиться ячейка в которую вводиться число

      a = 1 ‘задается номер строки с которой начинаем

      ‘       ВОТ ТУТ КАК РАЗ В МЕСТО ЭТИХ ТРЕХ СТРОЧЕК И ДОЛЖНА ПО ИДЕЕ БЫТЬ КОМАНДА  
‘              КОТОРАЯ ЗАПУСКАЕТ МАКРОС ПОСЛЕ ВВОДА ЧИСЛА В ЯЧЕЙКУ
 
‘    Range(«B2»).Select    
‘    ActiveCell.FormulaR1C1 = «543»  
‘    n = введенному в ячейку числу  

     x = 2 ‘ для того чтобы макрос хоть как то работал задаем умышленно фиксированное значение  
 y = 2 ‘ для того чтобы макрос хоть как то работал задаем умышленно фиксированное значение  
 n = Sheets(«лист-данные»).Cells(x, y) ‘присваиваем переменной n значение введенного в ячейку числа  
2           If n = Sheets(«лист-таблица»).Cells(a, 1) Then GoTo 1 ‘ находим такое же число как оператор вводил но уже в эталонной таблице  
   a = a + 1  
   If a <= 50 Then GoTo 2  
1      If Sheets(«лист-таблица»).Cells(a, 2) > 0 Then GoTo 3 ‘ Число найдено, а сдесь выясняем отрицательное ли число которое стоит рядом в эталонной таблице

   Sheets(«лист-данные»).Cells(x, y) = Sheets(«лист-таблица»).Cells(a, 2) ‘присваивается здачение отрицательного числа ячейке в которую изначально был ввод  
 Sheets(«лист-данные»).Select ‘ну тут ниже меняетс цвет шриф для яркости  
   Cells(x, y).Select    
    Selection.Font.ColorIndex = 3  
     Selection.Font.Bold = True  
     With Selection.Font  
         .Name = «Arial Cyr»  
         .Size = 12  
         .Strikethrough = False  
         .Superscript = False  
         .Subscript = False  
         .OutlineFont = False  
         .Shadow = False  
         .Underline = xlUnderlineStyleNone  
         .ColorIndex = 3  
     End With  
     pause (20 = cek) ‘ то же не знаю как писать паузу в работе, а она нужна чтобы оператор увидел результат  
4       r = r + 1  
   If r < 50000000 Then GoTo 4 ‘ пришлось вместо паузы вот такой ерундой заниматься  
 Selection.ClearContents ‘очистка ячейки куда был ввод  
 Selection.Font.ColorIndex = 1  

  3     End Sub  

  Естественно макрос до коца не проработан, да это не главное сейча для меня, проработаю, мне важно начало его написать.

Активная ячейка в Excel VBA

Активная ячейка — это текущая выбранная ячейка на листе, активная ячейка в VBA может использоваться как ссылка для перехода к другой ячейке или изменения свойств той же активной ячейки или ссылки на ячейки, предоставленной из активной ячейки, активная ячейка в VBA может можно получить с помощью метода application.property с ключевым словом active cell.

Для эффективной работы с кодированием VBA важно понимать концепцию объекта диапазона и свойств ячеек в VBA. В этих концепциях есть еще одна концепция, которую вам нужно изучить, это «активная ячейка VBA».

В Excel есть миллионы ячеек, и вы наверняка сомневаетесь, какая из них является активной. Для примера посмотрите на изображение ниже.

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

Если ваша активная ячейка не видна в вашем окне, посмотрите на поле имени, оно покажет вам адрес активной ячейки, на приведенном выше изображении адрес активной ячейки — B3.

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

# 1 — Ссылки в Excel VBA

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

Например, если мы хотим выбрать ячейку A1 и вставить значение «Hello», мы можем записать его двумя способами. Ниже приведен способ выбора ячейки и вставки значения с помощью объекта VBA «RANGE».

Код:

 Sub ActiveCell_Example1 () Диапазон ("A1"). Выберите диапазон ("A1"). Value = "Hello" End Sub 

Сначала будет выбрана ячейка A1 « Диапазон (« A1 »). Выбрать»

Затем он вставит значение «Hello» в диапазон ячейки A1 («A1»). Value = «Hello»

Теперь я удалю строку Range («A1»). Value = «Hello» и использую свойство Active Cell для вставки значения.

Код:

 Sub ActiveCell_Example1 () Диапазон ("A1"). Выберите ActiveCell.Value = "Hello" End Sub 

Точно так же сначала он выберет ячейку A1 « Диапазон (« A1 »). Выбрать»

Но здесь я использовал ActiveCell.Value = «Hello» вместо Range («A1»). Value = «Hello»

Причина, по которой я использовал свойство Active Cell, потому что в тот момент, когда я выбираю ячейку A1, она становится активной ячейкой. Таким образом, мы можем использовать свойство Excel VBA Active Cell для вставки значения.

# 2 — Активный адрес ячейки, значение, строка и номер столбца

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

На изображении выше активной ячейкой является «B3», а значение — 55. Давайте напишем код на VBA, чтобы получить адрес активной ячейки.

Код:

 Sub ActiveCell_Example2 () MsgBox ActiveCell.Address End Sub 

Запустите этот код с помощью клавиши F5 или вручную, тогда он покажет адрес активной ячейки в окне сообщения.

Выход:

Точно так же код ниже покажет значение активной ячейки.

Код:

 Sub ActiveCell_Example2 () MsgBox ActiveCell.Value End Sub 

Выход:

Код ниже покажет номер строки активной ячейки.

Код:

 Sub ActiveCell_Example2 () MsgBox ActiveCell.Row End Sub 

Выход:

Код ниже покажет номер столбца активной ячейки.

Код:

 Подложка ActiveCell_Example2 () MsgBox ActiveCell.Column End Sub 

Выход:

# 3 — Параметры активной ячейки в Excel VBA

Свойство Active Cell также имеет параметры. После ввода свойства ActiveCell откройте скобку, чтобы увидеть параметры.

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

Например, ActiveCell (1,1) означает, какая ячейка активна. Если вы хотите переместиться на одну строку ниже, вы можете использовать ActiveCell (2,1), здесь 2 не означает, что нужно переместиться на две строки вниз, а не только на одну строку вниз. Аналогично, если вы хотите переместить один столбец вправо, тогда это код ActiveCell (2,2)

Для примера посмотрите на изображение ниже.

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

Код:

ActiveCell.Value = «Hiiii» или ActiveCell (1,1) .Value = «Hiiii»

Запустите этот код вручную или с помощью клавиши F5, это вставит значение «Hiiii» в ячейку.

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

Код:

ActiveCell (2,1) .Value = «Hiiii»

Это вставит значение в ячейку под активной ячейкой.

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

Код:

ActiveCell (1,2) .Value = «Hiiii»

Это вставит «Hiiii» в следующую ячейку столбца активной ячейки.

Таким образом, мы можем ссылаться на ячейки в VBA, используя свойство Active Cell.

Надеюсь, вам понравилось. Спасибо, что уделили нам время.

Вы можете скачать шаблон VBA Active Cell Excel здесь: — VBA Active Cell Template

Содержание

  • 1 Как определить адрес активной ячейки.
  • 2 Обращение к ячейке
  • 3 Запись информации в ячейку
  • 4 Чтение информации из ячейки
  • 5 Очистка значения ячейки

Здравствуйте. Googl меня не понимает, может вы подскажите?

Есть форма календарь, которая запускается кнопкой.

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

Можно в продцедуре календаря изменить

ActiveCell.Value = Calendar1.Value

например на

 = Calendar1.Value

но на листе несколько ячеек, в которые нужно вставлять разные даты.

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

Отображение формы запускается так

Private Sub CommandButton1_Click()
    frmCalendar.Show
End Sub

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

CodeNet

/

Языки программирования

/

Visual Basic

/

VBA

/

Excel VBA: Приёмы программирования

Как определить адрес активной ячейки.

Q: Как в макросе узнать и использовать текущее положение курсора (не мышиного, естественно)?

A:Очень просто! 🙂 ActiveCell.Row и ActiveCell.Column — покажут координаты активной ячейки.

Комментарий:

можно использовать BB-коды

Максимальная длина комментария — 4000 символов.

CodeNet

ВКонтакте

Facebook

Twitter

Google

Яндекс

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

 

1.

90K

17 апреля 2013 года

Дмитрий Литвиненко

0 / / 17.04.2013

+1 / -1

17 апреля 2013, 22:49:22

Спасибо, освежило память))

2.

64K

28 сентября 2010 года

Vladlen70

0 / / 28.09.2010

+3 / -1

28 сентября 2010, 16:25:13

А не проще ли использовать — ActiveCell.Address или Activecell.AddressLocal?

Обращение к ячейке на листе Excel из кода VBA. Запись информации в ячейку. Чтение информации из ячейки. Очистка значения ячейки. Метод ClearContents объекта Range.

  1. Обращение к ячейке
  2. Запись информации в ячейку
  3. Чтение информации из ячейки
  4. Очистка значения ячейки

Обращение к ячейке

Допустим, у нас есть два открытых файла: «Книга1» и «Книга2», причем, файл «Книга1» активен и в нем находится исполняемый код VBA.

В общем случае при обращении к ячейке неактивной рабочей книги «Книга2» из кода файла «Книга1» прописывается полный путь:

  Workbooks("Книга2.xlsm").Sheets("Лист2").Range("C5")  Workbooks("Книга2.xlsm").Sheets("Лист2").Cells(5, 3)  

Удобнее обращаться к ячейке через свойство рабочего листа Cells(номер строки, номер столбца), так как вместо номеров строк и столбцов можно использовать переменные. Обратите внимание, что при обращении к любой рабочей книге, она должна быть открыта, иначе произойдет ошибка. Закрытую книгу перед обращением к ней необходимо открыть.

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

  ActiveCell  Range("A1")  Cells(1, 1)  

Точно также можно обращаться и к другим ячейкам активного рабочего листа, кроме обращения ActiveCell, так как активной может быть только одна ячейка, в нашем примере — это ячейка «A1».

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

  Sheets("Лист3").Cells(2, 8)  

Кроме того к ячейке на рабочем листе можно обращаться по ее индексу (порядковому номеру), который считается по расположению ячейки на листе слева-направо и сверху-вниз. Например, индекс ячеек в первой строке равен номеру столбца. Индекс ячеек во второй строке равен количеству ячеек в первой строке (которое равно общему количеству столбцов на листе — зависит от версии Excel) плюс номер столбца. Индекс ячеек в третьей строке равен количеству ячеек в двух первых строках плюс номер столбца. И так далее. Для примера, Cells(4) та же ячейка, что и Cells(1, 4). Используется такое обозначение редко, тем более, что у разных версий Excel может быть разным количество столбцов и строк на рабочем листе.

Запись информации в ячейку

Содержание ячейки определяется ее свойством — «Value», которое в VBA Excel является свойством по умолчанию и его можно явно не указывать. Записывается информация в ячейку при помощи оператора присваивания «=»:

  Cells(2, 4).Value = 15  Cells(2, 4) = 15  Range("A1") = "Этот текст записываем в ячейку"  ActiveCell = 28 + 10*36  

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

Чтение информации из ячейки

Считать информацию из ячейки в переменную можно также при помощи оператора присваивания «=»:

  Sub Test()  Dim a1 As Integer, a2 As Integer, a3 As Integer  Range("A3") = 6  Cells(2, 5) = 15  a1 = Range("A3")  a2 = Cells(2, 5)  a3 = a1 * a2  MsgBox a3  End Sub  

Точно также можно обмениваться информацией между ячейками:

  Cells(2, 2) = Range("A4")  

Очистка значения ячейки

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

  Cells(10, 2).ClearContents  Range("D23") = 0  ActiveCell = ""  

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

    Хитрости »

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


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

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