Как обратится к ячейке vba excel

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

Обращение к ячейке по адресу

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

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

Workbooks(«Книга2.xlsm»).Sheets(«Лист2»).Range(«C5»)

Workbooks(«Книга2.xlsm»).Sheets(«Лист2»).Cells(5, 3)

Workbooks(«Книга2.xlsm»).Sheets(«Лист2»).Cells(5, «C»)

Workbooks(«Книга2.xlsm»).Sheets(«Лист2»).[C5]

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

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

ActiveCell

Range(«A1»)

Cells(1, 1)

Cells(1, «A»)

[A1]

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

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

‘по основному имени листа

Лист2.Cells(2, 7)

‘по имени ярлыка

Sheets(«Имя ярлыка»).Cells(3, 8)

Имя ярлыка может совпадать с основным именем листа. Увидеть эти имена можно в окне редактора VBA в проводнике проекта. Без скобок отображается основное имя листа, в скобках – имя ярлыка.

Обращение к ячейке по индексу

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

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

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

По индексу можно обращаться к ячейке не только на всем рабочем листе, но и в отдельном диапазоне. Нумерация ячеек осуществляется в пределах заданного диапазона по тому же правилу: слева-направо и сверху-вниз. Вот индексы ячеек диапазона Range(«A1:C3»):

Индексы ячеек в диапазоне Range("A1:C3")

Обращение к ячейке Range("A1:C3").Cells(5) соответствует выражению Range("B2").

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

Если ячейке на рабочем листе Excel присвоено имя (Формулы –> Присвоить имя), то обращаться к ней можно по присвоенному имени.

Допустим одной из ячеек присвоено имя – «Итого», тогда обратиться к ней можно – Range("Итого").

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

Содержание ячейки определяется ее свойством «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. Кроме того, можно присвоить ячейке значение нуля. пустой строки или Empty:

Cells(10, 2).ClearContents

Range(«D23») = 0

ActiveCell = «»

Cells(5, «D») = Empty

Всё о работе с ячейками в 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

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

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

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

Полный путь к ячейке A1 в Книге1 на Листе1 можно записать двумя вариантами:

  • С помощью Range
  • С помощью Cells

Пример 1: Обратиться к ячейке A3 находящейся в Книге1 на Листе1

Workbooks("Книга1.xls").Sheets("Лист1").Range("A3") ' Обратиться к ячейке A3
Workbooks("Книга1.xls").Sheets("Лист1").Cells(3, 1) ' Обратиться к ячейке в 3-й строке и 1-й колонке (A3)

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

Пример 2: Обратиться к ячейке A1 в текущей книге на активном листе

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

Если всё же путь к книге или листу необходим, но не хочется его писать при каждом обращении к ячейкам, можно использовать конструкцию With End With. При этом, обращаясь к ячейкам, необходимо использовать в начале «.» (точку).

Пример 3: Обратиться к ячейке A1 и B1 в Книге1 на Листе2.

With Workbooks("Книга1").Sheets("Лист2")
  ' Вывести значение ячейки A1, которая находится на Листе2
  MsgBox .Range("A1")
  ' Вывести значение ячейки B1, которая находится на Листе2
  MsgBox .Range("B1")
End With

Так же, можно обратиться и к активной (выбранной в данный момент времени) ячейке.

Пример 4: Обратиться к активной ячейке на Листе3 текущей книги.

Application.ActiveCell ' полная запись
ActiveCell ' краткая запись

Чтение значения из ячейки

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

  • Value2 — базовое значение ячейки, т.е. как оно хранится в самом Excel-е. В связи с чем, например, дата будет прочтена как число от 1 до 2958466, а время будет прочитано как дробное число. Value2 — самый быстрый способ чтения значения, т.к. не происходит никаких преобразований.
  • Value — значение ячейки, приведенное к типу ячейки. Если ячейка хранит дату, будет приведено к типу Date. Если ячейка отформатирована как валюта, будет преобразована к типу Currency (в связи с чем, знаки с 5-го и далее будут усечены).
  • Text — визуальное отображение значения ячейки. Например, если ячейка, содержит дату в виде «число месяц прописью год», то Text (в отличие от Value и Value2) именно в таком виде и вернет значение. Использовать Text нужно осторожно, т.к., если, например, значение не входит в ячейку и отображается в виде «#####» то Text вернет вам не само значение, а эти самые «решетки».

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

Пример 5: В ячейке A1 активного листа находится дата 01.03.2018. Для ячейки выбран формат «14 марта 2001 г.». Необходимо прочитать значение ячейки всеми перечисленными выше способами и отобразить в диалоговом окне.

MsgBox Cells(1, 1)        ' выведет 01.03.2018
MsgBox Cells(1, 1).Value  ' выведет 01.03.2018
MsgBox Cells(1, 1).Value2 ' выведет 43160
MsgBox Cells(1, 1).Text   ' выведет 01 марта 2018 г.

Dim d As Date
d = Cells(1, 1).Value2    ' числовое представление даты преобразуется в тип Date
MsgBox d                  ' выведет 01.03.2018

Пример 6: В ячейке С1 активного листа находится значение 123,456789. Для ячейки выбран формат «Денежный» с 3 десятичными знаками. Необходимо прочитать значение ячейки всеми перечисленными выше способами и отобразить в диалоговом окне.

MsgBox Range("C1")        ' выведет 123,4568
MsgBox Range("C1").Value  ' выведет 123,4568
MsgBox Range("C1").Value2 ' выведет 123,456789
MsgBox Range("C1").Text   ' выведет 123,457р.

Dim c As Currency
c = Range("C1").Value2    ' значение преобразуется в тип Currency
MsgBox c                  ' выведет 123,4568

Dim d As Double
d = Range("C1").Value2    ' значение преобразуется в тип Double
MsgBox d                  ' выведет 123,456789

При присвоении значения переменной или элементу массива, необходимо учитывать тип переменной. Например, если оператором Dim задан тип Integer, а в ячейке находится текст, при выполнении произойдет ошибка «Type mismatch». Как определить тип значения в ячейке, рассказано в следующей статье.

Пример 7: В ячейке B1 активного листа находится текст. Прочитать значение ячейки в переменную.

Dim s As String
Dim i As Integer
s = Range("B1").Value2 ' успех
i = Range("B1").Value2 ' ошибка

Таким образом, разница между Text, Value и Value2 в способе получения значения. Очевидно, что Value2 наиболее предпочтителен, но при преобразовании даты в текст (например, чтобы показать значение пользователю), нужно использовать функцию Format.

Запись значения в ячейку

Осуществить запись значения в ячейку можно 2 способами: с помощью Value и Value2. Использование Text для записи значения не возможно, т.к. это свойство только для чтения.

Пример 8: Записать в ячейку A1 активного листа значение 123,45

Range("A1") = 123.45
Range("A1").Value = 123.45
Range("A1").Value2 = 123.45

Все три строки запишут в A1 одно и то же значение.

Пример 9: Записать в ячейку A2 активного листа дату 1 марта 2018 года

Cells(2, 1) = #3/1/2018#
Cells(2, 1).Value = #3/1/2018#
Cells(2, 1).Value2 = #3/1/2018#

В данном примере тоже запишется одно и то же значение в ячейку A2 активного листа.

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

In this guide, we’re going to show you how to refer a range or a cell in Excel VBA.

VBA Basics

Before diving into the code, let’s start with a cell or a range means in VBA. First, VBA is an object-based programming language, which means that the language refers each element as objects. Objects have properties that define them, and they can encapsulate other objects, or codes. Thus, a single cell, a range of cells, a worksheet, or Excel software as a whole is an object for VBA. You can think this as a hierarchical model.

The image illustrates only a small portion of Excel objects in VBA. An Excel instance contains a Workbooks collection. A collection is a group of related objects. For example, if you open two workbooks, the Workbooks collection has two Workbook object. Each Workbook object has its own worksheets under a Worksheets collection. This structure applies to all.

