Vba excel функция ячейка

Создание пользовательской функции в VBA Excel, ее синтаксис и компоненты. Описание пользовательской функции и ее аргументов. Метод Application.MacroOptions.

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

Объявление пользовательской функции

Синтаксис функции

[Static] Function Имя ([СписокАргументов])[As ТипДанных]

[Операторы]

[Имя = выражение]

[Exit Function]

[Операторы]

[Имя = выражение]

End Function

Компоненты функции

  • Static — необязательное ключевое слово, указывающее на то, что значения переменных, объявленных в функции, сохраняются между ее вызовами.
  • Имя — обязательный компонент, имя пользовательской функции.
  • СписокАргументов — необязательный компонент, одна или более переменных, представляющих аргументы, которые передаются в функцию. Аргументы заключаются в скобки и разделяются между собой запятыми.
  • Операторы — необязательный компонент, блок операторов (инструкций).
  • Имя = выражение — необязательный* компонент, присвоение имени функции значения выражения или переменной. Обычно, значение присваивается функции непосредственно перед выходом из нее.
  • Exit Function — необязательный компонент, принудительный выход из функции, если ей уже присвоено окончательное значение.

*Один из компонентов Имя = выражение следует считать обязательным, так как если не присвоить функции значения, смысл ее использования теряется.

Видимость функции

Видимость пользовательской функции определяется необязательными ключевыми словами Public и Private, которые могут быть указаны перед оператором Function (или Static, в случае его использования).

Ключевое слово Public указывает на то, что функция будет доступна для вызова из других процедур во всех модулях открытых книг Excel. Функция, объявленная как Public, отображается в диалоговом окне Мастера функций.

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

Если ключевое слово Public или Private не указано, функция считается по умолчанию объявленной, как Public.

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

Пример пользовательской функции

Для примера мы рассмотрим простейшую пользовательскую функцию, которой в следующем параграфе добавим описание. Называется функция «Деление», объявлена с типом данных Variant, так как ее возвращаемое значение может быть и числом, и текстом. Аргументы функции — Делимое и Делитель — тоже объявлены как Variant, так как в ячейках Excel могут быть числовые значения разных типов, и функция IsNumeric тоже проверяет разные типы данных и требует, чтобы ее аргументы были объявлены как Variant.

Function Деление(Делимое As Variant, Делитель As Variant) As Variant

  If IsNumeric(Делимое) = False Or IsNumeric(Делитель) = False Then

    Деление = «Ошибка: Делимое и Делитель должны быть числами!»

Exit Function

  ElseIf Делитель = 0 Then

    Деление = «Ошибка: деление на ноль!»

Exit Function

  Else

    Деление = Делимое / Делитель

  End If

End Function

Эта функция выполняет деление значений двух ячеек рабочего листа Excel. Перед делением проверяются два блока условий:

  • Если делимое или делитель не являются числом, функция возвращает значение: «Ошибка: Делимое и Делитель должны быть числами!», и производится принудительный выход из функции оператором Exit Function.
  • Если делитель равен нулю, функция возвращает значение: «Ошибка: деление на ноль!», и производится принудительный выход из функции оператором Exit Function.

Если проверяемые условия не выполняются (возвращают значение False) производится деление чисел и функция возвращает частное (результат деления).

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

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

Добавление описания функции

В списке функций, выводимом Мастером, невозможно добавить или отредактировать их описание. Список макросов позволяет добавлять процедурам описание, но в нем нет функций. Проблема решается следующим образом:

  • Запустите Мастер функций, посмотрите, как отображается имя нужной функции и закройте его.
  • Откройте список макросов и в поле «Имя макроса» впишите имя пользовательской функции.
  • Нажмите кнопку «Параметры» и в открывшемся окне добавьте или отредактируйте описание.
  • Нажмите кнопку «OK», затем в окне списка макросов — «Отмена». Описание готово!

Добавление описания на примере функции «Деление»:

Добавление описания пользовательской функции в окне «Параметры макроса»

Добавление описания пользовательской функции

Описание функции «Деление» в диалоговом окне Мастера функций «Аргументы функции»:

Описание пользовательской функции в диалоговом окне «Аргументы функции»

Описание пользовательской функции в окне «Аргументы функции»

С помощью окна «Список макросов» можно добавить описание самой функции, а ее аргументам нельзя. Но это можно сделать, используя метод Application.MacroOptions.

Метод Application.MacroOptions

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

Пример кода с методом Application.MacroOptions:

Sub ИмяПодпрограммы()

  Application.MacroOptions _

    Macro:=«ИмяФункции», _

    Description:=«Описание функции», _

    Category:=«Название категории», _

    ArgumentDescriptions:=Array(«Описание 1», «Описание 2», «Описание 3», ...)

End Sub

  • ИмяПодпрограммы — любое уникальное имя, подходящее для наименования процедур.
  • ИмяФункции — имя функции, параметры которой добавляются или изменяются.
  • Описание функции — описание функции, которое добавляется или изменяется.
  • Название категории — название категории в которую будет помещена функция. Если параметр Category отсутствует, пользовательская функция будет записана в раздел по умолчанию — «Определенные пользователем». Если указанное Название категории соответствует одному из названий стандартного списка, функция будет записана в него. Если такого Названия категории нет в списке, будет создан новый раздел с этим названием и функция будет помещена в него.
  • «Описание 1», «Описание 2», «Описание 3», … — описания аргументов в том порядке, как они расположены в объявлении пользовательской функции.

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

