Пользовательские формы (UserForm)

До сих пор ввод данных для макросов шёл через ячейки листа. Но иногда удобнее не заставлять человека искать нужную ячейку и не путать его пустыми клетками без подписей, а показать окошко с понятными полями — как в обычной программе. Такое окошко в VBA называется пользовательской формой (UserForm): своё окно с текстовыми полями, кнопками и списками, которое сам же и обрабатываешь кодом.

К концу темы ты сможешь:
— добавить в проект форму и разместить на ней текстовое поле, кнопку и список;
— написать обработчик нажатия кнопки, который переносит данные из формы на лист;
— объяснить разницу между показом (Show), скрытием (Hide) и выгрузкой формы (Unload);
— заполнить список (ComboBox/ListBox) вариантами и правильно проверить, выбрал ли пользователь что-то;
— проверить текстовое поле на пустоту, прежде чем принимать данные с формы.

Вспомни: в теме 5.2 мы писали свои процедуры Sub. Обработчик нажатия кнопки — это тоже Sub, просто редактор форм создаёт его автоматически и сам решает, когда его вызвать: в момент клика.

Зачем нужна форма

Попроси коллегу «впиши имя в A1, а телефон в B1» — и рано или поздно кто-то впишет не туда или сотрёт заголовок. Форма решает это иначе: на экране появляется окно с понятными подписями «Имя», «Телефон» и кнопкой «Сохранить» — вписать данные не в то место физически невозможно, а код за кнопкой сам решает, что и куда положить, и может по пути проверить, не забыли ли поле пустым.

Как добавить форму и элементы управления

Форму добавляют через редактор VBA: Insert → UserForm — появляется пустое окно-заготовка. Чтобы разместить на нём элементы, открывают панель инструментов — View → Toolbox — и перетаскивают нужный элемент прямо на форму мышкой.

TOOLBOX (панель элементов)              UserForm1 (окно-заготовка)
┌─────────────────┐                     ┌───────────────────────────┐
│ [ab] TextBox     │                     │  Имя:    [____________]   │  <- TextBox1
│ [A]  Label       │   перетащить  ──►   │                            │
│ [OK] CommandButt.│                     │  [ Сохранить ]             │  <- CommandButton1
│ ( ) OptionButton │                     │                            │
│ [▼] ComboBox     │                     └───────────────────────────┘
└─────────────────┘

Самые ходовые элементы: TextBox — поле для ввода текста или числа, Label — просто подпись, ничего не вводит; CommandButton — кнопка; OptionButton — переключатель, из нескольких вариантов можно выбрать только один; ListBox — список вариантов, видимых сразу; ComboBox — «поле со списком», раскрывается по клику. Каждый новый элемент получает имя по счёту: первое текстовое поле — TextBox1, вторая кнопка — CommandButton2, и так далее; имя потом можно поменять на понятное в окне свойств.

Событие нажатия кнопки, перенос данных и управление показом формы

Чтобы код заработал по нажатию кнопки, не нужно искать событие вручную: дважды щёлкни по кнопке прямо на форме в режиме конструктора — редактор сам создаст заготовку процедуры и сразу откроет её.

Private Sub CommandButton1_Click()
    Range("A1").Value = TextBox1.Value
End Sub

Здесь TextBox1.Value — это то, что пользователь напечатал в поле; строка кода просто кладёт это значение в ячейку A1 листа. Так же легко можно писать данные в следующую свободную строку таблицы, менять формат, запускать проверку — всё как в обычном макросе, только источник данных не лист, а форма.

Показывают форму командой UserForm1.Show — обычно её вызывают из макроса на листе или из кнопки в самой книге. Внутри кода формы для ссылки на саму себя используют слово Me. У формы есть два разных способа «убрать её с экрана», и разница между ними важна: Me.Hide просто прячет окно, но форма остаётся в памяти со всеми введёнными значениями — её можно показать снова, и поля не очистятся. Unload Me выгружает форму из памяти совсем: если показать её заново, все поля будут пустыми, как при первом открытии.

UserForm1.Show    -> форма появляется на экране

Me.Hide           -> форма СПРЯТАНА, но жива в памяти.
                     Значения в полях сохранены. Show снова покажет форму
                     с теми же данными, что были введены.

Unload Me         -> форма выгружена из памяти ПОЛНОСТЬЮ.
                     Следующий Show создаст её заново, поля пустые.