VBA envelops all cell and cell-based references in an object called Range. In theory, when a particular object is referenced, you also need to specify its parents. In VBA syntax, a dot (.) operator is used to move through object hierarchy. For example, to access the Range object, the code should be:

Application.Workbooks.Worksheets.Range

However, this reference is ambiguous when it comes to specify which Excel workbook or worksheet you are referring to. In order to do this, you must supply the name or the index number (starting with 1) of the particular object you are referring. This approach is like in Excel formulas — the argument is given in parentheses. For example to refer the range object in the worksheet “Sheet1” of the workbook “Book1.xlsm”:

Application.Workbooks("Book1.xlsm").Worksheets("Sheet1").Range

or

Application.Workbooks(1).Worksheets(1).Range

You do not have to specify all parents for Range object every time. If your intention is to work on the active sheet of the active workbook, you can simply use Range.

Range Object

The Range object allows you to refer a cell or cells just like in any Excel formula. For example,

Range("A1") 'Refers the cell A1
Range("A2:D11") 'Refers the range of cells between A2:D11
Range("A3,B4:E6,F12") 'Refers all cells in the cells A3, F12 and the range B4:E6
Range("2:2") 'Entire 2nd row
Range("E:E") 'Entire column E
Range("Input") 'Named range "Input"

Using square brackets to refer a range or a cell

You can use square brackets ([]) instead of the “Range” keyword and double quotes (“). This approach as essentially a shortcut, and the outcome is the same.

[A1] 'Refers the cell A1
[A2:D11] 'Refers the range of cells between A2:D11
[A3,B4:E6,F12] 'Refers all cells in the cells A3, F12 and the range B4:E6
[2:2] 'Entire 2nd row
[E:E] 'Entire column E
[Input] 'Named range "Input"

Cells property to refer a range or a cell

Cells is the name of a property of both Worksheet and Range objects. It is neither a collection nor an object. Thus, there are no objects named Cell.

In other words, the Cells property returns a Range object as well. Each Cells property in Worksheet and Range objects work in its parent’s context only. This behavior might make more sense within examples.

Syntax

The Cells property can be used in two ways:
With row and column index numbers:

Cells(row number,column number) 

With index number of the cell:

Cells(cell number) ‘refers the 23rd cell in the range

Examples

Worksheet.Cells

Cells property of a Worksheet object returns the cell in a specific location in the worksheet.
With row and column index numbers:

Cells(3,2) 'refers the cell at third row and second column in the active sheet (B3)

How to refer a range or a cell in Excel VBA 02
With index number of the cell:

Cells(5) 'refers the 5th cell in the range (E1)

The numbering of cells starts from 1, and increases from left to right and from top to bottom. This means that A1 is the first cell.

Range.Cells

On the other hand, the Cells property of a Range object returns the cell in specified location in the range.
With row and column index numbers:

Range(&quot;C4:F9&quot;).Cells(3,2) 'refers the cell at third row and second column in the active range (D6)


With index number of the cell:

Range(&quot;C4:F9&quot;).Cells(5) ‘refers the 5th cell in the range (C5)

Active objects to refer a range or a cell

There are keywords in VBA to reference active(selected) objects when the code is running.

ActiveCell 'Refers the selected cell
Selection 'Refers any selected object. This can be cells or a chart
ActiveSheet 'Refers the active worksheet
ActiveWorkbook 'Refers the active worksheet

11.6 Объект Range, его свойства и методы

Объект Excel.Range, программная работа с ячейками и диапазонами (наборами) ячеек средствами VBA, создание объекта Excel.Range, свойства, методы и события объекта Excel.Range

Пожалуй, наиболее часто используемый объект в иерархии объектной модели Excel это объект Range. Этот объект может представлять одну ячейку, несколько ячеек (в том числе несмежные ячейки или наборы несмежных ячеек) или целый лист. Если в Word вы могли для ввода данных использовать как объект Range, так и объект Selection, то в Excel все сводится к объекту Range:
если вам нужно ввести данные в ячейку или отформатировать ее, то вы должны получить объект Range, представляющий эту ячейку;
если вы хотите сделать что-то с выделенными вами ячейками, вам необходимо получить объект Range, представляющий выделение;
если вам нужно просто что-то сделать с группой ячеек, первое ваше действие опять-таки получить объект Range, представляющий эту группу ячеек.

В Microsoft Knowledge Base есть статья под номером 291308, в котором описываются 22 способа получения объекта Range в Excel. Вряд ли вы будете пользоваться всеми эти способами. Мы рассмотрим только самые распространенные:
самый простой и очевидный способ воспользоваться свойством Range. Это свойство предусмотрено для объектов Application, Worksheet и самого объекта Range (если вы решили создать новый диапазон на основе уже существующего). Например, получить ссылку на объект Range, представляющий ячейку A1, можно так:

Dim oRange As Range

Set oRange = Worksheets(«Лист1»).Range(«A1»)

А на диапазон ячеек с A1 по D10 так:

Dim oRange As Range

Set oRange = Worksheets(«Лист1»).Range(«A1:D10»)

С применением свойства Range самого объекта Range нужно быть очень осторожным. Дело в том, что Excel создает на основе объекта Range виртуальный лист со своей собственной нумерацией. Поэтому такой код:

Set oRange1 = Worksheets(«Лист1»).Range(«C1»)

Set oRange2 = oRange1.Range(«B1»)

oRange2.Value = 20

пропишет значение 20 не в ячейку B1, как можно было понять из кода, а в ячейку D1 (то есть B1 по отношению к виртуальному листу, начинающемуся с C1).
второй способ воспользоваться свойством Cells. Возможностей у этого свойства меньше мы можем вернуть диапазон, состоящий только из одной ячейки. Зато мы можем использовать более удобный синтаксис (с точки зрения передачи переменных, перехода в любую сторону на любое количество ячеек и т.п.). Например, для получения ссылки на ячейку D1 можно использовать код вида:

Dim oRange As Range

Set oRange = Worksheets(«Лист1»).Cells(1, 4)

Чтобы получить диапазон, состоящий из нескольких ячеек, удобно применять свойства Range и Cells вместе:

Dim oRange

Set oRange = Range(Cells(1, 1), Cells(5, 3))
третий способ воспользоваться многочисленными свойствами объекта Range, которые позволяют изменить текущий диапазон или создать на основе его новый. Эти свойства будут рассмотрены ниже.

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

oRange.Value = «Мое значение»

Поскольку объект Range с функциональной точки зрения очень важен, то свойств и методов у него очень много (и для комфортной работы в Excel их нужно знать). Ниже представлены некоторые самые употребимые свойства:
Address позволяет вернуть адрес текущего диапазона, например, для предыдущего примера вернется $A$1:$C$5. Этому свойству можно передать много параметров для определения стиля ссылки, абсолютного или относительного адреса для столбцов и строк, по отношению к чему этот адрес будет относительным и т.п. Свойство доступно только для чтения. AddressLocal то же самое, но с поправкой на особенности локализованных версий Excel.

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

sColumnName = Mid(oRange.Address, 2, (InStr(2, oRange.Address, «$») 2))

А номер строки так :

sRowNumber = Mid(oRange.Address, (InStr(2, oRange.Address, «$») + 1))

На первый взгляд кажется сложным, но на самом деле все очень просто для имени столбца мы просто берем все, что у нас находится между первым знаком доллара (он у нас всегда первый символ) и вторым, а для номера строки бы берем все, что у нас находится после второго знака доллара. Найти этот второй знак доллара можно при помощи встроенной функции InStr(), а взять нужное количество символов начиная с какого либо проще всего при помощи встроенной функции Mid().
AllowEdit это свойство, доступное только для чтения, позволяет определить, сможет ли пользователь править данную ячейку (набор ячеек) на защищенном листе. Используется для проверок.
Areas свойство исключительно важное. Дело в том, что, как уже говорилось, объект Range может состоять из несмежных наборов ячеек. Многие методы применительно к таким диапазонам ведут себя совершенно непредсказуемо или просто возвращают ошибки. Свойство Areas позволяет разбить подобные нестандартные диапазоны на набор стандартных. Созданные таким образом объекты Range будут помещены в коллекцию Areas. Это свойство можно использовать и для проверки «нестандартности» диапазона:

If Selection.Areas.Count > 1 Then

Debug.Print «Диапазон с несмежными областями»

End If
Borders возможность получить ссылку на коллекцию Borders, при помощи которой можно управлять рамками для нашего диапазона.
Cells это свойство есть и для объекта Range. Работает оно точно так же, за исключением того, что опять-таки используется своя собственная виртуальная адресация на основе диапазона:

Dim oRange, oRange2 As Range

Set oRange = Range(Cells(2, 2), Cells(5, 3))

Set oRange2 = oRange.Cells(1, 1) ‘Вместо A1 получаем ссылку на B2

Debug.Print oRange2.Address ‘Так оно и есть

Точно такие же особенности у свойств Row и Rows, Column и Columns.
Characters это простое с виду свойство позволяет решить непростую задачу: как изменить (текст или формат) части текста в ячейке, не затрагивая остальные данные. Например, чтобы ввести текст в ячейку A1 и изменить цвет первой буквы, можно воспользоваться кодом

Dim oRange As Range

Set oRange = Range(«A1»)

oRange.Value = «Мой текст»

oRange.Characters(1, 1).Font.Color = vbRed

Если же вам просто нужно изменить значение, то лучше воспользоваться свойством Value как в третьей строке примера.
Count возвращает количество ячеек в диапазоне. Может использоваться для проверок.
CurrentRegion очень удобное свойство, которое может пригодиться, например, при копировании/экспорте данных, полученных из внешнего источника (когда сколько будет этих данных, нам изначально неизвестно). Оно возвращает объект Range, представляющий диапазон, окруженный пустыми ячейками (то есть непустую область, в которую входит исходный диапазон/ячейка). Например, чтобы выделить всю непустую область вокруг активной ячейки, можно воспользоваться кодом

Worksheets(«Лист1»).Activate

ActiveCell.CurrentRegion.Select
Dependents позволяет получить объект Range (скорее всего, включающий несмежные области) которые зависят от ячеек исходного диапазона. Работает только для текущего листа ссылки во внешних листах этим свойством не отслеживаются. Например, чтобы выделить все ячейки, зависимые от активной, можно использовать код
Worksheets(«Лист1»).Activate
ActiveCell.Dependents.Select

Чтобы просмотреть обратную зависимость, можно использовать свойство Precedents. Чтобы просмотреть только первый уровень зависимостей, можно использовать свойства DirectDependents и DirectPrecedents.
End еще одно часто используемое свойство. Оно позволяет получить объект Range, представляющий последнюю ячейку исходного диапазона. В какой стороне будет считаться последняя ячейка, можно определить при помощи передаваемого параметра.
Errors свойство, которое через коллекцию Errors позволяет получить доступ к объектам Error, представляющим обнаруженные ошибки в диапазоне.
Font как и в Word, это свойство позволяет получить доступ к объекту Font, при помощи которого можно настроить особенности оформления текста в ячейке (цвет, шрифт, размер букв и т.п.)
FormatConditions возможность создать собственный объект, представляющий вариант оформления ячеек, который затем можно применять к разным ячейкам и диапазонам.
Formula одно из самых важных свойств объекта Range. Доступно и на чтение, и на запись. Если используется на чтение, то возвращает текст формулы, прописанной в ячейку (а не вычисленное значение), если используется на запись, то позволяет записать формулу в ячейку. Если применить это свойство для диапазона, в который входит несколько ячеек, то формула будет прописана по все ячейки диапазона. Пример применения этого свойства может выглядеть так:

Worksheets(«Лист1»).Range(«A3»).Formula = «=$A$1+$A$2»
Свойство FormulaLocal, как и AddressLocal, позволяет внести поправки на особенности нумерации ячеек в локализованной версии Excel (для русских версий Excel в нем нет необходимости).
FormulaHidden возможность спрятать формулы в диапазоне от пользователя. Работает только на защищенных листах.
HasFormula проверить диапазон на наличие вычисляемых значений (формул).
Hidden спрятать диапазон. Будет работать только в случае, если диапазон включает в себя хотя бы одну строку или столбец целиком, в противном случае вернется ошибка.
Interior еще одно свойство, связанное с форматированием. В основном позволяет покрасить ячейки диапазона.
Item позволяет получить еще один объект Range, который определяется путем смещения исходного диапазона.
Locked это свойство позволяет заблокировать ячейки диапазона при защите листа.
Name возможность получить ссылку на специальный объект именованного диапазона Name. На графическом экране с его возможностями можно познакомиться при помощи меню Вставка -> Имя. Он позволяет обращаться к диапазонам и формулам по именам и несколько напоминает по функциональности объект закладки в Word.
Next перейти на следующую ячейку. Если лист не защищен, то следующей ячейкой будет считаться ячейка справа, если защищен то следующая незаблокированная ячейка.
NumberFormat возможность установить один из предопределенных форматов для чисел. Соответствует возможностям вкладки Число в меню Формат -> Ячейки на графическом экране.
Offset это свойство позволяет получить новый объект Range с определенным смещением от исходного. Например, чтобы получить ячейку со смещением на три ячейки вверх от сходной и три ячейки влево, можно использовать код

Worksheets(«Лист1»).Activate

ActiveCell.Offset(rowOffset:=-3, columnOffset:=-3).Activate
свойство Orientation позволяет сориентировать текст в ячейках. Указывается угол наклона в градусах. Например, чтобы расположить текст по диагонали, можно использовать код

oRange.Orientation = -45
PageBreak это свойство обычно используется для программной вставки разрывов страницы. Его применение может выглядеть так:

Worksheets(«Лист1»).Rows(50).PageBreak = xlPageBreakManual
все свойства, которые начинаются на Pivot+, относятся к работе с объектом PivotTable (сводная таблица). Особенности работы с ней будут рассмотрены ниже.
QueryTable это очень важное свойство позволяет получить ссылку на объект QueryTable полученные с внешнего источника данные. Это свойство для объекта Range позволяет получить ссылку на объект QueryTable, которые находится в данном диапазоне. Подробнее про объект QueryTable будет рассказано ниже.
Range это свойство, как уже говорилось выше, позволяет создать новый диапазон на основе уже существующего. Необходимо помнить про особенности нумерации ячеек в этом случае.
Resize возможность изменить текущий диапазон. Например, увеличение его на один столбец вниз и одну строку вправо может выглядеть так:

oRange.Resize(oRange.Rows.Count + 1, oRange.Columns.Count + 1).Select
ShrinkToFit это свойство позволяет автоматически настроить размер текста в диапазоне таким образом, чтобы текст умещался в ширину столбца.
Style это свойство позволяет вернуть объект Style, представляющий стиль для указанного диапазона. На графическом экране то, что позволяет сделать объект Style, можно сделать через меню Формат -> Стиль.
Text возможность получить значение первой ячейки диапазона в виде значения типа String. Для объекта Range это свойство доступно только для чтения.
Validation это свойство позволяет вернуть объект Validation, при помощи которого можно настроить проверку вводимых в диапазон данных.
Value наиболее часто используемое свойство объекта Range. Позволяет получить или назначить значение (числовое, текстовое или какое-либо другое) ячейкам диапазона. Точно для той же цели используется свойство Value2, единственное отличие это свойство не поддерживает типы данных Currency и Date.
WrapText возможность включить/отключить перевод текста на следующую строку в ячейках диапазона.