Сейчас с помощью метода Application.MacroOptions попробуем изменить описание пользовательской функции «Деление» и добавить описания аргументов.

Sub ИзменениеОписания()

  Application.MacroOptions _

    Macro:=«Деление», _

    Description:=«Описание функции Деление изменено методом Application.MacroOptions», _

    ArgumentDescriptions:=Array(«- любое числовое значение», «- числовое значение, кроме нуля»)

End Sub

После однократного запуска этой подпрограммы получаем следующий результат:

Новое описание пользовательской функции и ее второго аргумента

Новое описание пользовательской функции и ее второго аргумента

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

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

“It is a capital mistake to theorize before one has data”- Sir Arthur Conan Doyle

This post covers everything you need to know about using Cells and Ranges in VBA. You can read it from start to finish as it is laid out in a logical order. If you prefer you can use the table of contents below to go to a section of your choice.

Topics covered include Offset property, reading values between cells, reading values to arrays and formatting cells.

A Quick Guide to Ranges and Cells

Function Takes Returns Example Gives

Range

cell address multiple cells .Range(«A1:A4») $A$1:$A$4
Cells row, column one cell .Cells(1,5) $E$1
Offset row, column multiple cells Range(«A1:A2»)
.Offset(1,2)
$C$2:$C$3
Rows row(s) one or more rows .Rows(4)
.Rows(«2:4»)
$4:$4
$2:$4
Columns column(s) one or more columns .Columns(4)
.Columns(«B:D»)
$D:$D
$B:$D

Download the Code

 

The Webinar

If you are a member of the VBA Vault, then click on the image below to access the webinar and the associated source code.

(Note: Website members have access to the full webinar archive.)

vba ranges video

Introduction

This is the third post dealing with the three main elements of VBA. These three elements are the Workbooks, Worksheets and Ranges/Cells. Cells are by far the most important part of Excel. Almost everything you do in Excel starts and ends with Cells.

 
Generally speaking, you do three main things with Cells

  1. Read from a cell.
  2. Write to a cell.
  3. Change the format of a cell.

 
Excel has a number of methods for accessing cells such as Range, Cells and Offset.These can cause confusion as they do similar things and can lead to confusion

In this post I will tackle each one, explain why you need it and when you should use it.

 
Let’s start with the simplest method of accessing cells – using the Range property of the worksheet.

Important Notes

I have recently updated this article so that is uses Value2.

You may be wondering what is the difference between Value, Value2 and the default:

' Value2
Range("A1").Value2 = 56

' Value
Range("A1").Value = 56

' Default uses value
Range("A1") = 56

 
Using Value may truncate number if the cell is formatted as currency. If you don’t use any property then the default is Value.

It is better to use Value2 as it will always return the actual cell value(see this article from Charle Williams.)

The Range Property

The worksheet has a Range property which you can use to access cells in VBA. The Range property takes the same argument that most Excel Worksheet functions take e.g. “A1”, “A3:C6” etc.

The following example shows you how to place a value in a cell using the Range property.

' https://excelmacromastery.com/
Public Sub WriteToCell()

    ' Write number to cell A1 in sheet1 of this workbook
    ThisWorkbook.Worksheets("Sheet1").Range("A1").Value2 = 67

    ' Write text to cell A2 in sheet1 of this workbook
    ThisWorkbook.Worksheets("Sheet1").Range("A2").Value2 = "John Smith"

    ' Write date to cell A3 in sheet1 of this workbook
    ThisWorkbook.Worksheets("Sheet1").Range("A3").Value2 = #11/21/2017#

End Sub

 
As you can see Range is a member of the worksheet which in turn is a member of the Workbook. This follows the same hierarchy as in Excel so should be easy to understand. To do something with Range you must first specify the workbook and worksheet it belongs to.

For the rest of this post I will use the code name to reference the worksheet.

code name worksheet

 
 
The following code shows the above example using the code name of the worksheet i.e. Sheet1 instead of ThisWorkbook.Worksheets(“Sheet1”).

' https://excelmacromastery.com/
Public Sub UsingCodeName()

    ' Write number to cell A1 in sheet1 of this workbook
    Sheet1.Range("A1").Value2 = 67

    ' Write text to cell A2 in sheet1 of this workbook
    Sheet1.Range("A2").Value2 = "John Smith"

    ' Write date to cell A3 in sheet1 of this workbook
    Sheet1.Range("A3").Value2 = #11/21/2017#

End Sub

You can also write to multiple cells using the Range property

' https://excelmacromastery.com/
Public Sub WriteToMulti()

    ' Write number to a range of cells
    Sheet1.Range("A1:A10").Value2 = 67

    ' Write text to multiple ranges of cells
    Sheet1.Range("B2:B5,B7:B9").Value2 = "John Smith"

End Sub

 
You can download working examples of all the code from this post from the top of this article.
 

The Cells Property of the Worksheet

The worksheet object has another property called Cells which is very similar to range. There are two differences

  1. Cells returns a range of one cell only.
  2. Cells takes row and column as arguments.

 