Список и поле со списком: AddItem и проверка данных

ListBox и ComboBox не заполняются вручную построчно — варианты добавляют кодом, командой AddItem, обычно в событии UserForm_Initialize — оно срабатывает автоматически один раз, в момент, когда форма только открывается.

Private Sub UserForm_Initialize()
    ComboBox1.AddItem "Москва"
    ComboBox1.AddItem "Казань"
    ComboBox1.AddItem "Томск"
End Sub

Перед тем как принимать данные с формы, их принято проверять. Для текстового поля проверка простая — сравнить с пустой строкой: If TextBox1.Value = «» Then. А вот для списка так не сработает: у ListBox и ComboBox проверяют не Value, а ListIndex — номер выбранного варианта по счёту (начиная с 0). Если пользователь вообще ничего не выбрал, ListIndex равен -1.

Private Sub CommandButton1_Click()
    If TextBox1.Value = "" Then
        MsgBox "Заполните имя"
        Exit Sub
    End If
    If ComboBox1.ListIndex = -1 Then
        MsgBox "Выберите город"
        Exit Sub
    End If
    Range("A1").Value = TextBox1.Value
    Range("B1").Value = ComboBox1.Value
End Sub

Команда Exit Sub сразу останавливает выполнение процедуры — если поле не заполнено, код дальше строки с MsgBox просто не пойдёт, и данные на лист не попадут, пока пользователь не исправит форму.

Проверь себя

Контрольный вопрос. Зачем в VBA нужна пользовательская форма, если можно попросить пользователя вписать данные прямо в ячейки листа?

Аформа упорядочивает ввод: понятные подписи, готовые кнопки и списки, проверка данных до того, как они попадут на лист
Бформа — единственный способ вообще ввести данные в Excel из VBA
Вформа нужна только для того, чтобы код VBA работал быстрее
Гформа заменяет собой лист Excel целиком

Подсказка: Подумай, что случается, если попросить коллегу «впиши в A1, а телефон в B1».

Онлайн-проверка ответа появится позже

Контрольный вопрос. Через какое меню редактора VBA открывают панель элементов управления (Toolbox) для формы?

АView → Toolbox
БInsert → Toolbox
ВDebug → Toolbox
ГFormat → Toolbox

Подсказка: Саму форму добавляют через Insert, а вот панель с элементами — через другое меню.

Онлайн-проверка ответа появится позже

Контрольный вопрос. Как называется по умолчанию ПЕРВОЕ текстовое поле, добавленное на форму?

АTextBox1
БTextBox0
ВText1
ГBox1

Подсказка: Название элемента + порядковый номер, начиная с единицы.

Онлайн-проверка ответа появится позже

Контрольный вопрос. Что нужно сделать в конструкторе формы, чтобы у элемента (например, кнопки) сразу появилась заготовка обработчика события?

Адважды щёлкнуть по элементу в режиме конструктора
Бперетащить элемент на панель Immediate
Впереименовать элемент в окне свойств
Гпоставить точку останова на форме

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

Онлайн-проверка ответа появится позже

Контрольный вопрос. Пользователь напечатал что-то в текстовое поле TextBox1 и нажал кнопку. Куда попадёт напечатанное значение?

Исходный код для этого задания:

Private Sub CommandButton1_Click()
    Range("A1").Value = TextBox1.Value
End Sub
Ав ячейку A1 листа
Бобратно в TextBox1 без изменений
Вв буфер обмена Windows
Гв первую свободную строку таблицы

Подсказка: Посмотри, что стоит СЛЕВА от знака равно в этой строке кода — туда и записывается значение.

Онлайн-проверка ответа появится позже

Контрольный вопрос. Чем показ формы через UserForm1.Show отличается от её выгрузки через Unload Me?

АShow выводит форму на экран, Unload Me убирает форму из памяти совсем
БShow и Unload Me делают одно и то же, просто разными словами
ВShow работает только один раз за сеанс, Unload Me — сколько угодно
ГUnload Me показывает форму, а Show её скрывает

Подсказка: Дальше в теме есть прямой ответ на похожий вопрос про поля формы после Hide — сравни, что там сказано, с тем, что делает Unload.

Онлайн-проверка ответа появится позже

Контрольный вопрос. Форму спрятали командой Me.Hide, не выгружая. Что произойдёт со значениями в её текстовых полях, если показать форму снова через Show?