Теперь о методах объекта Range:
Activate() выделяет текущий диапазон и устанавливает курсор ввода на его первую ячейку.
AddComment() возможность добавить комментарий к ячейке. Ячейка будет помечена красным уголком, а текст комментария будет показан в виде всплывающей подсказки. Этот метод можно вызвать только для диапазона, состоящего из одной ячейки. То же самое на графическом экране можно сделать при помощи меню Вставка -> Примечание.
AutoFill() возможность использовать автозаполнение для диапазона (например, если первые две ячейки будут заполнены как 1 и 2, то дальше в автоматическом режиме будет продолжено: 3, 4, 5 и т.п.)
AutoFit() автоматически поменять ширину всех столбцов и высоту всех строк в диапазоне, чтобы туда уместился текст ячеек. Можно применять только к тем диапазонам, которые состоят из набора столбцов (полностью) или набора ячеек (также полностью), иначе будет ошибка.
AutoFormat() возможности использовать один из стилей автоформатирования (то, что на графическом экране доступно через меню Формат -> Автоформат).
BorderAround() возможность поместить диапазон в рамку с выбранными вами параметрами.
методы Clear+ позволяют очистить содержимое диапазона от значений, форматирования, комментарий и т.п.
Consolidate() возможность слить данные нескольких диапазонов (в том числе на разных листах) в один диапазон, используя при этом выбранную вами агрегатную функцию.
Copy() возможность скопировать диапазон в другое место. Если место назначения не указано, он копируется в буфер обмена. Аналогично работает метод Cut(), при котором данные исходного диапазона вырезаются.
CopyFromRecordset() очень удобный метод, который позволяет вставить данные из объекта ADO Recordset на лист Excel, начиная с верхнего левого угла указанного диапазона.
DataSeries() метод, который может сэкономить множество времени и избежать возни с функциями даты и времени. Этот метод позволяет увеличить вами значения даты в диапазоне на указанный вами временной интервал. Например, если у вас в диапазоне стоит первое января, то при помощи этого метода можно сгенерировать первое число любого другого месяца.
Delete() удаляет данные текущего диапазона. В качестве необязательно параметра можно определить, с какой стороны будут сдвигаться ячейки на место удаленных.
Dirty() пометить ячейки диапазона как «грязные». Такие ячейки будут пересчитаны при следующем же пересчете. Обычно используется, когда Word сам не может догадаться, что их нужно пересчитать. Пересчитать ячейки диапазона можно и принудительно при помощи метода Calculate().
методы Fill+ (FillDown(), FillUp(), FillLeft(), FillRight()) позволяют размножить одно и то же значение по ячейкам диапазона в указанном вами направлении.
метод Find() позволяет произвести поиск по ячейкам диапазона и вернуть новый объект Range, который представляет первую ячейку, в котором было найдено нужное значение. У этого метода есть множество необязательных параметров, которые позволяют определить направление поиска, чувствительность к регистру, искать все значение ячейки или часть и т.п. Методы FindNext() и FindPrevious() позволяют продолжить поиск, начатый методом Find(), в разных направлениях.
метод GoalSeek() позволяет применить автоподбор значений для функции Excel программным способом. На графическом экране то же самое можно сделать при помощи меню Сервис -> Подбор параметра.
метод Insert() позволяет вставить ячейки в диапазон, сдвинув остальные (вы можете выбрать вправо или вниз).
метод Justify() позволяет равномерно распределить текст по диапазону. Если в данный диапазон он не помещается, он будет распространен на соседние ячейки (с перезаписью их значений).
метод Merge() позволяет слить все ячейки диапазона в одну. При этом останется только одно значение верхней левой ячейки. Разбить обратно такую слитую ячейку на несколько обычных можно при помощи метода UnMerge().
Parse() позволяет разбить одну ячейку на несколько по указанному вами шаблону (например, чтобы отделить код города от номера телефона).
PasteSpecial() операция, дополняющая Copy() и Cut(). Она позволяет вставить то, что лежит в буфере обмена, с указанием специальных параметров вставки (вставлять с добавлением к существующим данным, с умножением, вычитанием, делением и т.п.)
PrintOut() и PrintPreview() позволяют вывести диапазон на печать или открыть режим просмотра перед печатью..
Replace() метод, дополняющий метод Find(). Позволяет проводить поиск и замену значений в диапазоне.
Select() возможность выделить указанный диапазон. Объекта Selection в Excel нет вместо него есть возможность получить объект Range, представляющий выделенную область.
Show() экран будет проскроллирован таким образом, чтобы показать указанный диапазон.
ShowDependents() показать стрелки для ячеек, которые зависят от указанного диапазона (только первый уровень зависимости) или эти стрелки убрать. Обратный метод ShowPrecedents().
ShowErrors() показать источник ошибки для указанной ячейки.
Sort() возможность произвести сортировку ячеек в диапазоне. Можно использовать большое количество необязательных параметров для настройки сортировки. SortSpecial() с учетом особенностей азиатских языков.
Speak() удивительный метод, который позволяет зачитывать вслух содержимое диапазона (можно определить, в каком направлении и будут ли зачитываться формулы). К сожалению, в локализованной версии Excel не работает.
SpecialCells() очень удобный метод, который позволяет вернуть объект Range, включающий в себя все ячейки определенного типа (пустые, с ошибками, с комментариями, последние, с константами, с формулами, с определенным форматированием) и с определенным значением. Например, чтобы вернуть объект Range, состоящий из всех пустых ячеек диапазона, можно использовать код

Set oRange2 = oRange.SpecialCells(xlCellTypeBlanks)

oRange 2. Select ‘проверяем, так ли это
метод SubTotal() позволяет посчитать итоговое значение для диапазона (можно выбрать агрегатную функцию и множество других параметров).
метод Table() позволяет создать таблицу на основе передаваемого столбца, строки и функции, которую нужно использовать для вычисления ячеек таблицы. Пример из документации по этому методу позволяет автоматически сгенерировать таблицу умножения.
TextToColumns() сложный метод, который позволяет разбить столбцы в диапазоне на несколько столбцов в соответствии с определенным алгоритмом. Принимает множество необязательных параметров.

Аннотация: Лекция посвящена описанию объектной модели MS Excel, относящейся к ячейкам — объект Range.

15.1. Как обратиться к ячейке

15-01-Excel Обращение к ячейкам.xlsm — пример к п. 15.1.

Мы добрались до ячеек, работа с которыми осуществляется, в основном, через объект типа Range. Выше мы немного работали с ячейками, а теперь рассмотрим их наиболее интересные методы и свойства.

Выше мы уже обращались к ячейкам в некоторых примерах. Здесь мы кратко обобщим и поясним основные способы обращения к ячейкам.

Можно адресовать ячейку или диапазон ячеек, указав их адреса в стиле A1. Здесь и далее мы используем метод Select объекта Range, который выделяет ячейки (листинг 15.1.)

ActiveSheet.Range("A2").Select


Листинг
15.1.
Обращаемся к ячейке по имени в стиле A1

Для обращения к диапазону ячеек нужно знать верхнюю левую и нижнюю правую границы диапазона. Например, для обращения к диапазону высотой в одну строку от A2 до E2 или к диапазону A2:E4 — понадобится такой код (листинг 15.2.)

ActiveSheet.Range("A2:E2").Select
ActiveSheet.Range("A2:E4").Select


Листинг
15.2.
Обращаемся к диапазонам

Можно воспользоваться конструкцией с использованием объекта Cells, который позволяет обращаться к отдельной ячейке по ее индексу в формате R1C1. Чтобы обратиться к ячейке A5 таким способом, нужно заметить, что она расположена в пятой строке и первом столбце (листинг 15.3.):

ActiveSheet.Cells(5,1).Select


Листинг
15.3.
Обращаемся к ячейке по номеру строки и столбца

Можно объединить использование Range и Cells, указав координаты ячеек при адресации диапазона с помощью Cells (листинг 15.4.).

ActiveSheet.Range(Cells(5, 4), _
        Cells(7, 5)).Select


Листинг
15.4.
Обращение к диапазону с использованием комбинации Range и Cells