The example below shows you how to write values to cells using both the Range and Cells property

' https://excelmacromastery.com/
Public Sub UsingCells()

    ' Write to A1
    Sheet1.Range("A1").Value2 = 10
    Sheet1.Cells(1, 1).Value2  = 10

    ' Write to A10
    Sheet1.Range("A10").Value2 = 10
    Sheet1.Cells(10, 1).Value2  = 10

    ' Write to E1
    Sheet1.Range("E1").Value2 = 10
    Sheet1.Cells(1, 5).Value2  = 10

End Sub

 
You may be wondering when you should use Cells and when you should use Range. Using Range is useful for accessing the same cells each time the Macro runs.

For example, if you were using a Macro to calculate a total and write it to cell A10 every time then Range would be suitable for this task.

Using the Cells property is useful if you are accessing a cell based on a number that may vary. It is easier to explain this with an example.

 
In the following code, we ask the user to specify the column number. Using Cells gives us the flexibility to use a variable number for the column.

' https://excelmacromastery.com/
Public Sub WriteToColumn()

    Dim UserCol As Integer
    
    ' Get the column number from the user
    UserCol = Application.InputBox(" Please enter the column...", Type:=1)
    
    ' Write text to user selected column
    Sheet1.Cells(1, UserCol).Value2 = "John Smith"

End Sub

 
In the above example, we are using a number for the column rather than a letter.

To use Range here would require us to convert these values to the letter/number  cell reference e.g. “C1”. Using the Cells property allows us to provide a row and a column number to access a cell.

Sometimes you may want to return more than one cell using row and column numbers. The next section shows you how to do this.

Using Cells and Range together

As you have seen you can only access one cell using the Cells property. If you want to return a range of cells then you can use Cells with Ranges as follows

' https://excelmacromastery.com/
Public Sub UsingCellsWithRange()

    With Sheet1
        ' Write 5 to Range A1:A10 using Cells property
        .Range(.Cells(1, 1), .Cells(10, 1)).Value2 = 5

        ' Format Range B1:Z1 to be bold
        .Range(.Cells(1, 2), .Cells(1, 26)).Font.Bold = True

    End With

End Sub

 
As you can see, you provide the start and end cell of the Range. Sometimes it can be tricky to see which range you are dealing with when the value are all numbers. Range has a property called Address which displays the letter/ number cell reference of any range. This can come in very handy when you are debugging or writing code for the first time.

 
In the following example we print out the address of the ranges we are using:

' https://excelmacromastery.com/
Public Sub ShowRangeAddress()

    ' Note: Using underscore allows you to split up lines of code
    With Sheet1

        ' Write 5 to Range A1:A10 using Cells property
        .Range(.Cells(1, 1), .Cells(10, 1)).Value2 = 5
        Debug.Print "First address is : " _
            + .Range(.Cells(1, 1), .Cells(10, 1)).Address

        ' Format Range B1:Z1 to be bold
        .Range(.Cells(1, 2), .Cells(1, 26)).Font.Bold = True
        Debug.Print "Second address is : " _
            + .Range(.Cells(1, 2), .Cells(1, 26)).Address

    End With

End Sub

 
In the example I used Debug.Print to print to the Immediate Window. To view this window select View->Immediate Window(or Ctrl G)

 
ImmediateWindow

 
ImmediateSampeText

 
You can download all the code for this post from the top of this article.
 

The Offset Property of Range

Range has a property called Offset. The term Offset refers to a count from the original position. It is used a lot in certain areas of programming. With the Offset property you can get a Range of cells the same size and a certain distance from the current range. The reason this is useful is that sometimes you may want to select a Range based on a certain condition. For example in the screenshot below there is a column for each day of the week. Given the day number(i.e. Monday=1, Tuesday=2 etc.) we need to write the value to the correct column.

 
VBA Offset

 
We will first attempt to do this without using Offset.

' https://excelmacromastery.com/
' This sub tests with different values
Public Sub TestSelect()

    ' Monday
    SetValueSelect 1, 111.21
    ' Wednesday
    SetValueSelect 3, 456.99
    ' Friday
    SetValueSelect 5, 432.25
    ' Sunday
    SetValueSelect 7, 710.17

End Sub

' Writes the value to a column based on the day
Public Sub SetValueSelect(lDay As Long, lValue As Currency)

    Select Case lDay
        Case 1: Sheet1.Range("H3").Value2 = lValue
        Case 2: Sheet1.Range("I3").Value2 = lValue
        Case 3: Sheet1.Range("J3").Value2 = lValue
        Case 4: Sheet1.Range("K3").Value2 = lValue
        Case 5: Sheet1.Range("L3").Value2 = lValue
        Case 6: Sheet1.Range("M3").Value2 = lValue
        Case 7: Sheet1.Range("N3").Value2 = lValue
    End Select

End Sub

 
As you can see in the example, we need to add a line for each possible option. This is not an ideal situation. Using the Offset Property provides a much cleaner solution

' https://excelmacromastery.com/
' This sub tests with different values
Public Sub TestOffset()

    DayOffSet 1, 111.01
    DayOffSet 3, 456.99
    DayOffSet 5, 432.25
    DayOffSet 7, 710.17

End Sub

