До сих пор ввод данных для макросов шёл через ячейки листа. Но иногда удобнее не заставлять человека искать нужную ячейку и не путать его пустыми клетками без подписей, а показать окошко с понятными полями — как в обычной программе. Такое окошко в 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 нужна пользовательская форма, если можно попросить пользователя вписать данные прямо в ячейки листа?
Подсказка: Подумай, что случается, если попросить коллегу «впиши в A1, а телефон в B1».
Онлайн-проверка ответа появится позже
Контрольный вопрос. Через какое меню редактора VBA открывают панель элементов управления (Toolbox) для формы?
Подсказка: Саму форму добавляют через Insert, а вот панель с элементами — через другое меню.
Онлайн-проверка ответа появится позже
Контрольный вопрос. Как называется по умолчанию ПЕРВОЕ текстовое поле, добавленное на форму?
Подсказка: Название элемента + порядковый номер, начиная с единицы.
Онлайн-проверка ответа появится позже
Контрольный вопрос. Что нужно сделать в конструкторе формы, чтобы у элемента (например, кнопки) сразу появилась заготовка обработчика события?
Подсказка: Тот же жест, что открывает код модуля листа по двойному клику на его ярлыке.
Онлайн-проверка ответа появится позже
Контрольный вопрос. Пользователь напечатал что-то в текстовое поле TextBox1 и нажал кнопку. Куда попадёт напечатанное значение?
Исходный код для этого задания:
Private Sub CommandButton1_Click() Range("A1").Value = TextBox1.Value End SubПодсказка: Посмотри, что стоит СЛЕВА от знака равно в этой строке кода — туда и записывается значение.
Онлайн-проверка ответа появится позже
Контрольный вопрос. Чем показ формы через UserForm1.Show отличается от её выгрузки через Unload Me?
Подсказка: Дальше в теме есть прямой ответ на похожий вопрос про поля формы после Hide — сравни, что там сказано, с тем, что делает Unload.
Онлайн-проверка ответа появится позже
Контрольный вопрос. Форму спрятали командой Me.Hide, не выгружая. Что произойдёт со значениями в её текстовых полях, если показать форму снова через Show?
Подсказка: Hide не выгружает форму из памяти — в отличие от Unload.
Онлайн-проверка ответа появится позже
Контрольный вопрос. Какой командой заполняют список (ListBox) или поле со списком (ComboBox) вариантами — например, названиями городов?
Подсказка: Название команды прямо говорит, что она делает — добавляет один пункт.
Онлайн-проверка ответа появится позже
Контрольный вопрос. В каком событии формы обычно заполняют ComboBox или ListBox вариантами при первом открытии?
Подсказка: Нужно событие, которое срабатывает само, один раз, ещё до того, как пользователь что-то нажал.
Онлайн-проверка ответа появится позже
Контрольный вопрос. Как правильно проверить, выбрал ли пользователь хоть один вариант в 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 код не дойдёт.
✅ Готово, если: ты ввёл(а) верный ответ, и онлайн-проверка его приняла.
Онлайн-проверка ответа появится позже
Контрольный вопрос. Как называется элемент управления — переключатель, из нескольких вариантов которого можно выбрать только один?
Подсказка: Не путай с элементом, где можно отметить сразу несколько вариантов галочками.
Онлайн-проверка ответа появится позже
Контрольный вопрос. Отметь все верные утверждения о пользовательских формах в VBA (не менее двух вариантов).
Выберите все верные варианты.
Подсказка: Два утверждения приписывают элементам и форме то, чего на самом деле нет.
Онлайн-проверка ответа появится позже
Итог
Итог. Форму добавляют через 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 без сохранения. Проверь: если нажать «Сохранить», не выбрав город, данные не должны попасть на лист.
← Назад · ↑ В начало урока · ⌂ В начало курса · Вперёд: Капстоун главы →