Аони сохранятся такими же, какими были до скрытия
Бвсе поля станут пустыми, как при первом открытии
ВExcel покажет ошибку — Hide нельзя сочетать с повторным Show
Гполя заполнятся значениями по умолчанию из UserForm_Initialize

Подсказка: Hide не выгружает форму из памяти — в отличие от Unload.

Онлайн-проверка ответа появится позже

Контрольный вопрос. Какой командой заполняют список (ListBox) или поле со списком (ComboBox) вариантами — например, названиями городов?

АAddItem
БAdd
ВInsert
ГSetValue

Подсказка: Название команды прямо говорит, что она делает — добавляет один пункт.

Онлайн-проверка ответа появится позже

Контрольный вопрос. В каком событии формы обычно заполняют ComboBox или ListBox вариантами при первом открытии?

АUserForm_Initialize
БCommandButton1_Click
ВWorkbook_Open
ГUserForm_Close

Подсказка: Нужно событие, которое срабатывает само, один раз, ещё до того, как пользователь что-то нажал.

Онлайн-проверка ответа появится позже

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

Апроверить ListBox1.ListIndex — если он равен -1, ничего не выбрано
Бпроверить ListBox1.Value так же, как у обычного TextBox
Впроверить, пуст ли сам список вариантов
Гу ListBox всегда что-то выбрано по умолчанию, проверка не нужна

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

Онлайн-проверка ответа появится позже

Задание. Пользователь нажал кнопку, оставив текстовое поле пустым. Попадёт ли что-нибудь в ячейку A1? Ответь одним словом: да или нет.

Исходный код для этого задания:

Private Sub CommandButton1_Click()
    If TextBox1.Value = "" Then
        MsgBox "Заполните имя"
        Exit Sub
    End If
    Range("A1").Value = TextBox1.Value
End Sub

Подсказка: Exit Sub останавливает процедуру сразу после MsgBox — до строки с Range код не дойдёт.

✅ Готово, если: ты ввёл(а) верный ответ, и онлайн-проверка его приняла.

Онлайн-проверка ответа появится позже

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

АOptionButton
БCheckBox
ВTextBox
ГLabel

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

Онлайн-проверка ответа появится позже

Контрольный вопрос. Отметь все верные утверждения о пользовательских формах в VBA (не менее двух вариантов).

Выберите все верные варианты.

Аформу добавляют в проект через Insert → UserForm
Бэлементы на форму перетаскивают из панели Toolbox
ВLabel — это поле для ввода текста пользователем
Гдвойной клик по элементу в конструкторе создаёт заготовку обработчика события
Дформу нельзя показать больше одного раза за весь сеанс работы

Подсказка: Два утверждения приписывают элементам и форме то, чего на самом деле нет.

Онлайн-проверка ответа появится позже

Итог

Итог. Форму добавляют через Insert → UserForm, элементы перетаскивают из панели View → Toolbox: TextBox для ввода, Label для подписи, CommandButton для кнопки, OptionButton для взаимоисключающего выбора, ListBox/ComboBox для списка вариантов. Двойной клик по элементу создаёт заготовку обработчика события. Show выводит форму на экран; Me.Hide прячет её, сохраняя данные в памяти; Unload Me выгружает форму совсем, и при повторном показе поля будут пустыми. Списки заполняют командой AddItem, обычно в UserForm_Initialize. Перед тем как принимать данные, текстовое поле проверяют на пустую строку, а список — на ListIndex = -1; Exit Sub останавливает обработчик, если проверка не прошла.

Практика (необязательная)

Задание для практики. Создай форму «Новый заказ» с полем ФИО (TextBox), полем со списком «Город» (ComboBox, заполни через UserForm_Initialize тремя городами), полем «Сумма заказа» (TextBox) и двумя кнопками — «Сохранить» и «Отмена». По кнопке «Сохранить»: проверь, что ФИО не пустое и город выбран (иначе MsgBox и Exit Sub), затем запиши все три значения в следующую свободную строку таблицы на листе. По кнопке «Отмена» — просто Unload Me без сохранения. Проверь: если нажать «Сохранить», не выбрав город, данные не должны попасть на лист.

← Назад · ↑ В начало урока · ⌂ В начало курса · Вперёд: Капстоун главы →

Школа Виктора Комлева