Переменная равна значению ячейки в excel

В приложении 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 активного листа.

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

Adding data to the worksheet is often done and it is essential to learn how to set variable to cell value in excel VBA. There can be instances when you want to add the same data to your worksheet. This task could easily be achieved with the help of Excel VBA variables. You can assign your cell values with variables. Let’s learn how to set variables to cell values in Excel VBA.

Declaring Variables in VBA

Before learning the assignment of variables, one needs to know what are variables and why they are used? Like any other programming language, VBA has variables. Variables are the containers to store data in them. There are some rules for storing data in them.

Rules for naming Variables

  • The variable name cannot start with a number.
  • While naming the variables you cannot have space between the names which means a space character (‘ ‘) is prohibited.
  • The length of the variable name should be less than Two-hundred and fifty-five (255) characters.

Implicit and Explicit Declaration

In Excel VBA, variables can be classified into 2 categories implicit and explicit,

Implicit Declaration

The implicit declaration declares a variable of data type variant. When we create variables implicitly, we never mention the data type to be used. The VBA automatically considers that variable as of variant type.

Syntax: variable_name = assigned_value

The variant data type is of two types,

  • Numeric Variant: The numeric variant data type is provided by VBA when the variable is assigned with a number. The bytes used are 16. It can take any value to Double.

Numeric-variant-data-type

  • Text Variant: The text variant data type is provided by VBA when the variable is assigned with a text. The bytes used are 22. It’s always possible to take variable sizes of the string.

Text-variant-data-type

Explicit Declaration

The explicit declaration declares a variable of custom data type. One can always mention the data type of the variable being used at the time of declaration. The keyword used is ‘Dim’.

Syntax: Dim variable_name as data_type

variable_name = assigned_value

Variable-name-as-data-type

Opening VBA immediate Window

The excel immediate window can be compared with a terminal that displays the code output in any other programming language. We will use this immediate window to run our code in the macro itself and display the code output immediately. You can also use the immediate window for debugging and running multiple VBA macros at once.

Different Ways to Open Immediate Windows in VBA

Press Ctrl + G

Open your VBA, then use the Short cut Ctrl + G on your keyboard, and the immediate window will open at the bottom side of your VBA.

Using View Tab

Step 1: Go to the Developer Tab, under the code section, and click on Visual Basic.

Clicking-visual-basic

Step 2: The VBA editor is open now.

VBA-editor-opens

Step 3: Go to View Tab, and click on Immediate Window.

Clicking-immediate-window

Step 4: The Immediate Window appears.

Immediate-window-displayed

Set Variable to Cell Value

After learning how to declare variables, and how to access the immediate window, you are ready to learn how to set variables to cell Values. Given the name of a student, ‘Arushi’. Write her Age and Aim in the worksheet by assigning variables in the VBA Macro.

Assigning-variables-in-VBA-macro

Step 1: Go to the Developer Tab, under the code section, and click on Visual Basic.

Clicking-visual-basic

Step 2: Your VBA editor is opened. Create a new Module. The name of the Sub created is geeks(). Declare an Age variable explicitly with custom data type as Integer. Assign the variable value as 19.

Variable-value-19-assigned

Step 3: Set the cell value by the variable name. Use =Range(cell).Value function to access any cell in the worksheet. Assign the Age variable to it. Run your macro.

Assigning-age-variable

Step 4: The value of cell C5 is set to 19.

Value-of-C5-set-as-19

Step 5: Repeat steps 2, 3, and 4 to set Aim for cell D5. Declare a variable name Aim explicitly with data type as Variant. Assign the variable value “CA”. Again, use the range function and set the cell value of D5 to the variable Aim.

Setting-value-of-D5-to-variable-name

Step 6: The value of cell D5 is set to “CA”.

D5-set-as-CA

Set Cell Value to Variable

We can also assign the cell values in the worksheet to the variables. Consider, the same data set as above but this time the age and aim of the student ‘Arushi’ are prefilled. Your task is to assign these values to the variables and print them in the immediate window.

Values-prefilled-shown