Нам уже встречалось использование Cells для доступа к группам ячеек в цикле — в качестве индексов ячеек можно использовать переменные (листинг 15.5.)

For i = 1 To 3
        For j = 1 To 3
            ActiveSheet.Cells(i, j).Select
            Application.Wait (Now + _
            TimeValue("0:00:01"))
            p = p + 1
            Selection = p
        Next j
    Next i
ActiveSheet.Range("A1:E5").Clear


Листинг
15.5.
Обращение к ячейкам в цикле

Здесь мы циклически выделяем ячейки диапазона A1:C3, делая задержку на 1 секунду после каждого выделения и выводя количество прошедших с начала работы программы секунд. Здесь мы воспользовались для выделения ячейки уже знакомым вам методом Select, а для ввода данных в выделенную ячейку применили объект Selection, который в данном случае ссылается на выделенную ячейку. В конце мы очистили диапазон A1:E5 от введенных данных.

Объект Selection — это еще один способ работы с ячейками, однако он используется сравнительно редко, так как к ячейкам удобнее обращаться по их именам.

Выше мы использовали прямое обращение к ячейкам активного листа, без использования объектных переменных.)

Dim obj_MyCells As Range
Set obj_MyCells = ActiveSheet.Cells(5, 5)
obj_MyCells.Select


Листинг
15.6.
Объектная переменная и работа с ячейками

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

В листинге 15.7 мы сначала выделяем столбец A, потом столбец B, используя коллекцию Columns (столбцы), 3-ю строку, используя коллекцию Rows (строки) а далее — лист целиком.

ActiveSheet.Range("A:A").Select
    ActiveSheet.Columns("B:B").Select
    ActiveSheet.Range("3:3").Select
    ActiveSheet.Rows("4:4").Select
    ActiveSheet.Cells.Select


Листинг
15.7.
Работа со столбцами, строками и всеми ячейками листа

Еще один способ обращения к ячейкам — применение именованных диапазонов (коллекция Names ) мы рассмотрим ниже. А теперь поговорим о методах и свойствах объекта Range.

15.2. Методы Range

15.2.1. Activate — активация ячейки

15-02-Range Activate.xlsm — пример к п. 15.2.1.

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

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

Range("A1:E5").Select
    Range("C2").Activate


Листинг
15.8.
Активация ячейки в выделенной области

15.2.2. AddComment — добавляем комментарии к ячейкам

Позволяет добавлять комментарии к ячейкам. Если вы формируете какой-нибудь Excel-документ программно, вы можете добавить в некоторые ячейки комментарии для пояснения данных, которые в них хранятся. В листинге 15.9. мы добавляем комментарий к ячейке C3.

Range("C3").AddComment ("Проверка комментария")


Листинг
15.9.
Добавляем комментарий к ячейке

В правом верхнем углу ячейки появится красный треугольник, а наведя мышь на ячейку, можно увидеть текст комментария (рис. 15.1.).

Комментарий в ячейке MS Excel

Рис.
15.1.
Комментарий в ячейке MS Excel

15.2.3. AutoFit — автонастройка ширины столбцов и высоты строк

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

Метод можно применять как к диапазону, так и к отдельным строкам или столбцам.

Например, код в листинге 15.10. позволяет автоматически подобрать ширину столбцов A, B, C, D, E, руководствуясь данными, расположенными в первой строке этих столбцов. Если в других строках столбцов будут более длинные значения — они не будут приняты во внимание.

ActiveSheet.Range("A1:E1").Columns.AutoFit


Листинг
15.10.
Автоматически настраиваем ширину столбцов по ширине данных в указанных ячейках

Мы не случайно обращаемся здесь к свойству Columns объекта Range — иначе метод AutoFit не работает. Если же в подобном вызове не задавать конкретной строки, а выполнить эту команду так (листинг 15.11.), то ширина столбцов A — E будет подстроена таким образом, чтобы наилучшим образом вместить самое длинное из значений, хранящихся в ячейках, принадлежащих столбцам.

ActiveSheet.Range("A:E").Columns.AutoFit


Листинг
15.11.
Автоматически настраиваем ширину столбцов

15.2.4. Clear, ClearComments, ClearContents, ClearFormats — очистка и удаление

Метод Clear позволяет очистить диапазон — он удаляет данные и форматирование из ячеек. Например, в листинге 15.12. мы очищаем от форматирования сначала диапазон A1:E5, а потом — весь лист.

ActiveSheet.Range("A1:E5").Clear
Activesheet.Cells.Select
Selection.Clear


Листинг
15.12.
Очистка от данных и форматирования

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

ClearContents очищает содержимое ячеек, не затрагивая форматирование. Если вы выделите ячейки и нажмете клавишу Del на клавиатуре — вы добъетесь того же эффекта.

ClearFormats очищает лишь форматирование ячеек, не затрагивая содержимого.

15.2.5. Copy, Cut, PasteSpecial — буфер обмена

Выше мы уже рассматривали команды для работы с буфером обмена в MS Excel. Метод Copy копирует содержимое диапазона в буфер обмена, Cut — вырезает, PasteSpecial осуществляет специальную вставку.

Как ни странно, объект Range не поддерживает метод Paste, осуществляющий обычную вставку, однако, этот метод поддерживает объект Worksheet.

15.2.6. Delete — удалить диапазон

Удаляет выделенный диапазон — остальные ячейки сдвигаются, занимая его место.

15.2.7. Merge, UnMerge — объединение ячеек

15-03-Range Merge.xlsm — пример к п. 15.2.7.

Merge позволяет создать одну объединенную ячейку из заданного диапазона.

UnMerge разбивает объединенную ячейку на обычные ячейки.

Объединенные ячейки удобно использовать для хранения в них названий таблиц.

В листинге 15.13. мы программно формируем таблицу шириной в 10 ячеек. Заполняем ее данными, автоматически подстраиваем ширину столбцов под введенные значения. После этого вводим в левую верхнюю ячейку строки, которая расположена над таблицей, название таблицы, и объединяем все ячейки до конца таблицы, расположенные левее строки с названием. В итоге название будет отображено в одной большой строчке, занимающей всю верхнюю часть таблицы (рис. 15.2.).

'Заполняем область C3:L2
    'случайными целыми числами
    For i = 1 To 10
        For j = 1 To 10
            ActiveSheet.Cells(i + 2, j + 2) = _
            Int(Rnd * 100)
        Next j
    Next i
    'Выравниваем размер столбцов
    ActiveSheet.Range("C:L").Columns.AutoFit
    'Записываем название таблицы
    'в ячейку верхней строчки
    Range("C2") = "Название таблицы"
    'Объединяем ячейки над таблицей
    Range("C2:L2").Merge


Листинг
15.13.
Оформление таблиц с использованием объединения ячеек

Название таблицы в объединенной ячейке

Рис.
15.2.
Название таблицы в объединенной ячейке

15.2.8. Select — выделение ячейки

15-04-Range Select.xlsm — пример к п. 7.7.2.8.

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

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

Dim obj_Range As Range
    Dim num_Sum
    'Обращаемся к каждой ячейке
    'в выделенной области
    For Each obj_Range In Selection.Cells
        num_Sum = num_Sum + Val(obj_Range)
    Next
    MsgBox ("Сумма выделенных ячеек: " & _
    num_Sum)


Листинг
15.14.
Поиск суммы чисел в диапазоне, выделенном пользователем

Просмотров: 59

Работа с ячейками и диапазонами в VBA

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

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

Самым маленьким в иерархии объектов является ячейка. Работа с ячейкой начинается с обращения к ней в коде макроса. Обратиться к ячейке можно двумя способами. Если речь идет о ячейке, выбранной в данный момент, то ее указывают как ActiveCell. Активной ячейка становится после щелчка по ней мышью или перемещения, а нее курсором в программе Excel. В VBA для выбора и активации ячейки используют метод Select. Если речь идет о конкретной ячейке, то ее указывают комбинацией Cells(R,C). Здесь R и C представляют соответственно номер строки и номер столбца листа, на пересечении которых располагается указанная ячейка. Данный вариант является практически полным аналогом абсолютной адресации стиля R1C1. Чтобы получить значение ячейки, или ввести значение в ячейку используется метод value. Для примера рассмотрим следующий код

