Время на прочтение
7 мин
Количество просмотров 312K
Приветствую всех.
В этом посте я расскажу, что такое VBA и как с ним работать в Microsoft Excel 2007/2010 (для более старых версий изменяется лишь интерфейс — код, скорее всего, будет таким же) для автоматизации различной рутины.
VBA (Visual Basic for Applications) — это упрощенная версия Visual Basic, встроенная в множество продуктов линейки Microsoft Office. Она позволяет писать программы прямо в файле конкретного документа. Вам не требуется устанавливать различные IDE — всё, включая отладчик, уже есть в Excel.
Еще при помощи Visual Studio Tools for Office можно писать макросы на C# и также встраивать их. Спасибо, FireStorm.
Сразу скажу — писать на других языках (C++/Delphi/PHP) также возможно, но требуется научится читать, изменять и писать файлы офиса — встраивать в документы не получится. А интерфейсы Microsoft работают через COM. Чтобы вы поняли весь ужас, вот Hello World с использованием COM.
Поэтому, увы, будем учить Visual Basic.
Чуть-чуть подготовки и постановка задачи
Итак, поехали. Открываем Excel.
Для начала давайте добавим в Ribbon панель «Разработчик». В ней находятся кнопки, текстовые поля и пр. элементы для конструирования форм.
Появилась вкладка.
Теперь давайте подумаем, на каком примере мы будем изучать VBA. Недавно мне потребовалось красиво оформить прайс-лист, выглядевший, как таблица. Идём в гугл, набираем «прайс-лист» и качаем любой, который оформлен примерно так (не сочтите за рекламу, пожалуйста):
То есть требуется, чтобы было как минимум две группы, по которым можно объединить товары (в нашем случае это будут Тип и Производитель — в таком порядке). Для того, чтобы предложенный мною алгоритм работал корректно, отсортируйте товары так, чтобы товары из одной группы стояли подряд (сначала по Типу, потом по Производителю).
Результат, которого хотим добиться, выглядит примерно так:
Разумеется, если смотреть прайс только на компьютере, то можно добавить фильтры и будет гораздо удобнее искать нужный товар. Однако мы хотим научится кодить и задача вполне подходящая, не так ли?
Кодим
Для начала требуется создать кнопку, при нажатии на которую будет вызываться наша програма. Кнопки находятся в панели «Разработчик» и появляются по кнопке «Вставить». Вам нужен компонент формы «Кнопка». Нажали, поставили на любое место в листе. Далее, если не появилось окно назначения макроса, надо нажать правой кнопкой и выбрать пункт «Назначить макрос». Назовём его FormatPrice. Важно, чтобы перед именем макроса ничего не было — иначе он создастся в отдельном модуле, а не в пространстве имен книги. В этому случае вам будет недоступно быстрое обращение к выделенному листу. Нажимаем кнопку «Новый».
И вот мы в среде разработки VB. Также её можно вызвать из контекстного меню командой «Исходный текст»/«View code».
Перед вами окно с заглушкой процедуры. Можете его развернуть. Код должен выглядеть примерно так:
Sub FormatPrice()End Sub
Напишем Hello World:
Sub FormatPrice()
MsgBox "Hello World!"
End Sub
И запустим либо щелкнув по кнопке (предварительно сняв с неё выделение), либо клавишей F5 прямо из редактора.
Тут, пожалуй, следует отвлечься на небольшой ликбез по поводу синтаксиса VB. Кто его знает — может смело пропустить этот раздел до конца. Основное отличие Visual Basic от Pascal/C/Java в том, что команды разделяются не ;, а переносом строки или двоеточием (:), если очень хочется написать несколько команд в одну строку. Чтобы понять основные правила синтаксиса, приведу абстрактный код.
Примеры синтаксиса
' Процедура. Ничего не возвращает
' Перегрузка в VBA отсутствует
Sub foo(a As String, b As String)
' Exit Sub ' Это значит "выйти из процедуры"
MsgBox a + ";" + b
End Sub' Функция. Вовращает Integer
Function LengthSqr(x As Integer, y As Integer) As Integer
' Exit Function
LengthSqr = x * x + y * y
End FunctionSub FormatPrice()
Dim s1 As String, s2 As String
s1 = "str1"
s2 = "str2"
If s1 <> s2 Then
foo "123", "456" ' Скобки при вызове процедур запрещены
End IfDim res As sTRING ' Регистр в VB не важен. Впрочем, редактор Вас поправит
Dim i As Integer
' Цикл всегда состоит из нескольких строк
For i = 1 To 10
res = res + CStr(i) ' Конвертация чего угодно в String
If i = 5 Then Exit For
Next iDim x As Double
x = Val("1.234") ' Парсинг чисел
x = x + 10
MsgBox xOn Error Resume Next ' Обработка ошибок - игнорировать все ошибки
x = 5 / 0
MsgBox xOn Error GoTo Err ' При ошибке перейти к метке Err
x = 5 / 0
MsgBox "OK!"
GoTo ne
Err:
MsgBox
"Err!"
ne:
On Error GoTo 0 ' Отключаем обработку ошибок
' Циклы бывает, какие захотите
Do While True
Exit DoLoop 'While True
Do 'Until False
Exit Do
Loop Until False
' А вот при вызове функций, от которых хотим получить значение, скобки нужны.
' Val также умеет возвращать Integer
Select Case LengthSqr(Len("abc"), Val("4"))
Case 24
MsgBox "0"
Case 25
MsgBox "1"
Case 26
MsgBox "2"
End Select' Двухмерный массив.
' Можно также менять размеры командой ReDim (Preserve) - см. google
Dim arr(1 to 10, 5 to 6) As Integer
arr(1, 6) = 8Dim coll As New Collection
Dim coll2 As Collection
coll.Add "item", "key"
Set coll2 = coll ' Все присваивания объектов должны производится командой Set
MsgBox coll2("key")
Set coll2 = New Collection
MsgBox coll2.Count
End Sub
Грабли-1. При копировании кода из IDE (в английском Excel) есь текст конвертируется в 1252 Latin-1. Поэтому, если хотите сохранить русские комментарии — надо сохранить крокозябры как Latin-1, а потом открыть в 1251.
Грабли-2. Т.к. VB позволяет использовать необъявленные переменные, я всегда в начале кода (перед всеми процедурами) ставлю строчку Option Explicit. Эта директива запрещает интерпретатору заводить переменные самостоятельно.
Грабли-3. Глобальные переменные можно объявлять только до первой функции/процедуры. Локальные — в любом месте процедуры/функции.
Еще немного дополнительных функций, которые могут пригодится: InPos, Mid, Trim, LBound, UBound. Также ответы на все вопросы по поводу работы функций/их параметров можно получить в MSDN.
Надеюсь, что этого Вам хватит, чтобы не пугаться кода и самостоятельно написать какое-нибудь домашнее задание по информатике. По ходу поста я буду ненавязчиво знакомить Вас с новыми конструкциями.
Кодим много и под Excel
В этой части мы уже начнём кодить нечто, что умеет работать с нашими листами в Excel. Для начала создадим отдельный лист с именем result (лист с данными назовём data). Теперь, наверное, нужно этот лист очистить от того, что на нём есть. Также мы «выделим» лист с данными, чтобы каждый раз не писать длинное обращение к массиву с листами.
Sub FormatPrice()
Sheets("result").Cells.Clear
Sheets("data").Activate
End Sub
Работа с диапазонами ячеек
Вся работа в Excel VBA производится с диапазонами ячеек. Они создаются функцией Range и возвращают объект типа Range. У него есть всё необходимое для работы с данными и/или оформлением. Кстати сказать, свойство Cells листа — это тоже Range.
Примеры работы с Range
Sheets("result").Activate
Dim r As Range
Set r = Range("A1")
r.Value = "123"
Set r = Range("A3,A5")
r.Font.Color = vbRed
r.Value = "456"
Set r = Range("A6:A7")
r.Value = "=A1+A3"
Теперь давайте поймем алгоритм работы нашего кода. Итак, у каждой строчки листа data, начиная со второй, есть некоторые данные, которые нас не интересуют (ID, название и цена) и есть две вложенные группы, к которым она принадлежит (тип и производитель). Более того, эти строки отсортированы. Пока мы забудем про пропуски перед началом новой группы — так будет проще. Я предлагаю такой алгоритм:
- Считали группы из очередной строки.
- Пробегаемся по всем группам в порядке приоритета (вначале более крупные)
- Если текущая группа не совпадает, вызываем процедуру AddGroup(i, name), где i — номер группы (от номера текущей до максимума), name — её имя. Несколько вызовов необходимы, чтобы создать не только наш заголовок, но и всё более мелкие.
- После отрисовки всех необходимых заголовков делаем еще одну строку и заполняем её данными.
Для упрощения работы рекомендую определить следующие функции-сокращения:
Function GetCol(Col As Integer) As String
GetCol = Chr(Asc("A") + Col)
End FunctionFunction GetCellS(Sheet As String, Col As Integer, Row As Integer) As Range
Set GetCellS = Sheets(Sheet).Range(GetCol(Col) + CStr(Row))
End FunctionFunction GetCell(Col As Integer, Row As Integer) As Range
Set GetCell = Range(GetCol(Col) + CStr(Row))
End Function
Далее определим глобальную переменную «текущая строчка»: Dim CurRow As Integer. В начале процедуры её следует сделать равной единице. Еще нам потребуется переменная-«текущая строка в data», массив с именами групп текущей предыдущей строк. Потом можно написать цикл «пока первая ячейка в строке непуста».
Глобальные переменные
Option Explicit ' про эту строчку я уже рассказывал
Dim CurRow As Integer
Const GroupsCount As Integer = 2
Const DataCount As Integer = 3
FormatPrice
Sub FormatPrice()
Dim I As Integer ' строка в data
CurRow = 1
Dim Groups(1 To GroupsCount) As String
Dim PrGroups(1 To GroupsCount) As String
Sheets(
"data").Activate
I = 2
Do While True
If GetCell(0, I).Value = "" Then Exit Do
' ...
I = I + 1
Loop
End Sub
Теперь надо заполнить массив Groups:
На месте многоточия
Dim I2 As Integer
For I2 = 1 To GroupsCount
Groups(I2) = GetCell(I2, I)
Next I2
' ...
For I2 = 1 To GroupsCount ' VB не умеет копировать массивы
PrGroups(I2) = Groups(I2)
Next I2
I = I + 1
И создать заголовки:
На месте многоточия в предыдущем куске
For I2 = 1 To GroupsCount
If Groups(I2) <> PrGroups(I2) Then
Dim I3 As Integer
For I3 = I2 To GroupsCount
AddHeader I3, Groups(I3)
Next I3
Exit For
End If
Next I2
Не забудем про процедуру AddHeader:
Перед FormatPrice
Sub AddHeader(Ty As Integer, Name As String)
GetCellS("result", 1, CurRow).Value = Name
CurRow = CurRow + 1
End Sub
Теперь надо перенести всякую информацию в result
For I2 = 0 To DataCount - 1
GetCellS("result", I2, CurRow).Value = GetCell(I2, I)
Next I2
Подогнать столбцы по ширине и выбрать лист result для показа результата
После цикла в конце FormatPrice
Sheets("Result").Activate
Columns.AutoFit
Всё. Можно любоваться первой версией.
Некрасиво, но похоже. Давайте разбираться с форматированием. Сначала изменим процедуру AddHeader:
Sub AddHeader(Ty As Integer, Name As String)
Sheets("result").Range("A" + CStr(CurRow) + ":C" + CStr(CurRow)).Merge
' Чтобы не заводить переменную и не писать каждый раз длинный вызов
' можно воспользоваться блоком With
With GetCellS("result", 0, CurRow)
.Value = Name
.Font.Italic = True
.Font.Name = "Cambria"
Select Case Ty
Case 1 ' Тип
.Font.Bold = True
.Font.Size = 16
Case 2 ' Производитель
.Font.Size = 12
End Select
.HorizontalAlignment = xlCenter
End With
CurRow = CurRow + 1
End Sub
Уже лучше:
Осталось только сделать границы. Тут уже нам требуется работать со всеми объединёнными ячейками, иначе бордюр будет только у одной:
Поэтому чуть-чуть меняем код с добавлением стиля границ:
Sub AddHeader(Ty As Integer, Name As String)
With Sheets("result").Range("A" + CStr(CurRow) + ":C" + CStr(CurRow))
.Merge
.Value = Name
.Font.Italic = True
.Font.Name = "Cambria"
.HorizontalAlignment = xlCenterSelect Case Ty
Case 1 ' Тип
.Font.Bold = True
.Font.Size = 16
.Borders(xlTop).Weight = xlThick
Case 2 ' Производитель
.Font.Size = 12
.Borders(xlTop).Weight = xlMedium
End Select
.Borders(xlBottom).Weight = xlMedium ' По убыванию: xlThick, xlMedium, xlThin, xlHairline
End With
CurRow = CurRow + 1
End Sub
Осталось лишь добится пропусков перед началом новой группы. Это легко:
В начале FormatPrice
Dim I As Integer ' строка в data
CurRow = 0 ' чтобы не было пропуска в самом начале
Dim Groups(1 To GroupsCount) As String
В цикле расстановки заголовков
If Groups(I2) <> PrGroups(I2) Then
CurRow = CurRow + 1
Dim I3 As Integer
В точности то, что и хотели.
Надеюсь, что эта статья помогла вам немного освоится с программированием для Excel на VBA. Домашнее задание — добавить заголовки «ID, Название, Цена» в результат. Подсказка: CurRow = 0 CurRow = 1.
Файл можно скачать тут (min.us) или тут (Dropbox). Не забудьте разрешить исполнение макросов. Если кто-нибудь подскажет человеческих файлохостинг, залью туда.
Спасибо за внимание.
Буду рад конструктивной критике в комментариях.
UPD: Перезалил пример на Dropbox и min.us.
UPD2: На самом деле, при вызове процедуры с одним параметром скобки можно поставить. Либо использовать конструкцию Call Foo(«bar», 1, 2, 3) — тут скобки нужны постоянно.
Содержание рубрики VBA Excel на сайте «Время не ждёт». Систематизация статей по тематическим группам для ускорения поиска нужной информации по заданной теме.
-
Знакомство с VBA Excel
- Начинаем программировать с нуля
- Памятка для начинающих
- Первая кнопка (для начинающих)
- Первая форма (для начинающих)
- Первая функция (для начинающих)
- Правильные имена переменных и процедур
- Свойства ячейки (объекта Range)
- Свойство ActiveCell объекта Application
- Свойство Selection объекта Application
-
Методы VBA Excel
- Метод Application.Goto
- Метод Application.InputBox (синтаксис, параметры)
- Метод Application.Intersect (пересечение диапазонов)
- Метод Application.OnKey
- Метод Application.OnTime
- Метод Application.Union (объединение диапазонов)
- Метод Controls.Add пользовательской формы
- Метод CreateTextFile (синтаксис, параметры)
- Метод Find объекта Range
- Метод FindNext объекта Range
- Метод Hyperlinks.Add (создание гиперссылки)
- Метод OpenTextFile (синтаксис, параметры)
- Метод Range.AutoFill (автозаполнение ячеек)
- Метод Range.Insert (вставка со сдвигом ячеек)
- Метод Range.Justify (переупорядочивание текста)
- Метод Range.PasteSpecial (специальная вставка)
- Метод Range.Replace (замена текста в ячейках)
- Метод Range.Show
- Метод WorksheetFunction.Match (поиск позиции)
- Метод WorksheetFunction.Sum – сумма аргументов
- Метод WorksheetFunction.SumIf
- Метод WorksheetFunction.SumIfs
- Метод WorksheetFunction.Transpose
- Метод WorksheetFunction.VLookup
- Методы Count, CountA и CountBlank
- Методы CountIf и CountIfs
- Методы очистки ячеек (Range.Clear и другие)
- Открытие сайта методом FollowHyperlink
- Удаление ячеек со сдвигом (Range.Delete)
-
Объект Range в VBA Excel
- Автоподбор высоты объединенной ячейки
- Автоподбор ширины объединенной ячейки
- Вставка пустой строки или столбца
- Вставка формулы в ячейку
- Выделенный диапазон ячеек (адрес, выбор, строки)
- Выравнивание текста в ячейке
- Вырезание, копирование и вставка ячеек (диапазонов)
- Диапазон ячеек и массив (обмен значениями)
- Диапазон ячеек пуст (определение)
- Объединение ячеек и его отмена
- Переменная диапазона ячеек (As Range)
- Программное создание границ ячеек
- Размер ячейки (высота строки, ширина столбца)
- Свойства Column и Columns объекта Range
- Свойства Row и Rows объекта Range
- Свойство Areas объекта Range
- Свойство Cells объекта Range
- Свойство End объекта Range
- Свойство Range.Characters
- Свойство Range.CurrentRegion
- Свойство Range.Hidden
- Свойство Range.Offset
- Свойство Range.Resize (синтаксис, примеры)
- Свойство Range.Text
- Свойство Range.WrapText (перенос текста)
- Цвет текста (шрифта) в ячейке
- Цвет ячейки (заливка, фон)
- Узор (рисунок) в ячейке
- Форматирование текста в ячейке (объект Font)
- Ячейки (обращение, запись, чтение, очистка)
-
Объекты VBA Excel
- Объект Collection (создание, методы, примеры)
- Объект Dictionary (свойства, методы, примеры)
- Объект DocumentProperties — свойства документа
- Объект FileSystemObject
- Объект PageSetup (параметры страницы)
- Объект TextStream (свойства и методы)
- Рабочая книга (открыть, создать новую, закрыть)
- Рабочий лист (обращение, переименование, скрытие)
- Рабочий лист (создание, копирование, удаление)
- Регулярные выражения (объекты, свойства, методы)
-
Операторы в VBA Excel
- Арифметические операторы
- Логические операторы
- Оператор Beep (одиночный звуковой сигнал)
- Оператор If…Then…Else и функция IIf
- Оператор On Error (обработка ошибок)
- Оператор Open (синтаксис, параметры)
- Оператор Select Case (синтаксис, примеры)
- Оператор SendKeys (имитация нажатия клавиш)
- Оператор With
- Операторы сравнения
- Операторы чтения и записи в файл
-
Переменные в VBA Excel
- Глобальная переменная
- Ключевое слово Me
- Количество измерений массива
- Массивы (одномерные, многомерные, динамические)
- Пользовательские типы данных (оператор Type)
- Тип данных Decimal
- Типы данных
-
Примеры кода VBA Excel
- Автоматическая запись текущей даты и времени
- Автоматическое заполнение интервала дат (периода)
- Бегущая, ползущая и танцующая строки
- Буфер обмена (копирование, вставка, очистка)
- Вставка рисунка в ячейку
- Выбор случайной ячейки из диапазона
- Генератор случайных чисел (Rnd и Randomize)
- Генерация документов (реестр, массив, бланк)
- Генерация документов и отчетов
- Добавление кнопки в контекстное меню
- Запуск макроса при изменении ячейки
- Изменение свойств пользовательской формы
- Имитация движения и кликов мыши
- Квадратные ячейки (тетрадные клетки)
- Копирование данных с одного листа на другой
- Копирование и перемещение файлов
- Копирование строк по условию
- Номер последней заполненной строки
- Определение координат элемента массива
- Отбор неповторяющихся значений
- Отбор уникальных значений с помощью Collection
- Отбор уникальных значений с помощью Dictionary
- Открыта или закрыта книга (проверка состояния)
- Открытие файла другой программы из кода VBA Excel
- Ошибки в таблице – поиск и исправление
- Парсинг сайтов, html-страниц и файлов
- Перебор листов в книге
- Перемещение листа и его отмена
- Переход к ячейке по адресу из формулы
- Переход по ссылке к ячейке в другой книге
- Поиск значения в таблице
- Поиск и выделение дубликатов в столбце
- Пользовательская автоформа (создание)
- Проверка существования листа
- Программное создание графика (диаграммы)
- Программное создание модуля
- Программное создание формы
- Работа с умной таблицей
- Расчет рабочего времени
- Сбор данных из открытых книг
- Секундомер в ячейке рабочего листа
- Смещение умной таблицы вниз
- Создание простого тестового задания
- Создание таблицы (умной, обычной)
- Создание файлов
- Создание, копирование, перемещение папок
- Сортировка массива
- Сортировка таблицы (диапазона)
- Сохранение книг и листов в PDF
- Сохранение массива в текстовый файл
- Список папок
- Список файлов в папке
- Сравнение прайс-листов
- Сумма прописью (код пользовательской функции)
- Удаление книги из собственного кода
- Удаление повторяющихся значений в диапазоне ячеек
- Удаление пустых строк
- Удаление файлов
- Учет расхода воды и других ресурсов
- Число Пи (значение)
- Экспорт и импорт пользовательской формы
-
Прочее в VBA Excel
- Включение режима конструктора
- Время работы макроса
- Знаки подстановки для шаблонов
- Кавычки в коде — двойные и ёлочки
- Колонтитулы
- Конвертация цвета из Long в RGB
- Копирование, перемещение и поворот фигур
- Объявление функций в 64-разрядных версиях
- Округление чисел (особенности)
- Открыть папку (каталог) в проводнике
- Параметры и аргументы
- Преобразование текста в число
- Работа с трехмерными диапазонами
- Работа с фигурами (Shapes)
- Свойства файла — вывод информации о файле
- Свойство Application.WindowState
- Смена кодировки UTF-8 на ANSI (Windows-1251)
- Смена раскладки клавиатуры
- Сохранение файла рабочей книги
- Сочетание клавиш для процедуры (макроса)
- Стандартная палитра из 56 цветов
- Стандартный диалог выбора файлов Application.GetOpenFilename
-
Работа с Word из кода VBA Excel
- Bookmarks – закладки в документе Word
- Вставка таблицы Excel в документ Word
- Редактирование документов Word
- Создание и открытие документов Word
- Создание таблиц в документе Word
- Управление приложением Word
-
Редактор VBA Excel
- Debug — отладка программы
- Вызов процедуры Sub из другой подпрограммы VBA
- Защита паролем и снятие защиты проекта VBA
- Личная книга макросов (создание, предназначение)
- Макросы (запись, запуск, пример)
- Модуль (импорт, экспорт, удаление)
- Модуль, процедура, форма
- Окно Immediate (отладка кода, вычисления)
- Перенос кода процедуры и текста на новую строку
-
События VBA Excel
- Событие Worksheet.SelectionChange
-
Функции в VBA Excel
- Изменение значений других ячеек из функции
- Пользовательская функция (синтаксис, компоненты)
- Проверка переменных и выражений
- Работа с текстом (функции)
- Удаление лишних пробелов (LTrim, RTrim, Trim)
- Функции Left, Mid, Right (вырезать часть строки)
- Функции Space, String и StrReverse
- Функция Beep API (звуковой сигнал, мелодия)
- Функция Choose (синтаксис, компоненты, примеры)
- Функция FileDateTime
- Функция Filter (фильтрация массива)
- Функция Format (синтаксис, параметры, примеры)
- Функция FreeFile
- Функция Hex
- Функция InputBox (синтаксис, параметры, значения)
- Функция InStr (синтаксис, параметры, примеры)
- Функция InStrRev (синтаксис, параметры, примеры)
- Функции Int и Fix
- Функция Join (синтаксис, параметры, значения)
- Функция MicroTimer
- Функция MsgBox (синтаксис, параметры, значения)
- Функция Replace (замена подстроки)
- Функция Shell
- Функция Split (синтаксис, параметры, значения)
- Функция StrComp (сравнение строк)
- Функция StrConv (смена регистра букв)
- Функция Switch (синтаксис, примеры)
- Функция Timer (примеры)
- Функция Val (примеры)
- Функция для вычисления факториала
- Функции для работы с датой
- Функция преобразования HTML-цвета в число
- Функции преобразования типов данных
-
Циклы в VBA Excel
- Цикл Do Until… Loop
- Цикл Do While… Loop
- Цикл For Each… Next
- Цикл For… Next
- Цикл While… Wend
- Циклы (краткое описание)
-
Элементы управления в VBA Excel
- ComboBox – заполнение поля со списком
- ListBox – заполнение списка данными
- Заполнение списка ComboBox по условию
- Маска ввода в TextBox
- Привязка события к элементу управления
- Программное раскрытие ComboBox
- Размеры и расположение элементов управления
- Свойства SelStart, SelLength, SelText (TextBox)
- Свойство Picture элементов управления
- Сочетания клавиш для кнопок
- Удаление элементов ActiveX с рабочего листа
- Удаление элементов управления формы с листа
- Элемент управления CheckBox (флажок)
- Элемент управления ComboBox (поле со списком)
- Элемент управления CommandButton (кнопка)
- Элемент управления DTPicker
- Элемент управления Frame (рамка)
- Элемент управления Image
- Элемент управления Label (метка, надпись)
- Элемент управления ListBox (список)
- Элемент управления MultiPage
- Элемент управления OptionButton (переключатель)
- Элемент управления RefEdit (редактор ссылок)
- Элемент управления ScrollBar (полоса прокрутки)
- Элемент управления SpinButton (счетчик)
- Элемент управления TabStrip
- Элемент управления TextBox (текстовое поле)
- Элемент управления ToggleButton (выключатель)
- Элемент управления TreeView (древовидная структура)
Introduction
This is a tutorial about writing code in Excel spreadsheets using Visual Basic for Applications (VBA).
Excel is one of Microsoft’s most popular products. In 2016, the CEO of Microsoft said «Think about a world without Excel. That’s just impossible for me.” Well, maybe the world can’t think without Excel.
- In 1996, there were over 30 million users of Microsoft Excel (source).
- Today, there are an estimated 750 million users of Microsoft Excel. That’s a little more than the population of Europe and 25x more users than there were in 1996.
We’re one big happy family!
In this tutorial, you’ll learn about VBA and how to write code in an Excel spreadsheet using Visual Basic.
Prerequisites
You don’t need any prior programming experience to understand this tutorial. However, you will need:
- Basic to intermediate familiarity with Microsoft Excel
- If you want to follow along with the VBA examples in this article, you will need access to Microsoft Excel, preferably the latest version (2019) but Excel 2016 and Excel 2013 will work just fine.
- A willingness to try new things
Learning Objectives
Over the course of this article, you will learn:
- What VBA is
- Why you would use VBA
- How to get set up in Excel to write VBA
- How to solve some real-world problems with VBA
Important Concepts
Here are some important concepts that you should be familiar with to fully understand this tutorial.
Objects: Excel is object-oriented, which means everything is an object — the Excel window, the workbook, a sheet, a chart, a cell. VBA allows users to manipulate and perform actions with objects in Excel.
If you don’t have any experience with object-oriented programming and this is a brand new concept, take a second to let that sink in!
Procedures: a procedure is a chunk of VBA code, written in the Visual Basic Editor, that accomplishes a task. Sometimes, this is also referred to as a macro (more on macros below). There are two types of procedures:
- Subroutines: a group of VBA statements that performs one or more actions
- Functions: a group of VBA statements that performs one or more actions and returns one or more values
Note: you can have functions operating inside of subroutines. You’ll see later.
Macros: If you’ve spent any time learning more advanced Excel functionality, you’ve probably encountered the concept of a “macro.” Excel users can record macros, consisting of user commands/keystrokes/clicks, and play them back at lightning speed to accomplish repetitive tasks. Recorded macros generate VBA code, which you can then examine. It’s actually quite fun to record a simple macro and then look at the VBA code.
Please keep in mind that sometimes it may be easier and faster to record a macro rather than hand-code a VBA procedure.
For example, maybe you work in project management. Once a week, you have to turn a raw exported report from your project management system into a beautifully formatted, clean report for leadership. You need to format the names of the over-budget projects in bold red text. You could record the formatting changes as a macro and run that whenever you need to make the change.
What is VBA?
Visual Basic for Applications is a programming language developed by Microsoft. Each software program in the Microsoft Office suite is bundled with the VBA language at no extra cost. VBA allows Microsoft Office users to create small programs that operate within Microsoft Office software programs.
Think of VBA like a pizza oven within a restaurant. Excel is the restaurant. The kitchen comes with standard commercial appliances, like large refrigerators, stoves, and regular ole’ ovens — those are all of Excel’s standard features.
But what if you want to make wood-fired pizza? Can’t do that in a standard commercial baking oven. VBA is the pizza oven.
Yum.
Why use VBA in Excel?
Because wood-fired pizza is the best!
But seriously.
A lot of people spend a lot of time in Excel as a part of their jobs. Time in Excel moves differently, too. Depending on the circumstances, 10 minutes in Excel can feel like eternity if you’re not able to do what you need, or 10 hours can go by very quickly if everything is going great. Which is when you should ask yourself, why on earth am I spending 10 hours in Excel?
Sometimes, those days are inevitable. But if you’re spending 8-10 hours everyday in Excel doing repetitive tasks, repeating a lot of the same processes, trying to clean up after other users of the file, or even updating other files after changes are made to the Excel file, a VBA procedure just might be the solution for you.
You should consider using VBA if you need to:
- Automate repetitive tasks
- Create easy ways for users to interact with your spreadsheets
- Manipulate large amounts of data
Getting Set Up to Write VBA in Excel
Developer Tab
To write VBA, you’ll need to add the Developer tab to the ribbon, so you’ll see the ribbon like this.
To add the Developer tab to the ribbon:
- On the File tab, go to Options > Customize Ribbon.
- Under Customize the Ribbon and under Main Tabs, select the Developer check box.
After you show the tab, the Developer tab stays visible, unless you clear the check box or have to reinstall Excel. For more information, see Microsoft help documentation.
VBA Editor
Navigate to the Developer Tab, and click the Visual Basic button. A new window will pop up — this is the Visual Basic Editor. For the purposes of this tutorial, you just need to be familiar with the Project Explorer pane and the Property Properties pane.
Excel VBA Examples
First, let’s create a file for us to play around in.
- Open a new Excel file
- Save it as a macro-enabled workbook (. xlsm)
- Select the Developer tab
- Open the VBA Editor
Let’s rock and roll with some easy examples to get you writing code in a spreadsheet using Visual Basic.
Example #1: Display a Message when Users Open the Excel Workbook
In the VBA Editor, select Insert -> New Module
Write this code in the Module window (don’t paste!):
Sub Auto_Open()
MsgBox («Welcome to the XYZ Workbook.»)
End Sub
Save, close the workbook, and reopen the workbook. This dialog should display.
Ta da!
How is it doing that?
Depending on your familiarity with programming, you may have some guesses. It’s not particularly complex, but there’s quite a lot going on:
- Sub (short for “Subroutine): remember from the beginning, “a group of VBA statements that performs one or more actions.”
- Auto_Open: this is the specific subroutine. It automatically runs your code when the Excel file opens — this is the event that triggers the procedure. Auto_Open will only run when the workbook is opened manually; it will not run if the workbook is opened via code from another workbook (Workbook_Open will do that, learn more about the difference between the two).
- By default, a subroutine’s access is public. This means any other module can use this subroutine. All examples in this tutorial will be public subroutines. If needed, you can declare subroutines as private. This may be needed in some situations. Learn more about subroutine access modifiers.
- msgBox: this is a function — a group of VBA statements that performs one or more actions and returns a value. The returned value is the message “Welcome to the XYZ Workbook.”
In short, this is a simple subroutine that contains a function.
When could I use this?
Maybe you have a very important file that is accessed infrequently (say, once a quarter), but automatically updated daily by another VBA procedure. When it is accessed, it’s by many people in multiple departments, all across the company.
- Problem: Most of the time when users access the file, they are confused about the purpose of this file (why it exists), how it is updated so often, who maintains it, and how they should interact with it. New hires always have tons of questions, and you have to field these questions over and over and over again.
- Solution: create a user message that contains a concise answer to each of these frequently answered questions.
Real World Examples
- Use the MsgBox function to display a message when there is any event: user closes an Excel workbook, user prints, a new sheet is added to the workbook, etc.
- Use the MsgBox function to display a message when a user needs to fulfill a condition before closing an Excel workbook
- Use the InputBox function to get information from the user
Example #2: Allow User to Execute another Procedure
In the VBA Editor, select Insert -> New Module
Write this code in the Module window (don’t paste!):
Sub UserReportQuery()
Dim UserInput As Long
Dim Answer As Integer
UserInput = vbYesNo
Answer = MsgBox(«Process the XYZ Report?», UserInput)
If Answer = vbYes Then ProcessReport
End Sub
Sub ProcessReport()
MsgBox («Thanks for processing the XYZ Report.»)
End Sub
Save and navigate back to the Developer tab of Excel and select the “Button” option. Click on a cell and assign the UserReportQuery macro to the button.
Now click the button. This message should display:
Click “yes” or hit Enter.
Once again, tada!
Please note that the secondary subroutine, ProcessReport, could be anything. I’ll demonstrate more possibilities in example #3. But first…
How is it doing that?
This example builds on the previous example and has quite a few new elements. Let’s go over the new stuff:
- Dim UserInput As Long: Dim is short for “dimension” and allows you to declare variable names. In this case, UserInput is the variable name and Long is the data type. In plain English, this line means “Here’s a variable called “UserInput”, and it’s a Long variable type.”
- Dim Answer As Integer: declares another variable called “Answer,” with a data type of Integer. Learn more about data types here.
- UserInput = vbYesNo: assigns a value to the variable. In this case, vbYesNo, which displays Yes and No buttons. There are many button types, learn more here.
- Answer = MsgBox(“Process the XYZ Report?”, UserInput): assigns the value of the variable Answer to be a MsgBox function and the UserInput variable. Yes, a variable within a variable.
- If Answer = vbYes Then ProcessReport: this is an “If statement,” a conditional statement, which allows us to say if x is true, then do y. In this case, if the user has selected “Yes,” then execute the ProcessReport subroutine.
When could I use this?
This could be used in many, many ways. The value and versatility of this functionality is more so defined by what the secondary subroutine does.
For example, maybe you have a file that is used to generate 3 different weekly reports. These reports are formatted in dramatically different ways.
- Problem: Each time one of these reports needs to be generated, a user opens the file and changes formatting and charts; so on and so forth. This file is being edited extensively at least 3 times per week, and it takes at least 30 minutes each time it’s edited.
- Solution: create 1 button per report type, which automatically reformats the necessary components of the reports and generates the necessary charts.
Real World Examples
- Create a dialog box for user to automatically populate certain information across multiple sheets
- Use the InputBox function to get information from the user, which is then populated across multiple sheets
Example #3: Add Numbers to a Range with a For-Next Loop
For loops are very useful if you need to perform repetitive tasks on a specific range of values — arrays or cell ranges. In plain English, a loop says “for each x, do y.”
In the VBA Editor, select Insert -> New Module
Write this code in the Module window (don’t paste!):
Sub LoopExample()
Dim X As Integer
For X = 1 To 100
Range(«A» & X).Value = X
Next X
End Sub
Save and navigate back to the Developer tab of Excel and select the Macros button. Run the LoopExample macro.
This should happen:
Etc, until the 100th row.
How is it doing that?
- Dim X As Integer: declares the variable X as a data type of Integer.
- For X = 1 To 100: this is the start of the For loop. Simply put, it tells the loop to keep repeating until X = 100. X is the counter. The loop will keep executing until X = 100, execute one last time, and then stop.
- Range(«A» & X).Value = X: this declares the range of the loop and what to put in that range. Since X = 1 initially, the first cell will be A1, at which point the loop will put X into that cell.
- Next X: this tells the loop to run again
When could I use this?
The For-Next loop is one of the most powerful functionalities of VBA; there are numerous potential use cases. This is a more complex example that would require multiple layers of logic, but it communicates the world of possibilities in For-Next loops.
Maybe you have a list of all products sold at your bakery in Column A, the type of product in Column B (cakes, donuts, or muffins), the cost of ingredients in Column C, and the market average cost of each product type in another sheet.
You need to figure out what should be the retail price of each product. You’re thinking it should be the cost of ingredients plus 20%, but also 1.2% under market average if possible. A For-Next loop would allow you to do this type of calculation.
Real World Examples
- Use a loop with a nested if statement to add specific values to a separate array only if they meet certain conditions
- Perform mathematical calculations on each value in a range, e.g. calculate additional charges and add them to the value
- Loop through each character in a string and extract all numbers
- Randomly select a number of values from an array
Conclusion
Now that we’ve talked about pizza and muffins and oh-yeah, how to write VBA code in Excel spreadsheets, let’s do a learning check. See if you can answer these questions.
- What is VBA?
- How do I get set up to start using VBA in Excel?
- Why and when would you use VBA?
- What are some problems I could solve with VBA?
If you have a fair idea of how to you could answer these questions, then this was successful.
Whether you’re an occasional user or a power user, I hope this tutorial provided useful information about what can be accomplished with just a bit of code in your Excel spreadsheets.
Happy coding!
Learning Resources
- Excel VBA Programming for Dummies, John Walkenbach
- Get Started with VBA, Microsoft Documentation
- Learning VBA in Excel, Lynda
A bit about me
I’m Chloe Tucker, an artist and developer in Portland, Oregon. As a former educator, I’m continuously searching for the intersection of learning and teaching, or technology and art. Reach out to me on Twitter @_chloetucker and check out my website at chloe.dev.
Learn to code for free. freeCodeCamp’s open source curriculum has helped more than 40,000 people get jobs as developers. Get started