VBA (Visual Basic for Applications) – встраиваемый язык программирования семейства Visual Basic, предназначенный для автоматизации и расширения приложений Microsoft Office (Excel, Word, PowerPoint, Access, Outlook). С точки зрения информатики VBA интересен как строго типизированный императивный язык с процедурами и функциями, модулями, типами данных, массивами, словарями, обработкой исключений и объектной моделью приложений. Он позволяет быстро реализовывать алгоритмы, анализировать данные табличного вида, строить модели и визуализировать результаты.
Связь с ЕГЭ. В заданиях ЕГЭ по информатике регулярно проверяются: владение переменными и типами, понимание алгоритмов обработки массивов и строк, циклы, ветвления, оценка сложности, корректность работы с индексами, аккуратность входа/выхода. VBA служит удобной «практической лабораторией» для отработки тех же идей: можно формально запрограммировать псевдокод ЕГЭ, протестировать граничные случаи и измерить эффективность.
Где живёт код
Код VBA хранится в модулях внутри документа Office:
Стандартные модули (Module1, Module2, …): процедуры и функции верхнего уровня.
Модули листов/документов (например, Sheet1, ThisWorkbook): обработчики событий.
Модули классов: определение собственных типов-объектов (инкапсуляция состояния и методов).
UserForm: формы с элементами управления (кнопки, поля, списки).
Запуск и отладка
VBA-редактор (Alt+F11) предоставляет:
Immediate Window (? выражение) – мгновенные вычисления и вызовы.
Locals/Watch – наблюдение за переменными.
Step Into/Over/Out – пошаговая отладка.
Breakpoints – точки останова.
Правило 1 (строгая дисциплина объявлений). Всегда включайте в начале каждого модуля директиву:
Option Explicit
Это требует явного объявления всех переменных (иначе неявный Variant), предотвращая трудноуловимые опечатки.
Базовые типы
Byte (0..255), Integer (−32768..32767), Long (32-бит целое), LongLong (64-бит, 64-разрядные версии),
Single, Double (вещественные), Currency (фиксированная точка, денежные расчёты),
Boolean, Date, String,
Ссылочные: Object, Variant (универсальный контейнер), пользовательские Class.
Правило 2 (минимизация Variant). Используйте точные типы. Variant удобен, но дороже по памяти и времени и скрывает ошибки приведения типов.
Объявление и инициализация
Dim i As Long, s As String
i = 0: s = «»
Константы:
Const PI As Double = 3.14159265358979
Арифметика и строковые операции
Целочисленное деление: \
Остаток: Mod
Возведение в степень: ^
Конкатенация строк: & (предпочтительнее + во избежание неоднозначностей)
Формула длины сцепления:
Len(A & B) = Len(A) + Len(B)
Ветвления
If условие Then
...
ElseIf другоеУсловие The
...
Else
...
End If
Циклы
С параметром:
Dim i As Long
For i = 1 To n Step 1
...
Next i
Пока/До:
Do While условие
...
Loop
Итерация по коллекции:
Dim c As Variant
For Each c In CollectionObject
...
Next c
Правило 3 (инвариант цикла). Перед началом цикла формулируйте и проверяйте инвариант – свойство, истинное на каждой итерации. Это облегчает доказательство корректности (актуально для задач ЕГЭ).