Sub Test_Cell()

Cells(2,4).Select

Cells(1,2).Value=5

ActiveCell.Value=10

End Sub

Что произойдет после запуска данного макроса? Прежде всего стоить заметить, что, так как лист не указан, все операции будут выполнены на открытом листе. Прежде всего программа выберет ячейку D2, так как колонка D является 4 по счету. Затем в ячейку B2 запишется значение 5, а в текущую ячейку D2 – значение 10. Несмотря на свою простоту, код наглядно демонстрирует, что для внесения данных в VBA выделять ячейки не обязательно, достаточно их указать в коде. Это очень важно, так как в итоге можно, находясь на одном листе книги, выбирать данные на остальных листах, не перемещаясь между ними. Такой подход позволяет сократить код программы макроса и ускорить работу. Кроме этого, можно указать ячейки по их расположению относительно указанной ячейки. Для этого используют метод Offset. Перемещение вниз по строкам и вправо по столбцам указывают положительными числами. Перемещение по строкам вверх и по столбцам влево будет отрицательным.

Пример кода

Sub Test_Cell2

Cells(4,3).Select

ActiveCell.Value=1

ActiveCEll.Offset(1,1)=2

ActiveCEll.Offset(2,2)=3

End Sub

Результатом работы макроса будет выбор ячейки С3. Значение данной ячейки станет равным единице. Затем последовательно программа переместится относительно активной ячейки на одну строку вниз и одну колонку влево, а потом на две строки вниз и две колонки влево. Фактически будут выбраны (но не активированы!) ячейки D5 и Е6, куда и запишутся соответственно значения 2 и 3.

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

1. WrapText. Включает или выключает перенос текста в ячейке.

ActiveCell.WrapText=true

2. EntireRow, EntireColumn – соответственно показывают номер строки и номер колонки выбранной ячейки. Эти свойства изменить нельзя, но допустимо использовать для работы. Рассмотрим вариант, в котором необходимо скрыть ячейку. Саму ячейку отдельно скрыть нельзя, поэтому мы скроем целиком строку с выбранной ячейкой

ActiveCell.EntireRow.Hidden=true

3. AutoFit – автоматически настраивает ширину и высоту ячейки по ее содержимому.

ActiveCell.AutoFit

4. Font –указываются настройка шрифта. Задается стиль (bold, Italic, UnderLIne), размер (Size) и другие параметры. К примеру, сделаем шрифт активной ячейки полужирным и зададим размер (кегль) равным 12

ActiveCell.Font.Bold=true

ActiveCell.Font.Size=12

5. Formula – задает в ячейке формулу для вычислений. Более подробно о вычислениях в VBA вы можете узнать на наших занятиях.

a = ActiveCell.Offset(-2, 0).Value

b = ActiveCell.Offset(-1, 0).Value

ActiveCell.Formula = “=” & a & “+” & b

Макрос суммирует значение двух ячеек, находящихся непосредственно над активной. Обратите внимание, что формула записывается как текстовая строка, начинающаяся со знака «=», а части этой строки разделены знаком амперсанда «&» с обязательным пробелом как перед ним, так и после него.

6. Interior – указывает оформление. Часто применяют, чтобы указать цвет заливки. Для указания цвета используют свойство ColorIndex либо Color. В первом случае указывают номер цвета их имеющихся 56 вариантов, во втором задают цвет с помощью комбинирования соотношения красного, зеленого и синего цветов палитрой RGB. Первая цифра в скобках отвечает за уровень красного цвета, вторая соответствует уровню зеленого, третья – синему. Максимальное значение уровня цвета равно 255.

ActiveCell.Interior.ColorIndex = 6

ActiveCell.Offset(1, 0).Interior.Color = RGB(255, 255, 0)

Оба указанных выше варианта зададут желтый цвет заливки.

7. Сору – Копирует содержимое ячейки. Можно сразу указать место назначения скопированных данных. Если это не сделать, выполнится копирование в буфер обмена.

8. Cut – вырезает содержимое ячейки.

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

Перейдем к использованию диапазонов в VBA. Работу с ними ведут с помощью объекта Rangе, указав в скобках нужный адрес. Например, команда

Range(“A2:D6”).value=10

Запишет значение 10 в каждую ячейку диапазона A2:D6. Обратите внимание, что адрес выбранного диапазона находится в кавычках. В качестве диапазона можно указать и одну ячейку, поэтому операторы ниже равносильны и активируют одну и ту же ячейку.

Cells(1,2).Select

Range(“B1”).Select

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

Range(Cells(2,1),Cells(6,4))

Несмежные диапазоны указывают двумя способами. Во-первых, отделяют адреса в объекте Range запятой

Range(“A1,B10”).Value = 180

Кроме этого, для указания несмежного диапазона используют метод Union

Union(Range(“A1”), Range(“B10”)).Value = 180

Оба варианта запишут значение 180 в диапазоны A1 и B10 одновременно, пропустив все ячейки между ними. Метод Union удобнее, если нужно применить цикл. О работе с циклами мы поговорим на следующих занятиях.

Объект Range поддерживает все методы и свойства, доступные для объектов Cells. Кроме этого, у данного объекта есть и другие свойства, и методы, которые либо нельзя использовать для объектов Cells, либо такое использование является бессмысленным.

1. Row – номер строки первой ячейки выбранного диапазона.

2. Column – номер столбца первой ячейки выбранного диапазона

3. Rows.Count и Columns.Count – количество строк и столбцов соответственно указанном диапазоне.

4. Sort – сортировка диапазона

5. AutoFilter – – аналог команды Excel «Данные» → «Фильтр» → «Автофильтр». Настройка фильтрации задается указанными для данного метода параметрами.

6. Clear, ClearComments, ClearContents, ClearFormats – выполняют очистку всего диапазона, комментариев, содержимого и формата диапазона соответственно.

7. Delete – удаляет диапазон. Необходимо указать смещение ячеек после удаления диапазона с помощью свойства Shift. Смещение влево задается как Shift=XlToLeft, для смещения вверх применяют вариант Shift:=XlUp

Стоит отметить тонкость обращения к активному диапазону в среде VBA. При работе с диапазонами для указания активного диапазона команды ActiveRange не существует. Аналогом объекта ActiveCell, указывающего на активную ячейку, для диапазонов является объект Selection. Он содержит все выделенные ячейки на листе. Доступ к данному объекту и работа с ним выполняется теми же методами и свойствами, что и при работе с объектом Range. Объект Selection позволяет более гибко обработать нужный диапазон, так как отсутствует привязка к конкретному адресу. Это очень удобно, так как расположение фактических данных обычно не совпадает с адресом указанного в макросе диапазона.

Кроме объекта Selection, содержащего выделенный диапазон, существую еще два варианта для выбора диапазона на рабочем листе. Это объекты CurrentRegion и UsedRange.

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

Объект UsedRange содержит диапазон, в котором происходит работа пользователя. Этот диапазон содержит все ячейки листа, в которых обрабатывалось содержимое, в том числе форматы. При удалении ячеек с данными на листе они продолжают использоваться в Used Range. Чтобы их убрать, необходимо перейти в заполненную ячейку и сохранить файл. Кроме этого можно применить такой код

With ActiveSheet.UsedRange: End With

Обратите внимание, что для использования объекта CurrentRegion надо указать ячейку, относительно которой вычисляется адрес данного объекта. При использовании UsedRange требуется указать лист, на котором идет работа. Аналогично обращению к текущей ячейке текущий лист задают как ActiveSheet. Более подробно работу с листами рассмотрим в следующих занятиях.