Public Sub DayOffSet(lDay As Long, lValue As Currency)

    ' We use the day value with offset specify the correct column
    Sheet1.Range("G3").Offset(, lDay).Value2 = lValue

End Sub

 
As you can see this solution is much better. If the number of days in increased then we do not need to add any more code. For Offset to be useful there needs to be some kind of relationship between the positions of the cells. If the Day columns in the above example were random then we could not use Offset. We would have to use the first solution.

 
One thing to keep in mind is that Offset retains the size of the range. So .Range(“A1:A3”).Offset(1,1) returns the range B2:B4. Below are some more examples of using Offset

' https://excelmacromastery.com/
Public Sub UsingOffset()

    ' Write to B2 - no offset
    Sheet1.Range("B2").Offset().Value2 = "Cell B2"

    ' Write to C2 - 1 column to the right
    Sheet1.Range("B2").Offset(, 1).Value2 = "Cell C2"

    ' Write to B3 - 1 row down
    Sheet1.Range("B2").Offset(1).Value2 = "Cell B3"

    ' Write to C3 - 1 column right and 1 row down
    Sheet1.Range("B2").Offset(1, 1).Value2 = "Cell C3"

    ' Write to A1 - 1 column left and 1 row up
    Sheet1.Range("B2").Offset(-1, -1).Value2 = "Cell A1"

    ' Write to range E3:G13 - 1 column right and 1 row down
    Sheet1.Range("D2:F12").Offset(1, 1).Value2 = "Cells E3:G13"

End Sub

Using the Range CurrentRegion

CurrentRegion returns a range of all the adjacent cells to the given range.

In the screenshot below you can see the two current regions. I have added borders to make the current regions clear.

VBA CurrentRegion

A row or column of blank cells signifies the end of a current region.

You can manually check the CurrentRegion in Excel by selecting a range and pressing Ctrl + Shift + *.

If we take any range of cells within the border and apply CurrentRegion, we will get back the range of cells in the entire area.

For example
Range(“B3”).CurrentRegion will return the range B3:D14
Range(“D14”).CurrentRegion will return the range B3:D14
Range(“C8:C9”).CurrentRegion will return the range B3:D14
and so on

How to Use

We get the CurrentRegion as follows

' Current region will return B3:D14 from above example
Dim rg As Range
Set rg = Sheet1.Range("B3").CurrentRegion

Read Data Rows Only

Read through the range from the second row i.e.skipping the header row

' Current region will return B3:D14 from above example
Dim rg As Range
Set rg = Sheet1.Range("B3").CurrentRegion

' Start at row 2 - row after header
Dim i As Long
For i = 2 To rg.Rows.Count
    ' current row, column 1 of range
    Debug.Print rg.Cells(i, 1).Value2
Next i

Remove Header

Remove header row(i.e. first row) from the range. For example if range is A1:D4 this will return A2:D4

' Current region will return B3:D14 from above example
Dim rg As Range
Set rg = Sheet1.Range("B3").CurrentRegion

' Remove Header
Set rg = rg.Resize(rg.Rows.Count - 1).Offset(1)

' Start at row 1 as no header row
Dim i As Long
For i = 1 To rg.Rows.Count
    ' current row, column 1 of range
    Debug.Print rg.Cells(i, 1).Value2
Next i

 

Using Rows and Columns as Ranges

If you want to do something with an entire Row or Column you can use the Rows or Columns property of the Worksheet. They both take one parameter which is the row or column number you wish to access

' https://excelmacromastery.com/
Public Sub UseRowAndColumns()

    ' Set the font size of column B to 9
    Sheet1.Columns(2).Font.Size = 9

    ' Set the width of columns D to F
    Sheet1.Columns("D:F").ColumnWidth = 4

    ' Set the font size of row 5 to 18
    Sheet1.Rows(5).Font.Size = 18

End Sub

Using Range in place of Worksheet

You can also use Cells, Rows and Columns as part of a Range rather than part of a Worksheet. You may have a specific need to do this but otherwise I would avoid the practice. It makes the code more complex. Simple code is your friend. It reduces the possibility of errors.

 
The code below will set the second column of the range to bold. As the range has only two rows the entire column is considered B1:B2

' https://excelmacromastery.com/
Public Sub UseColumnsInRange()

    ' This will set B1 and B2 to be bold
    Sheet1.Range("A1:C2").Columns(2).Font.Bold = True

End Sub

 
You can download all the code for this post from the top of this article.
 

Reading Values from one Cell to another

In most of the examples so far we have written values to a cell. We do this by placing the range on the left of the equals sign and the value to place in the cell on the right. To write data from one cell to another we do the same. The destination range goes on the left and the source range goes on the right.

 
The following example shows you how to do this:

' https://excelmacromastery.com/
Public Sub ReadValues()

    ' Place value from B1 in A1
    Sheet1.Range("A1").Value2 = Sheet1.Range("B1").Value2

    ' Place value from B3 in sheet2 to cell A1
    Sheet1.Range("A1").Value2 = Sheet2.Range("B3").Value2

    ' Place value from B1 in cells A1 to A5
    Sheet1.Range("A1:A5").Value2 = Sheet1.Range("B1").Value2

    ' You need to use the "Value" property to read multiple cells
    Sheet1.Range("A1:A5").Value2 = Sheet1.Range("B1:B5").Value2

End Sub

 
As you can see from this example it is not possible to read from multiple cells. If you want to do this you can use the Copy function of Range with the Destination parameter

' https://excelmacromastery.com/
Public Sub CopyValues()

    ' Store the copy range in a variable
    Dim rgCopy As Range
    Set rgCopy = Sheet1.Range("B1:B5")

    ' Use this to copy from more than one cell
    rgCopy.Copy Destination:=Sheet1.Range("A1:A5")

    ' You can paste to multiple destinations
    rgCopy.Copy Destination:=Sheet1.Range("A1:A5,C2:C6")

End Sub

 
The Copy function copies everything including the format of the cells. It is the same result as manually copying and pasting a selection. You can see more about it in the Copying and Pasting Cells section.

Using the Range.Resize Method

When copying from one range to another using assignment(i.e. the equals sign), the destination range must be the same size as the source range.

Using the Resize function allows us to resize a range to a given number of rows and columns.

For example:
 

' https://excelmacromastery.com/
Sub ResizeExamples()
 
    ' Prints A1
    Debug.Print Sheet1.Range("A1").Address

    ' Prints A1:A2
    Debug.Print Sheet1.Range("A1").Resize(2, 1).Address

    ' Prints A1:A5
    Debug.Print Sheet1.Range("A1").Resize(5, 1).Address
    
    ' Prints A1:D1
    Debug.Print Sheet1.Range("A1").Resize(1, 4).Address
    
    ' Prints A1:C3
    Debug.Print Sheet1.Range("A1").Resize(3, 3).Address
    
End Sub

 
When we want to resize our destination range we can simply use the source range size.

In other words, we use the row and column count of the source range as the parameters for resizing:

' https://excelmacromastery.com/
Sub Resize()

    Dim rgSrc As Range, rgDest As Range
    
    ' Get all the data in the current region
    Set rgSrc = Sheet1.Range("A1").CurrentRegion

      ' Get the range destination
    Set rgDest = Sheet2.Range("A1")
    Set rgDest = rgDest.Resize(rgSrc.Rows.Count, rgSrc.Columns.Count)
    
    rgDest.Value2 = rgSrc.Value2

End Sub

 
We can do the resize in one line if we prefer:

' https://excelmacromastery.com/
Sub ResizeOneLine()

    Dim rgSrc As Range
    
    ' Get all the data in the current region
    Set rgSrc = Sheet1.Range("A1").CurrentRegion
    
    With rgSrc
        Sheet2.Range("A1").Resize(.Rows.Count, .Columns.Count).Value2 = .Value2
    End With
    
End Sub

Reading Values to variables

We looked at how to read from one cell to another. You can also read from a cell to a variable. A variable is used to store values while a Macro is running. You normally do this when you want to manipulate the data before writing it somewhere. The following is a simple example using a variable. As you can see the value of the item to the right of the equals is written to the item to the left of the equals.

' https://excelmacromastery.com/
Public Sub UseVariables()

    ' Create
    Dim number As Long

    ' Read number from cell
    number = Sheet1.Range("A1").Value2

    ' Add 1 to value
    number = number + 1

    ' Write new value to cell
    Sheet1.Range("A2").Value2 = number

End Sub

 
To read text to a variable you use a variable of type String:

' https://excelmacromastery.com/
Public Sub UseVariableText()

    ' Declare a variable of type string
    Dim text As String

    ' Read value from cell
    text = Sheet1.Range("A1").Value2

    ' Write value to cell
    Sheet1.Range("A2").Value2 = text

End Sub

 
You can write a variable to a range of cells. You just specify the range on the left and the value will be written to all cells in the range.

' https://excelmacromastery.com/
Public Sub VarToMulti()

    ' Read value from cell
    Sheet1.Range("A1:B10").Value2 = 66

End Sub

 
You cannot read from multiple cells to a variable. However you can read to an array which is a collection of variables. We will look at doing this in the next section.

How to Copy and Paste Cells

If you want to copy and paste a range of cells then you do not need to select them. This is a common error made by new VBA users.

Note: We normally use Range.Copy when we want to copy formats, formulas, validation. If we want to copy values it is not the most efficient method.
I have written a complete guide to copying data in Excel VBA here.

 
You can simply copy a range of cells like this:

Range("A1:B4").Copy Destination:=Range("C5")

 
Using this method copies everything – values, formats, formulas and so on. If you want to copy individual items you can use the PasteSpecial property of range.

 
It works like this

Range("A1:B4").Copy
Range("F3").PasteSpecial Paste:=xlPasteValues
Range("F3").PasteSpecial Paste:=xlPasteFormats
Range("F3").PasteSpecial Paste:=xlPasteFormulas

 
The following table shows a full list of all the paste types

Paste Type
xlPasteAll
xlPasteAllExceptBorders
xlPasteAllMergingConditionalFormats
xlPasteAllUsingSourceTheme
xlPasteColumnWidths
xlPasteComments
xlPasteFormats
xlPasteFormulas
xlPasteFormulasAndNumberFormats
xlPasteValidation
xlPasteValues
xlPasteValuesAndNumberFormats

Reading a Range of Cells to an Array

You can also copy values by assigning the value of one range to another.

Range("A3:Z3").Value2 = Range("A1:Z1").Value2

 
The value of  range in this example is considered to be a variant array. What this means is that you can easily read from a range of cells to an array. You can also write from an array to a range of cells. If you are not familiar with arrays you can check them out in this post.  

 
The following code shows an example of using an array with a range:

' https://excelmacromastery.com/
Public Sub ReadToArray()

    ' Create dynamic array
    Dim StudentMarks() As Variant

    ' Read 26 values into array from the first row
    StudentMarks = Range("A1:Z1").Value2

    ' Do something with array here

    ' Write the 26 values to the third row
    Range("A3:Z3").Value2 = StudentMarks

End Sub

 
Keep in mind that the array created by the read is a 2 dimensional array. This is because a spreadsheet stores values in two dimensions i.e. rows and columns

Going through all the cells in a Range

Sometimes you may want to go through each cell one at a time to check value.

 
You can do this using a For Each loop shown in the following code

' https://excelmacromastery.com/
Public Sub TraversingCells()

    ' Go through each cells in the range
    Dim rg As Range
    For Each rg In Sheet1.Range("A1:A10,A20")
        ' Print address of cells that are negative
        If rg.Value < 0 Then
            Debug.Print rg.Address + " is negative."
        End If
    Next

End Sub

 
You can also go through consecutive Cells using the Cells property and a standard For loop.

 
The standard loop is more flexible about the order you use but it is slower than a For Each loop.

' https://excelmacromastery.com/
Public Sub TraverseCells()
 
    ' Go through cells from A1 to A10
    Dim i As Long
    For i = 1 To 10
        ' Print address of cells that are negative
        If Range("A" & i).Value < 0 Then
            Debug.Print Range("A" & i).Address + " is negative."
        End If
    Next
 
    ' Go through cells in reverse i.e. from A10 to A1
    For i = 10 To 1 Step -1
        ' Print address of cells that are negative
        If Range("A" & i) < 0 Then
            Debug.Print Range("A" & i).Address + " is negative."
        End If
    Next
 
End Sub

Formatting Cells

Sometimes you will need to format the cells the in spreadsheet. This is actually very straightforward. The following example shows you various formatting you can add to any range of cells

' https://excelmacromastery.com/
Public Sub FormattingCells()

    With Sheet1

        ' Format the font
        .Range("A1").Font.Bold = True
        .Range("A1").Font.Underline = True
        .Range("A1").Font.Color = rgbNavy

        ' Set the number format to 2 decimal places
        .Range("B2").NumberFormat = "0.00"
        ' Set the number format to a date
        .Range("C2").NumberFormat = "dd/mm/yyyy"
        ' Set the number format to general
        .Range("C3").NumberFormat = "General"
        ' Set the number format to text
        .Range("C4").NumberFormat = "Text"

        ' Set the fill color of the cell
        .Range("B3").Interior.Color = rgbSandyBrown

        ' Format the borders
        .Range("B4").Borders.LineStyle = xlDash
        .Range("B4").Borders.Color = rgbBlueViolet

    End With

End Sub

Main Points

The following is a summary of the main points

  1. Range returns a range of cells
  2. Cells returns one cells only
  3. You can read from one cell to another
  4. You can read from a range of cells to another range of cells.
  5. You can read values from cells to variables and vice versa.
  6. You can read values from ranges to arrays and vice versa
  7. You can use a For Each or For loop to run through every cell in a range.
  8. The properties Rows and Columns allow you to access a range of cells of these types

What’s Next?

Free VBA Tutorial If you are new to VBA or you want to sharpen your existing VBA skills then why not try out the The Ultimate VBA Tutorial.

Related Training: Get full access to the Excel VBA training webinars and all the tutorials.

(NOTE: Planning to build or manage a VBA Application? Learn how to build 10 Excel VBA applications from scratch.)

Excel VBA Cells

Excel VBA Cells Function

Cells are one type of element in excel VBA. (Three elements of excel is Workbooks, Worksheets and Ranges/Cells)

Hierarchical between these elements or object will be:

Hireachical Element

Basic Structure For Referring a Cell

Excel VBA allows you to refer to cells in many different ways, cells refers to single cells only. (Note: it can’t refer to multiple cells like Range (“A2:E7”)

It is used for referencing a cell object e.g. it can be written as Cells (6, 5) for referring a cell “F5” where 6 is the column number & 5 is the row number Cells takes row & column number as an argument, cells are located within the range object With the help of cells in VBA, we can perform three important tasks, i.e. we can

  1. Read content from a cell
  2. Write a value to a cell
  3. Change the format of a cell

Difference between range & cells in VBA is Cells usually refer to a single cell at a time, while Range references a group of cells. The cell is a property of range in excel sheet, which is a characteristic, where it is used to describe a range Cells only returns one cell which is used to represent cells within a range of the worksheet.

This cells property is used to specify a single cell or all cells on the worksheet, where it returns a single cell in the Cells collection.

Syntax of VBA Cells in Excel

The syntax for VBA cells function in excel is as follows:

VBA Cells syntax

Cells argument will consider two numeric arguments to represent row & column, where the first one is for representing row number & and the second or last one referring to as column number.

Row Index: Which is row number which we are referring to.

Column Index: Which is column number which we are referring to.

Note: Either numbers or letters can be used to specify the Column index in CELLS E.G. Cells (5, “E”)

Comma (,): Separator between them is the union operator, which is used to combine several range of cells.

Expression = Cells (4, 2) indicates it is “B4” Cell on an active worksheet in row 4 and col 2

OR

Expression = Cells (4, “E”) indicates it is “B4” Cell on an active worksheet in row 4 and col 2

Above either of the code can be used to

Difference between Cell & Range syntax VBA code

To select cell B4 on the active worksheet, you can use either of the following examples:

ActiveSheet.Cells(4, 2).Select

or

ActiveSheet.Range(“B4”).Select

How to Use VBA Cells in Excel?

We will learn how to use VBA cells function with a few examples in excel.

You can download this VBA Cells Excel Template here – VBA Cells Excel Template

Example #1 – VBA Cells

Step 1:  Select or click on Visual Basic in the Code group on the Developer tab or you can directly click on Alt + F11 shortcut key.

VBA Cells Developers

Step 2: To create a blank module, right-click on Microsoft excel objects, in that click on Insert and under the menu section select Module, where the blank module gets created.

VBA Cells Module 1

Step 3: Double click on it, it is also called a code window, where you need to type Sub Cells_Example1() as the first message without any quotes around it. Now, you can observe, Excel automatically adds the line End Sub below the first message line when you press Enter.

Code:

Sub Cells_Example1()

End Sub

VBA Cells Example 1.1

Step 4: Now, all the codes which you enter must be between these two lines, Now you can start typing CELLS VBA code or syntax. Before typing code, enter CTRL + SPACE where VBA Intellisense Drop-down Menu appears, which helps you out in writing the code & you can autocomplete words in the VB editor.

The dropdown contains a list of all the members of the VB OBJECT MODEL active reference (i.e. includes objects, properties, variables, methods, and constants). This feature helps out in saving time & prevent misspell the words or typo-error.

VBA Cells Example 1.2

Step 5: After typing cells, click on the tab key to select it.

Code:

Sub Cells_Example1()

Cells

End Sub

Example 1.3

Step 6: Once you leave a space and enter open bracket “(”, CELLS argument will appear where it considers two numeric arguments to represent row & column index, where the first one is for representing row number & and the second or last one referring to as column number.

Code:

Sub Cells_Example1()

Cells(

End Sub

VBA Cells Example 1.4

Step 7: Now, I enter the row index number as “4” & column index as “2” and close the bracket. Full stop and enter one space by clicking on the spacebar, now the cells argument is ready. And I want value in it. So, I enter again enter CTRL + SPACE where VBA Intellisense Drop-down Menu appears, type “Val” which means value.

Code:

Sub Cells_Example1()

Cells(4, 2). Val

End Sub

Example 1.5

Step 8: Suppose you want “HI” to appear in that cell. For that, you need to type = “HI”. and click enter.

Code:

Sub Cells_Example1()

Cells(4, 2).Value = "Hi"

End Sub

Example 1.6

Step 9: Now, the code is ready, you can run the macro by clicking the Run Sub button (i.e. green “play” button) or by pressing F5. You can observe “Hi” appears in the cell “B4”

VBA Cells

Things to Remember

  • Only one cell can be referred at a time with the help of Cells property.
  • Cell property is very significant & useful in a programming loop.
  • If you missed out or don’t specify a worksheet (by its name in VBA code), Excel considers or assumes the ACTIVE Sheet in a workbook.
  • If you missed out or don’t specify row and column index argument, then Excel will refer to all cells on the worksheet. E.g. Cells is the syntax for all cells on the Active Sheet.
  • You can combine cells with range together to define a starting & ending pint of a range with variables.

Recommended Articles

This is a guide to VBA Cells. Here we discuss how to use Excel VBA Cells Function along with practical examples and downloadable excel template. You can also go through our other suggested articles –

  1. VBA Web Scraping
  2. VBA XML
  3. VBA Subscript out of Range
  4. VBA IsError

  • Функция Excel VBA Cells

Функция Excel VBA Cells

Клетки являются одним из типов элементов в Excel VBA. (Три элемента Excel — это рабочие книги, рабочие таблицы и диапазоны / ячейки)

Иерархия между этими элементами или объектом будет:

Основная структура для ссылки на ячейку

Excel VBA позволяет ссылаться на ячейки разными способами, ячейки ссылаются только на отдельные ячейки. (Примечание: он не может ссылаться на несколько ячеек, таких как Range («A2: E7»)

Он используется для ссылки на объект ячейки, например, он может быть записан как ячейки (6, 5) для ссылки на ячейку «F5», где 6 — номер столбца и 5 — номер строки. Ячейки принимает номер строки и столбца в качестве аргумента, ячейки. расположены внутри объекта диапазона. С помощью ячеек в VBA мы можем выполнить три важные задачи, т.е.

  1. Читать содержимое из ячейки
  2. Запишите значение в ячейку
  3. Изменить формат ячейки

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

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

Синтаксис ячеек VBA в Excel

Синтаксис для функции ячеек VBA в Excel выглядит следующим образом:

Аргумент Cells будет рассматривать два числовых аргумента для представления строки и столбца, где первый — для представления номера строки &, а второй или последний — для номера столбца.

Индекс строки: номер строки, на которую мы ссылаемся.

Индекс столбца: номер столбца, на который мы ссылаемся.

Примечание. Для указания индекса столбца в ячейках CELLS EG (5, «E») можно использовать цифры или буквы.

Запятая (, ): Разделителем между ними является оператор объединения, который используется для объединения нескольких диапазонов ячеек.

Выражение = Ячейки (4, 2) указывает, что это ячейка «B4» на активном листе в строке 4 и столбце 2

ИЛИ

Выражение = Ячейки (4, «E») указывает, что это ячейка «B4» на активном листе в строке 4 и столбце 2

Выше любой код может быть использован для

Разница между синтаксисом VBA-кода Cell и Range

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

ActiveSheet.Cells (4, 2) .Выбрать

или

ActiveSheet.Range ( «B4»). Выберите

Как использовать ячейки VBA в Excel?

Мы научимся использовать функцию ячеек VBA на нескольких примерах в Excel.

Вы можете скачать этот шаблон VBA Cells Excel здесь — Шаблон VBA Cells Excel

Пример № 1 — клетки VBA

Шаг 1: Выберите или нажмите Visual Basic в группе « Код » на вкладке « Разработчик » или вы можете напрямую нажать сочетание клавиш Alt + F11 .

Шаг 2: Чтобы создать пустой модуль, щелкните правой кнопкой мыши объекты Microsoft Excel, в этом нажмите Вставить и в разделе меню выберите Модуль, где будет создан пустой модуль.

Шаг 3: Дважды щелкните по нему, оно также называется окном кода, где вам нужно ввести Sub Cells_Example1 () в качестве первого сообщения без кавычек. Теперь вы можете наблюдать, что Excel автоматически добавляет строку End Sub под первой строкой сообщения, когда вы нажимаете Enter.

Код:

 Sub Cells_Example1 () End Sub 

Шаг 4. Теперь все коды, которые вы вводите, должны находиться между этими двумя строками. Теперь вы можете начать ввод кода или синтаксиса CELLS VBA. Прежде чем вводить код, введите CTRL + ПРОБЕЛ, где появится раскрывающееся меню VBA Intellisense, которое поможет вам в написании кода и вы сможете автоматически дополнять слова в редакторе VB.

Раскрывающийся список содержит список всех членов активной ссылки VB OBJECT MODEL (т.е. включает объекты, свойства, переменные, методы и константы). Эта функция помогает сэкономить время и предотвратить ошибочные слова или опечатку.

Шаг 5: После ввода ячеек нажмите на клавишу табуляции, чтобы выбрать ее.

Код:

 Sub Cells_Example1 () Ячейки Конец Sub 

Шаг 6: Как только вы оставите пробел и введете открытую скобку «(», появится аргумент CELLS, где он рассматривает два числовых аргумента для представления индекса строки и столбца, где первый — для представления номера строки, а второй или последний ссылается в качестве номера столбца.

Код:

 Sub Cells_Example1 () Ячейки (End Sub 

Шаг 7: Теперь я ввожу номер индекса строки как «4» и индекс столбца как «2» и закрываю скобку. Полная остановка и введите один пробел, нажав на пробел, теперь аргумент ячейки готов. И я хочу ценность в этом. Итак, я снова ввожу ввод CTRL + SPACE, где появляется выпадающее меню VBA Intellisense, введите «Val», что означает значение.

Код:

 Sub Cells_Example1 () Ячейки (4, 2). Val End Sub 

Шаг 8: Предположим, вы хотите, чтобы в этой ячейке появилось «HI». Для этого вам нужно набрать = «HI». и нажмите ввод.

Код:

 Sub Cells_Example1 () Ячейки (4, 2) .Value = "Hi" End Sub 

Шаг 9: Теперь код готов, вы можете запустить макрос, нажав кнопку Run Sub (т.е. зеленую кнопку «play») или нажав F5 . Вы можете наблюдать «Привет» появляется в ячейке «B4»

То, что нужно запомнить

  • Только одна ячейка может быть передана одновременно с помощью свойства Cells.
  • Свойство ячейки очень важно и полезно в цикле программирования.
  • Если вы пропустили или не указали лист (по его имени в коде VBA), Excel учитывает или принимает лист ACTIVE в книге.
  • Если вы пропустили или не указали аргумент индекса строки и столбца, то Excel будет ссылаться на все ячейки на листе. Например, Ячейки — это синтаксис для всех ячеек на Активном Листе.
  • Вы можете комбинировать ячейки с диапазоном, чтобы определить начальную и конечную пинту диапазона с переменными.

Рекомендуемые статьи

Это руководство по VBA Cells. Здесь мы обсуждаем, как использовать функцию Excel VBA Cells вместе с практическими примерами и загружаемым шаблоном Excel. Вы также можете просмотреть наши другие предлагаемые статьи —

  1. Функция копирования и вставки в VBA
  2. Функция подстроки Excel
  3. Индекс VBA вне диапазона
  4. Excel ISNUMBER Formula

Понравилась статья? Поделить с друзьями:
  • Vba excel функция не возвращает значение
  • Vba excel ячейки по имени диапазона
  • Vba excel функция найти
  • Vba excel ячейка перенос по словам
  • Vba excel функция если пример