Процедура и функция
Sub ПроцедураИмя(ByVal a As Long, ByRef b As Double)
' без возврата значения
End Sub
Function ИмяФункции(ByVal s As String) As Long
ИмяФункции = Len(s)
End Function
ByVal vs ByRef
ByVal – передача копии значения (изменения внутри не влияют на аргумент).
ByRef – передача по ссылке (процедура может менять исходную переменную).
Правило 4 (явность семантики). Явно указывайте ByVal/ByRef у каждого параметра. Это исключает недоразумения и повышает предсказуемость кода.
Опциональные параметры и значения по умолчанию
Sub Foo(ByVal x As Long, Optional ByVal sep As String = «,»)
...
End Sub
Правило 5 (минимальная область). Декларируйте переменные в самом узком возможном блоке. Это снижает связанность и риск побочных эффектов.
Статические и динамические массивы
Dim A(1 To 10) As Double ' статический
Dim B() As Long: ReDim B(0 To n) ' динамический
Опция базового индекса:
Option Base 0 ' или 1
Рекомендуется явно задавать границы при ReDim и не полагаться на Option Base.
Правило 6 (границы и инварианты). При работе с массивами всегда фиксируйте допустимый диапазон индексов и проверяйте его в сложных циклах.
Многомерные массивы
Dim M(1 To R, 1 To C) As Double
Адресная формула для 2D (логическая, копируемая в комментарий/док):
offset(i, j) = (i - LBi) * (UBj - LBj + 1) + (j - LBj)
где LBi/UBi – нижняя/верхняя границы измерений.
Коллекции и словари
Collection – упорядоченный список объектов/значений.
Scripting.Dictionary – хеш-словарь (потребуется подключение библиотеки Microsoft Scripting Runtime).
Dim data As Variant
data = Range(«A1:D10000»).Value2
' ... обработка в памяти ...
Range(«A1:D10000»).Value2 = data
Правило 7 (минимизировать обращения к объектной модели). Считывайте диапазоны целиком в массив, обрабатывайте в памяти, записывайте обратно. Это на порядки быстрее, чем проход по ячейкам.
Обработка ошибок
On Error GoTo EH
' ... основной код ...
Exit Sub
EH:
MsgBox «Ошибка: » & Err.Number & « – » & Err.Description
Правило 8 (узкие зоны обработки). Оборачивайте в обработчик только потенциально опасные участки (I/O, преобразования), а не весь модуль.
Контракты (пред- и постусловия)
В начале процедуры проверяйте корректность аргументов:
If n < 0 Then Err.Raise 5, , «n должно быть неотрицательным»
Это повышает надёжность и упрощает отладку.
Частые приёмы оптимизации в Excel/VBA:
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Application.EnableEvents = False
' ... массовые операции ...
Application.EnableEvents = True
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
Правило 9 (восстановление состояния). Всегда возвращайте настройки приложения в исходное состояние в блоке Finally-эквиваленте (через обработчик ошибок/On Error).
Избегайте Select/Activate; используйте полные ссылки (Worksheets(«Лист1»).Range(«A1»)).
Упражнение 1. Линейная обработка таблицы (инвариант и сложность)
В диапазоне A2:A100000 – целые. Напишите функцию CountPositivesRng(rng As Range) As Long, которая возвращает число положительных элементов.
Требования:
Упражнение 2. Строки и нормализация ввода
Реализуйте функцию NormalizeName(ByVal s As String) As String, которая:
– обрезает пробелы по краям;
– сжимает последовательности внутренних пробелов до одного;
– приводит первую букву каждого слова к верхнему регистру, остальные к нижнему.
Укажите, какие встроенные функции строк вы использовали и почему. Докажите корректность на граничных случаях: пустая строка, один символ, множественные пробелы, дефисы.
Упражнение 3. Сумма по подпрямоугольнику (двумерный массив)
В листе Лист1 задана матрица R x C целых чисел, начиная с A1. Напишите процедуру, которая строит вспомогательную таблицу двумерных префиксных сумм S того же размера (записать на Лист2, начиная с A1).
Формулы для копирования в комментарии:
S(i, j) = A(i, j) + S(i-1, j) + S(i, j-1) - S(i-1, j-1)
Sum(x1..x2, y1..y2) = S(x2, y2) - S(x1-1, y2) - S(x2, y1-1) + S(x1-1, y1-1)
Поясните порядок обхода и обработку краёв (нулевая рамка).
Упражнение 4. Оптимизация ввода-вывода (сравнительный эксперимент)
Сравните время выполнения двух реализаций подсчёта суммы диапазона A1:A200000:
а) Поэлементный цикл по ячейкам листа.
б) Чтение диапазона в массив Variant и суммирование в памяти.
Зафиксируйте экспериментальные условия (выключение ScreenUpdating, Calculation) и прокомментируйте различие во времени. Укажите, почему подход (б) масштабируется лучше.
Упражнение 5. Контракты и обработка ошибок
Напишите процедуру импорта CSV-файла в активный лист:
Sub ImportCsv(ByVal path As String, ByVal delimiter As String)
Требования:
– предусловия: файл существует; разделитель непустой;
– постусловия: данные загружены в прямоугольный диапазон без «лестницы»;
– обработка ошибок: недоступный файл, некорректная кодировка, строки разной длины;
– восстановление ScreenUpdating/Calculation/EnableEvents при любом исходе.
Опишите в комментариях стратегию разбиения строки на поля и политику обработки кавычек.
VBA – практичный язык для строгой отработки фундаментальных идей информатики: типы, область видимости, функции и передача аргументов, массивы и алгоритмы над ними, строки и нормализация данных, обработка ошибок, оценка сложности и оптимизация. Следование изложенным правилам (явные объявления, минимизация обращений к объектной модели, аккуратные границы массивов, локализованная обработка ошибок) делает программы предсказуемыми, быстрыми и корректными. Для подготовки к ЕГЭ это означает: уверенный перенос псевдокода в рабочий код, умение доказывать корректность через инварианты и оценивать стоимость решений по времени и памяти.