Текущий же наш урок подошел к концу. Желаем всем хорошего дня и удачи в работе.

 

Johny

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

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

#1

17.12.2013 10:16:31

Наша повседневная работа написания кода так или иначе связана с обращением к ячейкам.
Хотелось бы написать про методы обращения к ячейкам. Если что-то пропустил — не ругайте.  :D  
Итак, поехали…  :)

Код
Sub CellsSelection()
    
    Dim cell As Range
    Dim severalCells As Range
    Dim rng As Range

    '=======================================
    'Выделяем ячейку F6
    '=======================================
    Set cell = Range("F6")
    Set cell = Cells(6, 6) 
    Set cell = Cells(6, "F")
    Set cell = Cells(81926) ' (16384 * 5) + 6
    Set cell = Cells.Item(6, 6)
    Set cell = Cells.Cells(6, 6)

    '=======================================
    '1. Выделяем диапазон D4:G10
    '=======================================
    Set rng = Range("D4:G10")
    Set rng = Range(Cells(4, "D"), Cells(10, "G"))
    Set rng = Range(Cells(4, 4), Cells(10, 7))
    Set rng = Range("D4", Cells(10, 7))
    Set rng = Range("D4", "G10")
    Set rng = Range(Range("D4"), "G10")
    Set rng = Range("D4").Resize(7, 4)
    'Обращаемся к диапазону без привязки к объекту Worksheet
    Set rng = Range("Лист1!D4:G10")
    
    
    'Во всех нижеприведённых методах необходимо
    'представить диапазон D4:G10 как лист
    'с верхней левой ячейкой A1, то есть мысленно
    'переносим D4:G10 в A1. :)
    
    '========================================
    '2. Выделяем ячейку F6 в диапазоне D4:G10
    '========================================
    Set cell = rng.Range("C3")
    Set cell = rng(3, 3)
    Set cell = rng(11)
    Set cell = rng.Item(3, 3)
    Set cell = rng.Item(11)
    Set cell = rng.Cells(11)
    Set cell = rng.Cells(3, 3)
    
    '===========================================
    '3. Выделяем ячейку E11 ВНЕ диапазона D4:G10
    '===========================================
    Set cell = rng(30)
    Set cell = rng.Item(30)
    Set cell = rng.Cells(30)
    Set cell = rng.Range("B8")
    Set cell = rng.Cells(8, 2)
    Set cell = rng(8, 2)
    Set cell = rng.Item(8, 2)
    Set cell = rng.Cells(8, 2)
    
    '=============================================
    '4. Выделяем диапазон E8:F9 в диапазоне D4:G10
    '=============================================
    Set severalCells = rng.Range("B5:C6")
    Set severalCells = rng.Range("B5", "C6")
    'В общем, принцип такой же, что и в пункте 2. :)
    
End Sub

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

  • Cells Selection.xlsm (16.88 КБ)

There is no knowledge that is not power

 

SkyPro

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

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

#2

17.12.2013 18:55:09

Я бы еще добавил:

Цитата
сышышь, ячейка, ходьсуда!
Код
[A1]

Изменено: SkyPro17.12.2013 18:57:00

SkyPro

 

ZVI

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

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

#3

17.12.2013 21:12:19

VBA-справку – на

мыло

примеры?

1. Помимо Cells можно еще вспомнить про Rows и Columns и Areas:

Цитата
Johny: Наша повседневная работа написания кода…  

Не наша и не повседневная работа:

Скрытый текст

По понедельникам:

Скрытый текст

Для пятниц:

Скрытый текст

2. Так как Range бывает разным: Cells, Columns, Rows, Areas
то и For — Each работает иначе

Скрытый текст

3. Можно вспомнить и про Offset, CurrentRegion, SpecialsCells, UsedRange и проч.
Но VBA-справка все же покороче будет     :)

Изменено: ZVI17.12.2013 21:19:03

 

Johny

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

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

#4

18.12.2013 08:22:39

@ZVI
Владимир, «For Each cell In rng» — это понятно. Просто хотел показать, что есть некоторые способы, которые могли бы облегчить обработку ячеек, так как некоторые способы плохо документированы или вообще недокументированы на MSDN.   :)  
Кстати, по поводу Rows. Есть очень интересный момент. Например, возьмём диапазон A1   :D  4. Пройдёмся по Rows и возьмём первую ячейку каждой строки через Item:

Код
Sub EnumerateRows()

    Dim rngRow As Range
    
    For Each rngRow In Range("A1:D4").Rows
        Debug.Print rngRow(1)
    Next

End Sub

Работать не будет.   :(  А вот так будет:

Код
Debug.Print rngRow.Cells(1) 
Debug.Print rngRow.Cells(1, 1) 
Debug.Print rngRow.Range("A1")

Почему не работает Item — не знаю.   :)  

Цитата
Но VBA-справка все же покороче будет   :)

И что — все эти способы есть в справке? А можно посмотреть на эту справку? :)

Изменено: Johny18.12.2013 08:27:05

There is no knowledge that is not power

 

ikki

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

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

раздел How to Reference Cells and Ranges
в 2003-м

фрилансер Excel, VBA — контакты в профиле
«Совершенствоваться не обязательно. Выживание — дело добровольное.» Э.Деминг

 

Johny

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

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

@Саша
Про 2003-ий офис я забыл в 2007, поэтому его нема. :)
А можно скинуть этот хелп? И там прямо все-все способы прописаны? :)

There is no knowledge that is not power

 

ikki

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

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

фрилансер Excel, VBA — контакты в профиле
«Совершенствоваться не обязательно. Выживание — дело добровольное.» Э.Деминг

 

Ivan.kh

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

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

ikki, не могу ни одну из ваших ссылок открыть

 

ikki

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

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

сорри.
это внутренние ссылки.
из автономной справки vba.
копипаст виноват.

фрилансер Excel, VBA — контакты в профиле
«Совершенствоваться не обязательно. Выживание — дело добровольное.» Э.Деминг

 

anvg

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

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

Excel 2016, 365

#10

19.12.2013 05:19:28

Цитата
ikki, не могу ни одну из ваших ссылок открыть

Уважаемый, а в чём проблема?  

Первая же ссылка в поисковике ведёт на такой же список тем.

 

ZVI

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

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

#11

19.12.2013 05:52:59

@Johny
Евгений, идея собрать варианты в одном месте хорошо, тема полезная, кому-то может очень даже пригодиться.
А по поводу Rows, так там все работает штатно, просто Item у Rows это тоже Rows

Код
Sub EnumerateRows()
    Dim rngRow As Range
    For Each rngRow In Range("A1:D4").Rows
        Debug.Print rngRow.Item(1).Address
    Next
End Sub 

При Set rng =  Range( «адрес» )  Excel подразумевает по умолчанию Set rng =   Range( «адрес» ).Cells , тогда и rng.Item(i) является rng.Cells( i )
Но если явно прописано .Rows то и его .Item(i) будет с той же «фамилией» .Rows( i )

Изменено: ZVI19.12.2013 05:56:38

 

Ivan.kh

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

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

#12

19.12.2013 11:30:31

Цитата
Уважаемый, а в чём проблема?

Уважаемый, да ни в чём, просто сказал, что ссылки не работают, вот и все. ;)

 

Johny

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

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

#13

19.12.2013 11:37:44

Цитата
ZVI: Но если явно прописано .Rows то и его .Item(i) будет с той же «фамилией» .Rows( i )

@Владимир, нет такого объекта «Row», а есть Range.  :)  
В одной авторитетной книге написано:

Цитата
Curiously, you can not replace rngRow.Cells(1) with rngRow(1), as you can with a normal Range
object, because it returns a reference to the entire row and causes a run-time error. It seems that there is
something special about the Range object referred to by the Rows and Columns properties. You may find
it helps to think of them as Row and Column objects, even though such objects do not officially exist.