Step 1: Go to the Developer Tab, under the code section, and click on Visual Basic.

Clicking-visual-basic

Step 2: Declare the Age variable explicitly using the Dim keyword.

Age-variable-declared

Step 3: Assign the Age variable with the value of cell ‘C5′. This can be achieved using =Range(cell).Value function. Print the Age variable in the immediate window using Debug.Print(variable) function.

Assigning-age-variable-to-C5

Step 4: Click on the run button. The macro will run, and 19 is printed in the immediate window of the VBA.

Running-the-macro

Step 5: Repeat Steps 2, 3, and 4. Declare the Aim variable explicitly. The Range function assigns a cell value of D5 in the variable Aim. Print the Aim variable in the immediate window.

Printing-aim-variable-in-window

Step 6: Click on the run button, and “CA” is printed in the Immediate Window.

CA-printed-in-immediate-window

Novichek =)

537 / 28 / 4

Регистрация: 25.04.2011

Сообщений: 238

1

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

25.04.2011, 16:09. Показов 68181. Ответов 6

Метки нет (Все метки)


Студворк — интернет-сервис помощи студентам

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Sub Макрос1()
'
' Макрос1 Макрос
'
 
'
  
    m = Cells(1, 1) ' получение значения ячейки из A1 (может я я тут что то не так сделал?)
    If m = 1 Then
    Range("H13:L13").Select
    Selection.Copy
    Range("H14").Select
    ActiveSheet.Paste
    End If
End Sub

Может я в синтаксисе что то не так написал??? Но макрос упорно не хочет выполняться?
Идея была такая: «Выбирает значение ячейки А1 — если оно равно 1 — выбирает диапазон Н13-L13 — копирует и вставляет его в Н14»



1



Ципихович Эндрю

1508 / 478 / 56

Регистрация: 10.04.2009

Сообщений: 8,008

25.04.2011, 17:04

2

Visual Basic
1
2
'значение ячейки Эксель без пробелов в начале и в конце ячейки
Значение = Trim(Worksheets("Лист1").Range("c1").Value)



2



730 / 406 / 95

Регистрация: 19.12.2010

Сообщений: 756

25.04.2011, 18:02

3

Novichek =), макрос полностью работоспособен. См. вложение.



1



Novichek =)

537 / 28 / 4

Регистрация: 25.04.2011

Сообщений: 238

26.04.2011, 14:51

 [ТС]

4

Что бы не плодить не нужные темы и не сорить на форуме продолжу спрашивать тут =)

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Sub Макрос23()
' Макрос2 Макрос
'
  Mw = "Легроин"
    m = Range("B1") ' получение значения ячейки из В1
    If m = Mw Then
    Range("L4").Select
    Selection.Copy
    Range("L5").Select
    ActiveSheet.Paste
    End If
      Mw = "Бензин"
    m = Range("B1") ' получение значения ячейки из В1
    If m = Mw Then
    Range("M4").Select
    Selection.Copy
    Range("L5").Select
    ActiveSheet.Paste
    End If
End Sub

Смысл всей задумки такой: создание базы веществ с определенными свойствами ( в ячейкахM4 и L4) с помощью выпадающего списка ActiveX. Щелкая на какое нибудь значение из списка (например «бензин») в связанной ячейке B1 появляется значение переменной «бензин», собственно после чего выполняется вышеуказанный код и свойство копируется в L5. Собственно хорошо когда 2 вещества, а когда их 200… Может как-нибудь можно написать цикл или еще что-то подобное чтобы упростить код?



0



730 / 406 / 95

Регистрация: 19.12.2010

Сообщений: 756

26.04.2011, 17:04

5

Можно автоматизировать выбор из базы без макросов.



1



537 / 28 / 4

Регистрация: 25.04.2011

Сообщений: 238

27.04.2011, 08:57

 [ТС]

6

Цитата
Сообщение от 19vitek
Посмотреть сообщение

Можно автоматизировать выбор из базы без макросов.

Огромное человеческое спасибо! ) Правильно зачем лишний раз усложнять жизнь ))))

Добавлено через 41 минуту
Кстати еще хотел спросить есть ли способы чтобы инфу полученную из базы Экселя он отправлял в таблицу Ворда? (было бы вообще круто) Заранее спасибо за ответы!



0



13 / 13 / 0

Регистрация: 24.09.2015

Сообщений: 206

27.10.2015, 22:23

7

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

Добавлено через 2 минуты
http://www.planetaexcel.ru/for… &TID=31272 То что вы хотите (хотели), находится здесь.



0



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

Хитрости »

1 Май 2011              225674 просмотров


Что такое переменная и как правильно её объявить?

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

Для чего нужна переменная? Чтобы хранить значение и применить его позже в любой момент. Например, в ячейке А1 записана сумма, а нажатием на кнопку запускается обновление отчета. После обновления отчета сумма в А1 изменится. Необходимо сверить сумму до обновления с суммой после и в зависимости от этого сделать какое-либо действие. Переменная как раз позволит запомнить значение ячейки до того, как она обновится и использовать именно это значение после обновления.


  • Требования к переменным
  • Типы данных, хранимых в переменных
  • Как объявлять переменные
  • Как правильно назвать переменную
  • Пример использования переменных
  • Константы

В качестве имен переменных можно использовать символы букв и числа, но первой в имени переменной всегда должна быть буква. Не допускается использование точки, запятой, пробела и иных знаков препинания, кроме нижнего подчеркивания. Длина имени не должна превышать 254 символов. Так же нельзя использовать в качестве имен для переменных зарезервированные константы редактора VBA(например Sub, Msgbox, ubound, Date и т.п.). Так же для переменных неважен регистр букв.

 
Теперь рассмотрим основные декларированные в VBA

типы данных, которые можно хранить в переменных:

Тип данных Занимает байт в памяти Пределы значений
Byte 1 Целые числа от 0 до 255
Boolean 2 True или False
Integer 2 Целые числа от (-32768) до 32767
Long 4 Целые числа от (-2147483648) до 2147483647
Single 4 От (–3.402823Е+38) до (–1.401298Е-45) и от 1.401298Е-45 до 3.402823Е+38
Double 8 От ±1.79769313486232Е+308 до ±4.94065645841247Е-324
Decimal 12 От ±79228162514264337593543950335 без десятичных знаков до ±7,9228162514264337593543950335 с 28-ю знаками после запятой
Currency 8 От (–922337203685477.5808) до 922337203685477.5807
Date 8 От 01.01.100 до 31.12.9999(не надо путать с датами в Excel — 01.01.1900 до 31.12.9999)
String 10(+длина строки) От 0 до 65400 символов для фиксированных строк и чуть более 2 млрд. для строк переменной длины
Object 4 Любой объект
Array Определяется кол-вом и размером элементов
Variant от 16-ти Любой из встроенных типов данных

Как видно из таблицы больше всего памяти занимает Variant. Притом это если он хранит числовые данные. Если же такая переменная будет хранить данные строкового типа(текст), то размер занимаемой памяти будет измеряться уже начиная с 22 байт + длина строки, хранящейся в переменной. Чем больше памяти занимает переменная, тем дольше она инициализируется в памяти и тем медленнее код будет выполняться. Вот поэтому и важно явно задавать тип данных, хранимых в переменной — это называется объявить переменную.

Тип данных Decimal больше не используется, поэтому объявить переменную данного типа в VBA не получится — подобная попытка приведет к синтаксической ошибке. Для работы с данными типа Decimal переменную необходимо изначально объявить как Variant или вообще без типа (например Dim a), т.к. тип данных Variant используется в VBA по умолчанию и принимает любой тип данных.

Так же переменным можно назначать и другие типы данных, которых нет в таблице выше — это типы, которые поддерживаются объектной моделью приложений, к которым «подключен» VBA. Например, если зайти в VBA из Excel, то библиотека типов объектной модели Excel подключена по умолчанию и для переменных становится доступно множество типов этой объектной модели. Многие из них знакомы всем: Workbook, Worksheet, Range, Cells, Chart и т.д. Т.е. это книги, листы, ячейки, диаграммы. Типов много, почти на каждый объект и коллекцию. Рассматривать здесь все бессмысленно. Могу лишь привести пару строк кода:

Dim rRange as Range 'назначили переменной тип ячейка/диапазон
Set rRange = Range("A1") 'присвоили ссылку на ячейку A1 текущего листа

Про объявление переменных подробно написано чуть ниже.
А более подробно про обращение к диапазонам из VBA можно почитать в этой статье: Как обратиться к диапазону из VBA

как объявлять переменные

На самом деле все очень просто. Это делается при помощи операторов области действия: Dim, Public,Static и оператора присвоения типа As. Самый распространенный оператор — Dim. Его и возьмем в качестве примера. Синтаксис объявления:

[оператор области действия] Имя_переменной As [тип данных]

Очень частая ошибка при объявлении переменных, совершаемая начинающими изучать VBA:

Dim MyVar1, MyVar2, MyVar3 As Integer

Вроде бы исходя из логики всем переменным присвоен тип данных Integer. Но это ошибочное суждение. Тип Integer присвоен только последней переменной, к которой он «привязан» оператором AsMyVar3. Все остальные переменные имеют тип данных Variant. Т.е. если Вы не задаете каждой переменной свой тип хранимых данных явно(т.е. не указываете для неё тип данных через As), то VBA сам присваивает для такой переменной тип данных Variant, т.к. он может хранить любой тип данных. А вот так выглядит правильное присвоение типа данных:

Dim MyVar1 As Integer, MyVar2 As Integer, MyVar3 As Integer

Это и есть объявление переменных. Т.е. сначала идет оператор области действия (Dim, Public,Static), сразу за ним имя переменной, затем оператор As и тип.
Но это не все. Некоторые типы переменным можно присваивать еще короче — даже без оператора As:

Dim MyVar1%, MyVar2%, MyVar3%

Всего шесть типов, которые можно объявить подобным методом:
! — Single
# — Double
$ — String
% — Integer
& — Long
@ — Currency
На что стоит обратить внимание, при объявлении переменных подобным образом: между именем переменной и знаком типа не должно быть пробелов.
Я лично в большинстве статей предпочитаю использовать первый метод, т.е. полное указание типа. Это читабельнее и понятнее. В каких-то проектах могу использовать краткое указание, в общих(разработка в команде) — полное. В своих кодах Вы вправе использовать удобный Вам метод — ошибки не будет.

Теперь разберемся с операторами области действия(Dim, Public и Static):

  • Dim — данный оператор используется для объявления переменной, значение которой будет храниться только в той процедуре, внутри которой данная переменная объявлена. Во время запуска процедуры такая переменная инициализируется в памяти и использовать её значение можно внутри только этой процедуры, а по завершению процедуры переменная выгружается из памяти(обнуляется) и данные по ней теряются. Переменную, объявленную подобным образом еще называют локальной переменной. Однако с помощью данного оператора можно объявить переменную, которая будет доступна в любой процедуре модуля. Необходимо объявить переменную вне процедуры — в области объявлений(читать как первой строкой в модуле, после строк объявлений типа — Option Explicit). Тогда значение переменной будет доступно в любой процедуре лишь того модуля, в котором данная переменная была объявлена. Такие переменные называются переменными уровня модуля. Также для использования переменных во всех процедурах и функциях одного конкретного модуля можно использовать оператор Private. Но он в данном случае ничем не отличается от Dim, а пишется длиннее :) Плюс, Private нельзя использовать внутри процедуры или функции(только в области объявлений), что еще больше сужает её применимость. По сути чаще этот оператор применяется к функциям и процедурам(об этом см.ниже)
  • Static — данный оператор используется для объявления переменной, значение которой предполагается использовать внутри конкретной процедуры, но не теряя значения данной переменной по завершении процедуры. Переменные данного типа обычно используют в качестве накопительных счетчиков. Такая переменная инициализируется в памяти при первом запуске процедуры, в которой она объявлена. По завершении процедуры данные по переменной не выгружаются из памяти, но однако они не доступны в других процедурах. Как только Вы запустите процедуру с этой переменной еще раз — данные по такой переменной будут доступны в том виде, в котором были до завершения процедуры. Выгружается из памяти такая переменная только после закрытия проекта(книги с кодом).
  • Public — данный оператор используется для объявления переменной, значение которой будет доступно в любой процедуре проекта(в обычных модулях, модулях класса, модулях форм, модулях листов и книг). Переменная, объявленная подобным образом, должна быть объявлена вне процедуры — в области объявлений. Такая переменная загружается в память во время загрузки проекта(при открытии книги) и хранит значение до выгрузки проекта(закрытия книги). Использовать её можно в любом модуле и любой процедуре проекта. Важно: объявлять подобным образом переменную необходимо строго в стандартном модуле. Такие переменные называются переменными уровня проекта. В простонародье такие переменные еще называют глобальными(возможно из-за того, что раньше подобные переменные объявлялись при помощи оператора Global, который в настоящее время устарел и не используется).
    Для большего понимания того, где и как объявлять переменные уровня проекта два небольших примера.
    Неправильное объявление

    Option Explicit
     
    Sub main()
    Public MyVariable As String
    MyVariable = "Глобальная переменная"
    'показываем текущее значение переменной
    MsgBox MyVariable
    'пробуем изменить значение переменной
    Call sub_main
    'показываем измененное значение переменной
    MsgBox MyVariable
    End Sub
    'доп.процедура изменения значения переменной
    Sub ChangeMyVariable()
    MyVariable = "Изменили её значение"
    End Sub

    переменные не будут видны во всех модулях всех процедур и функций проекта, потому что:
    1. Оператор Public недопустим внутри процедуры(между Sub и End Sub), поэтому VBA при попытке выполнения такой процедуры обязательно выдаст ошибку — Invalid Attribut in Sub or Function.
    2. Даже если Public заменить на Dim — это уже будет переменная уровня процедуры и для других процедур будет недоступна.
    3. Т.к. объявление неверное — вторая процедура(ChangeMyVariable) ничего не знает о переменной MyVariable и естественно, не сможет изменить именно её.
    Правильное объявление

    'выше глобальных переменных и констант могут быть только декларации:
    Option Explicit     'принудительное объявление переменных
    Option Base 1       'нижняя граница объявляемых массивов начинается с 1
    Option Compare Text 'сравнение текста без учета регистра
    'глобальная переменная - первой строкой, выше всех процедур
    Public MyVariable As String
    'далее процедуры и функции
    Sub main()
        MyVariable = "Глобальная переменная"
        'показываем текущее значение переменной
        MsgBox MyVariable, vbInformation, "www.excel-vba.ru"
        'пробуем изменить значение переменной
        Call ChangeMyVariable
        'показываем измененное значение переменной
        MsgBox MyVariable, vbInformation, "www.excel-vba.ru"
    End Sub
    'доп.процедура изменения значения переменной
    Sub ChangeMyVariable()
        MyVariable = "Изменили её значение"
    End Sub

    Если при этом вместо Public записать Dim, то эта переменная будет доступна из всех функций и процедур того модуля, в котором записана, но недоступна для функций и процедур других модулей.
    Переменные уровня проекта невозможно объявить внутри модулей классов(ClassModule, ЭтаКнига(ThisWorkbook), модулей листов, модулей форм(UserForm) — подробнее про типы модулей: Что такое модуль? Какие бывают модули?)

  • Операторы области действия так же могут применяться и к процедурам. Для процедур доступен еще один оператор области действия — Private. Объявленная подобным образом процедура доступна только из того модуля, в котором записана и такая процедура не видна в диалоговом окне вызова макросов(Alt+F8)
  • 'процедура записана в Module1
    'эта процедура будет доступна для вызова исключительно из процедур в этом же модуле
    'но не будет доступна при вызове из других модулей
    Private Sub PrivateMain()
        MsgBox "Процедура может быть вызвана только из модуля, в котором записана", vbInformation, "www.excel-vba.ru"
    End Sub
    'другая процедура, записанная в этом же модуле
    Sub CallPrivate()
        Call PrivateMain
    End Sub
    'эта процедура записана в другом модуле - Module2
    'при попытке вызова этой процедурой получим ошибку
    ' Sub or Function not defined
    ' потому что процедура PrivateMain объявлена только для Module1
    Sub CallPrivate_FromModule1()
        Call PrivateMain
    End Sub

    При этом, если из Excel нажать сочетание клавиш Alt+F8, то в окне будут доступны только CallPrivate_FromModule1 и CallPrivate. Процедура PrivateMain будет недоступна.

Как правильно назвать переменную:

«Что самое сложное в работе программиста? — выдумывать имена переменным.» :-)А ведь придумать имя переменной тоже не так-то просто. Можно, конечно, давать им имена типа: a, d, f, x, y и т.д.(я сам иногда так делаю, но либо в простых кодах, либо для специального запутывания кода). Но стоит задуматься: а как Вы с ними будете управляться в большом коде? Код строк на 10 еще потерпит такие имена, а вот более крупные проекты — не советовал бы я в них оперировать такими переменными. Вы сами запутаетесь какая переменная как объявлена и какой тип данных может хранить и что за значение ей присвоено. Поэтому лучше всего давать переменным осмысленные имена и следовать соглашению об именовании переменных. Что за соглашение? Все очень просто: перед основным названием переменной ставится префикс, указывающий на тип данных, который мы предполагаем хранить в данной переменной. Про имеющиеся типы данных я уже рассказал выше. А ниже приведена примерная таблица соответствий префиксов типам данных:

Префикс Тип хранимых данных
b Boolean
bt Byte
i Integer
l Long
s Single
d Double
c Currency
dt Date
str String
obj Object
v Variant

Лично я немного для себя её переделал, т.к. некоторые обозначения мне кажутся скудными. Например Double я обозначаю как dbl, а Single как sgl. Это мне кажется более наглядным.

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

DefBool B
Sub test()
    Dim bCheck
End Sub

Автоматически переменной bCheck будет присвоен тип Boolean, т.к. она начинается с буквы b — регистр здесь не имеет значения(впрочем как в VBA в целом). Оператор Def задается в области объявления. Можно задать не одну букву, а целый диапазон букв:

DefBool B-C
Sub test()
    Dim bCheck, cCheck
End Sub

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

DefBool B
DefStr S
Sub test()
    Dim bCheck, sCheck
End Sub

Ниже приведен полный перечень операторов типов и данные, которые задает каждый из них:
DefBool — Задает тип Boolean
DefByte — Задает тип Byte
DefCur — Задает тип Currency
DefDate — Задает тип Date
DefDbl — Задает тип Double
DefInt — Задает тип Integer
DefLng — Задает тип Long
DefObj — Задает тип Object
DefSng — Задает тип Single
DefStr — Задает тип String
DefVar — Задает тип Variant
По умолчанию в VBA применена инструкция DefVar для всех букв(иначе говоря для всех переменных, которым не назначен тип данных явно через оператор As).

Ну и немаловажный момент это непосредственно осмысленное имя переменной. Имя переменной должно примерно отражать то, что в ней будет храниться. Например, Вы создаете отчет и Вам надо объявить две переменные: одна имя листа, другая имя книги. Можно было сделать так: str1, str2. Коротко, здорово. Но если подумать — и как можно понять, какая из этих переменных что хранит? Никак. Надо просматривать код и вспоминать, какой переменной какое значение было присвоено. Не совсем удобно, правда? А если бы Вы задали имена так: strBookName, strSheetName, то вроде как более понятно, что мы в них будем хранить. Это удобно не только вам самим при работе с кодом, но и другим людям, которые, возможно в будущем будут пользоваться Вашим кодом. Им будет удобнее читать код, если он будет оформлен грамотно, а переменные названы осмысленно. И не стоит экономить на длине имени — имя должно быть понятным. Без фанатизма, конечно :-). Хоть VBA и позволяет нам создавать переменные длиной до 254 символов, но читать такую переменную так же неудобно, как и с одним символом. Но здесь уже все зависит от Ваших предпочтений и фантазии.
Небольшое дополнение: лучше привыкать давать названия переменным на латинице(т.е. английский алфавит), т.к. для VBA английский язык «родной» и лучше использовать его.

Небольшой пример использования переменных в кодах:
Sub main()
'объявляем переменные с назначением конкретных типов
'As String - текст
'As Long   - целое число
Dim sAddress As String, sNewAddress As String, sShName As String
Dim lRow As Long
Dim rRange as Range 'назначили переменной тип ячейка/диапазон
 
'присвоили переменной rRange ссылку на текущую выделенную ячейку
Set rRange = Selection
'меняем выделение - выделяем ячейку D9
Range("D9").Select
'назначаем переменной адрес выделенных ячеек
sAddress = Selection.Address
'назначаем переменной lRow значение первой строки выделенной области
lRow = Selection.Row
'показываем сообщение
MsgBox "Адрес выделенной области: " & sAddress, vbInformation, "www.excel-vba.ru"
MsgBox "Номер первой строки: " & lRow, vbInformation, "www.excel-vba.ru"
'назначаем другой переменной значение адреса ячейки A1
sNewAddress = "A1"
'выделяем ячейку, заданную переменной sNewAddres
Range(sNewAddress).Select
MsgBox "Адрес выделенной области: " & sNewAddress, vbInformation, "www.excel-vba.ru"
'выделяем изначально выделенную ячейку, используя переменную rRange
rRange.Select
MsgBox "Адрес выделенной области: " & rRange.Address, vbInformation, "www.excel-vba.ru"
'задаем значение переменной
sShName = "excel-vba"
'переименовываем активный лист на имя, заданное переменной
ActiveSheet.Name = sShName
End Sub

Просмотреть пошагово выполнение данного кода поможет статья: Отлов ошибок и отладка кода VBA
Важно! Назначение значений переменным задается при помощи знака равно(=). Однако, есть небольшой нюанс: для переменных типа Object(а так же других объектных типов(Workbook, Worksheet, Range, Cells, Chart и т.п.)) присвоение идет при помощи ключевого оператора Set:

'присвоили переменной rRange ссылку на текущую выделенную ячейку
Set rRange = Selection

это так же называется присвоением ссылки на объект. Почему именно ссылки? Все просто: при помещении в переменную непосредственно ячейки или диапазона(Set var = Range(«A1») или Set rRange = Selection) нет никакого запоминания самой ячейки. В переменную помещается лишь ссылка на эту ячейку(можете считать, что это как ссылка в формулах) со всеми вытекающими: такое назначение не запоминает свойства ячейки до или после — в переменной хранится ссылка на конкретную ячейку и доступ есть исключительно к свойствам ячейки на текущий момент. Чтобы запомнить для этой ячейки значение, цвет или даже адрес (а так же и другие свойства) до её изменения и применить запомненное даже после изменения/перемещения самой ячейки — необходимо запоминать в переменные именно свойства ячейки:

Sub main()
    Dim val, l_InteriorColor As Long, l_FontColor As Long
    Dim rRange As Range 'назначили переменной тип ячейка/диапазон
 
    'присвоили переменной rRange ссылку на активную ячейку
    Set rRange = ActiveCell
    'запоминаем свойства ячейки
    val = rRange.Value                      'значение
    l_InteriorColor = rRange.Interior.Color 'цвет заливки
    l_FontColor = rRange.Font.Color         'цвет шрифта
    'копируем другую ячейку и вставляем на место активной
    ActiveSheet.Range("D1").Copy rRange
 
    'проверяем, что rRange теперь имеет совершенно другие свойста - как у D1
    MsgBox "Значение rRange: " & rRange.Value & vbNewLine & _
           "Цвет заливки rRange: " & rRange.Interior.Color & vbNewLine & _
           "Цвет шрифта rRange: " & rRange.Font.Color & vbNewLine, vbInformation, "www.excel-vba.ru"
 
    'назначаем свойства из сохраненных в переменных
    rRange.Value = val                      'значение
    rRange.Interior.Color = l_InteriorColor 'цвет заливки
    rRange.Font.Color = l_FontColor         'цвет шрифта
 
    'проверяем, что rRange возвращены параметры до копирования
    MsgBox "Значение rRange: " & rRange.Value & vbNewLine & _
           "Цвет заливки rRange: " & rRange.Interior.Color & vbNewLine & _
           "Цвет шрифта rRange: " & rRange.Font.Color & vbNewLine, vbInformation, "www.excel-vba.ru"
End Sub

Это так же распространяется на все другие объекты. Т.е. те переменные, значения которым назначаются через оператор Set.
Для других же типов Set не нужен и в переменную значение заносится без этих нюансов.


Константы

Так же есть и иной вид «переменных» — константы. Это такая же переменная, только(как следует из её названия) — она не может быть изменена во время выполнения кода, т.к. является величиной постоянной и значение её назначается только один раз — перед выполнением кода.

Const sMyConst As String = "Имя моей программы"

Константам могут быть назначены данные тех же типов, что и для переменных, за исключением типа Object, т.к. Object это всегда ссылка на объект, который как правило обладает «динамическими»(т.е. обновляющимися) свойствами. А изменение для констант недопустимо.
Для дополнительной области видимости/жизни констант используется только Public. Если область видимости не указана, то константа будет доступна только из того модуля, в котором объявлена. Здесь обращаю внимание на то, что Dim уже не используется, т.к. Dim это идентификатор только для переменных. Пару важных отличий объявления констант от объявления переменных:

  • при объявлении константы необходимо обязательно указывать явно, что это константа ключевым словом Const
  • сразу в момент объявления необходимо назначить константе значение: = «Имя моей программы»

Во всем остальном объявление и применение констант идентично объявлению переменных. Коротко приведу пару примеров.
Если константа объявлена внутри процедуры:

Sub TestConst()
    Const sMyConst As String = "Имя моей программы"
    MsgBox sMyConst 'показываем сообщение с именем программы
End Sub

то она не может быть использована в другой процедуре:

Sub TestConst()
    Const sMyConst As String = "Имя моей программы"
    MsgBox sMyConst 'показываем сообщение с именем программы
End Sub
Sub TestConst2()
    MsgBox sMyConst 'вызовет ошибку Variable not defined
End Sub

Чтобы использовать одну константу во всех процедурах модуля(того, в котором она объявлена), необходимо объявить её в области объявлений:

Const sMyConst As String = "Имя моей программы"
Sub TestConst()
    MsgBox sMyConst 'показываем сообщение с именем программы
End Sub
Sub TestConst2()
    MsgBox sMyConst 'уже не вызовет ошибку Variable not defined
End Sub

Чтобы использовать одну константу во всех процедурах проекта(книги), необходимо объявить её как Public:

Public Const sMyConst As String = "Имя моей программы"
Sub TestConst()
    MsgBox sMyConst 'показываем сообщение с именем программы
End Sub
Sub TestConst2()
    MsgBox sMyConst 'не вызовет ошибку Variable not defined, даже если процедура в другом модуле
End Sub

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

Также см.:
Variable not defined или что такое Option Explicit и зачем оно нужно?
Что такое модуль? Какие бывают модули?
Что такое макрос и где его искать?
Отлов ошибок и отладка кода VBA


Статья помогла? Поделись ссылкой с друзьями!

  Плейлист   Видеоуроки


Поиск по меткам



Access
apple watch
Multex
Power Query и Power BI
VBA управление кодами
Бесплатные надстройки
Дата и время
Записки
ИП
Надстройки
Печать
Политика Конфиденциальности
Почта
Программы
Работа с приложениями
Разработка приложений
Росстат
Тренинги и вебинары
Финансовые
Форматирование
Функции Excel
акции MulTEx
ссылки
статистика

Like this post? Please share to your friends:
  • Переконвертировать odt в word
  • Переменная для текста в excel
  • Перекодировка текста в word
  • Переменная для имени файла excel
  • Перекодировать jpg в word онлайн