Пользовательские формы (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 без сохранения. Проверь: если нажать «Сохранить», не выбрав город, данные не должны попасть на лист.

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

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