Как видно, авторы предлагают думать, что .Rows/Columns возвращают некий объект Row/Column (которого на самом деле нет). А вот что «something special» в нём, неизвестно.  :)

Изменено: Johny19.12.2013 11:38:20

There is no knowledge that is not power

 

ZVI

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

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

#14

20.12.2013 04:57:26

Цитата
Johny: @Владимир, нет такого объекта «Row», а есть Range.   :)  

Евгений, Вы обсуждаете фразу, которую я не приводил, почему тогда не есть ли жизнь на Марсе?   :)

Cells и Rows — это свойства (properties) объекта.
В зависимости от примененного свойства может поменяться интерфейс объекта  (см. For-Each в п.2, сообщение #3 ) и его другие свойства, например, значение Item (уже пояснял в #11) или значение Count (объекта Range):

Код
Sub Test1()
  Dim Rng1 As Range, Rng2 As Range
  Set Rng1 = Range("A1:D4").Cells
  Set Rng2 = Range("A1:D4").Rows
  Debug.Print "Item(1)", Rng1(1).Address, Rng2(1).Address
  Debug.Print "Count", Rng1.Count, Rng2.Count
End Sub

Это все учтено во внутренней реализации класса для объекта Range и отражается во внешнем VBA-интерфейсе.

Изменено: ZVI20.12.2013 05:10:56

 

Johny

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

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

#15

20.12.2013 08:53:56

Цитата
В зависимости от примененного свойства может поменяться интерфейс объекта

Владимир, если я пишу «Dim cell As Range», то я использую интерфейс Range, а не какой-либо другой, поэтому не важно, какое свойство я вызываю — Cells или Rows — я продолжаю «общаться» с интерфейсом Range. Поэтому это утверждение неправильное.   :|  
Вот что приблизительно происходит внутри на примере C#:

Код
    interface IRange
    {
        string Address { get; set; }
        string Formula { get; set; }
        IRange Cells { get; set; }
    }

    public class Range : IRange { }
    public class Rows : IRange { }
    public class Cells : IRange { } 
     
    public void TestRange()
    {
        IRange var1 = new Range();
        IRange var2 = new Rows();
        IRange var3 = new Cells();

        Console.WriteLine(var1.Address);
        Console.WriteLine(var2.Address);
        Console.WriteLine(var3.Address);
    } 

Как видно, мы общаемся с разными классами через ОДИН интерфейс. :)

There is no knowledge that is not power

 

ZVI

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

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

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

 

Johny

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

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

Тогда получается, что в Rows свойство Item переопределено? :)

There is no knowledge that is not power

 

ZVI

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

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

Евгений Вы не отвечаете на мои вопросы ;)

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

Ответ на Ваш вопрос — из примера кода в сообщении #11 видно, что свойства Item и Count реализованы по разному, разве Вы не видите отличий в выводимых сообщениях?

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

 

Johny

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

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

Владимир, моё сообщение #17 это подразумевало. :) Я всё понял — поэтому так кратко и написал. :)
Просто совсем забыл с этим C#’ом, что в VBA мы имеем дело с интерфейсами, а не с объектами. :)

There is no knowledge that is not power

 

ZVI

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

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

Ну да, C# однозначно честнее в этом плане.

По поводу формул, в VBA справке есть раздел Range Collection.
Там вскользь упомянуто, что (подчеркнуто мною)

Range Collection represents a cell, a row, a column, a selection of cells containing one or more contiguous blocks of cells, or a 3-D range.

Using the Range Collection
The following properties and methods for returning a Range object are described in this section:

  • Range property
  • Cells property
  • Range and Cells
  • Offset property
  • Union method

и есть некоторые примеры использования формул.
Но в Вашей коллекции примеров побольше, да и полезно в одном месте собрать их.

 

Johny

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

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

#21

20.12.2013 11:24:50

Цитата
3. Можно вспомнить и про Offset, CurrentRegion, SpecialsCells, UsedRange и проч.

Offset, CurrentRegion — c этим всё понятно.
SpecialCells интересен в плане быстрого удаления отфильтрованных данных. Напишу про это.
Часто многим требуется удалить из таблицы какие-то строки, в одном из столбцов которых находятся нужные значения.
Кто-то делает циклом, кто-то через Find. Согласен, что им есть место, но в случае больших таблиц всё-таки быстрее метод с автофильтром.
Как он работает.
Возьмём, к примеру, диапазон A1: G5000. Итак, я знаю строку, с которой начинается таблица (исключая заголовок, где, собственно, и стоит фильтр). Далее, определяю последнюю строку (получаю 5000) и храню в переменной. После этого фильтрую данные. А далее использую SpecialCells и Delete:

Код
Sub QuickRemove()

    Dim lastRow As Long, rng As Range, rngVisible As Range

    Call ResetAutoFilter(ActiveSheet)

    'Последняя строка
    lastRow = Cells(Rows.Count, 1).End(xlUp).Row
    
    'Фильтруем
    Range("A1:G1").AutoFilter Field:=3, Criteria1:=555
    
    'On Error Resume Next обязательно, так как в случае если ничего не отфильтруется,
    'то возникает ошибка, а так - мы её подавляем.
    On Error Resume Next
    'Видимые ячейки - это то, что мы отфильтровали - значит, то, что нам надо.
    'Диапазон начинается со второй строки, так как первая строка - это заголовок таблицы.
    Set rngVisible = Range("A2:G" & lastRow).SpecialCells(xlCellTypeVisible)
    'Если Err = 0, то что-то отфильтровалось.
    'Можно ещё проверить так: If Not rngVisible Is Nothing Then ...
    If Err = 0 Then
        rngVisible.Delete 3 'Удаляем все строки - миссия выполнена. :)
    Else
        MsgBox Err.Description
        Err.Clear
    End If

End Sub 

Такого же эффекта можно добиться ещё меньшим количество строк (да и код более элегантный получается  :)  ). Идея — в комментарии.

Код
Sub AnotherQuickRemove()

    Dim rngVisible As Range

    Call ResetAutoFilter(ActiveSheet)
    
    'Фильтруем
    Range("A1:G1").AutoFilter Field:=3, Criteria1:=12

    On Error Resume Next
    
    'Объёкт AutoFilter имеет свойство Range, который даёт нам диапазон,
    'находящийся "в ведомости" фильтра. :)
    'Но есть один нюанс - диапазон также содержит заголовок, который нам не нужен.
    'Данные  манипуляции избавляются от заголовка.
    With ActiveSheet.AutoFilter.Range
        Set rngVisible = .Offset(1).Resize(.Rows.Count - 1).SpecialCells(xlCellTypeVisible)
    End With
    
    If Not rngVisible Is Nothing Then
        rngVisible.Delete 3
    Else
        MsgBox Err.Description
        Err.Clear
    End If

End Sub

В процедуре используется вспомогательная процедура «ResetAutoFilter», которая сбрасывает каждый фильтр и не удаляет сам фильтр с листа (может, кому пригодится  :)  ):

Код
Sub ResetAutoFilter(sheet As Worksheet)
    Dim fs As Filters, rng As Range, i As Integer
    With sheet
        If .AutoFilterMode Then
            With .AutoFilter
                Set fs = .Filters
                Set rng = .Range
            End With
            For i = 1 To fs.Count
                If fs(i).On Then rng.AutoFilter i
            Next
        End If
    End With
End Sub

UsedRange удобно использовать для удаления «невидимого» форматирования, которое влияет на размер полос прокрутки (когда полоса прокрутки «говорит», что на листе много строк/столбцов, в то время как их очень мало).

Изменено: Johny20.12.2013 11:28:49
(Орфографическая ошибка :) )

There is no knowledge that is not power

Понравилась статья? Поделить с друзьями:

А вот еще интересные статьи:

  • Как обратится к другой книге в excel
  • Как оборвать все связи в excel
  • Как обрамить ячейки в excel
  • Как обойти пароль на word
  • Как обрамить текст в word

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии