Introduction to UserForms
Свайпніть щоб показати меню
UserForms мають обмежену або відсутню функціональність у Excel для Mac — VBA IDE на Mac не підтримує повноцінне проєктування UserForm у багатьох версіях, що може спричинити саме таку незрозумілу поведінку.
MsgBox та InputBox підходять для простих питань так/ні та однорядкових відповідей, але для додавання клієнта зазвичай потрібно кілька полів одночасно — назва компанії, контактна особа, місто, статус. Для цього використовується UserForm: невелике спеціальне вікно з власними підписами, текстовими полями, випадаючими списками та кнопками, яке створюється у VBE та повністю керується вашим кодом.
Створення форми
У VBE клацніть правою кнопкою миші на вашому проєкті в Project Explorer і виберіть Insert → UserForm. З'явиться порожня область для дизайну, а також плаваюча панель інструментів із елементами керування, які можна перетягувати на форму.
Мітки, текстові поля, комбіновані списки та кнопки
Кожен елемент керування, який ви перетягуєте на форму, отримує стандартну назву на кшталт TextBox1 або CommandButton1 — функціонально, але беззмістовно, коли на формі вже шість чи сім елементів. Найважливіша звичка в цьому розділі відображається у вікні властивостей: перейменовуйте кожен елемент одразу після додавання, використовуючи короткий префікс, що ідентифікує його тип (txt для TextBox, cbo для ComboBox, cmd для CommandButton, opt для OptionButton, chk для CheckBox, lst для ListBox), а далі — описову назву. txtCompanyName буде однозначно зрозумілим у коді навіть через три тижні; TextBox1 — ні.
Мітки — це прості, неінтерактивні текстові підписи ("Company Name:") — користувач їх бачить, але не може вводити текст чи натискати на них. Текстові поля призначені для введення довільного тексту. Комбіновані списки відображають випадаючий перелік варіантів, саме для цього використовуються cboCity та cboStatus — обмеження вибору міста та статусу відомим списком замість того, щоб дозволяти користувачу вільно вводити "chicago", "Chicago,IL" чи "CHI" для одного й того ж у різних записах.
Написання коду для форми
Двічі клацніть будь-який елемент керування на поверхні дизайну, щоб одразу перейти до його коду — VBA автоматично створює процедуру події з іменем ControlName_EventName, і код, написаний у ній, виконується щоразу, коли ця подія відбувається для цього елемента керування. Для кнопки типовою подією є Click:
Private Sub UserForm_Initialize()
' runs once, automatically, when the form is first shown
cboCity.AddItem "Chicago"
cboCity.AddItem "Boston"
cboCity.AddItem "Austin"
cboCity.AddItem "Seattle"
cboCity.AddItem "Denver"
cboStatus.AddItem "Active"
cboStatus.AddItem "Inactive"
cboStatus.AddItem "Prospect"
End Sub
Private Sub cmdCancel_Click()
Unload Me
End Sub
UserForm_Initialize — це спеціальна процедура події, яка спрацьовує автоматично в момент завантаження форми — ще до того, як користувач щось побачить — тому саме тут доцільно заповнювати ComboBox-и за допомогою .AddItem, а не вручну через вікно властивостей, особливо якщо вибірки можуть змінюватися або надходити з аркуша. Unload Me у cmdCancel_Click повністю закриває форму; Me завжди посилається на форму, в якій виконується код, тому цей рядок працює без змін незалежно від того, як ви згодом перейменуєте саму форму.
Приклад: Збереження нового клієнта
Ось процедура для кнопки Save — саме вона записує новий рядок у tblCustomers:
Private Sub cmdSave_Click()
Dim tbl As ListObject
Dim newRow As ListRow
Set tbl = ThisWorkbook.Worksheets("Customers").ListObjects("tblCustomers")
Set newRow = tbl.ListRows.Add
newRow.Range(1, 1).Value = "C" & Format(tbl.ListRows.Count + 1, "000")
newRow.Range(1, 2).Value = txtCompanyName.Value
newRow.Range(1, 3).Value = txtContact.Value
newRow.Range(1, 4).Value = txtEmail.Value
newRow.Range(1, 5).Value = cboCity.Value
newRow.Range(1, 6).Value = cboStatus.Value
MsgBox txtCompanyName.Value & " was added successfully."
Unload Me
End Sub
- Рядок
tbl = ThisWorkbook.Worksheets("Customers").ListObjects("tblCustomers")звертається з форми безпосередньо до книги — UserForm є просто ще одним фрагментом коду, тому всі властивості ListObjects застосовуються до неї без змін; tbl.ListRows.Addдодає справжній новий рядок у межах таблиці, а не записує дані за останньою використаною клітинкою вручну;txtCompanyName.Value,cboCity.Valueта інші зчитують поточне значення, яке користувач ввів або вибрав у відповідному елементі керування —.Valueє спільною властивістю майже для всіх типів елементів, тому цей підхід працює як для TextBox, так і для ComboBox;- Рядок генерації Customer ID — це спрощений приклад для цього завдання; для реального створення ідентифікаторів потрібно перевіряти наявність пропусків або повторів, чого цей рядок не робить;
- Unload Me наприкінці закриває форму лише після запису рядка — якщо закрити раніше, значення
txtCompanyName.Valueта інших елементів стануть недоступними, оскільки після закриття форми ці елементи більше не існують.
Мітка форми "Company Name" є лише зручнішою назвою для стовпця таблиці Customer — код записує txtCompanyName.Value саме в цей стовпець незалежно від підпису мітки, оскільки для VBA має значення лише ім'я TextBox, а не його підпис на екрані.
Customer ID відсутній на формі, оскільки він генерується автоматично кодом ("C0" & (tbl.ListRows.Count + 100)) замість введення користувачем — це відображає, як у реальних системах нові записи отримують автоматичну нумерацію, а не покладаються на вибір унікального ID людиною.
Завдання
- Додати новий UserForm, назвати його
frmAddCustomerі додати три TextBox (txtCompanyName,txtContact,txtEmail) та два ComboBox (cboCity, cboStatus), кожен з відповідною міткою. - Додати дві CommandButton,
cmdSaveіcmdCancel, і написати процедуриUserForm_InitializeтаcmdCancel_Clickточно як показано. - Написати
cmdSave_Clickяк показано, потім додати тимчасову кнопку в іншому місці книги з кодомfrmAddCustomer.Showдля тестування відкриття форми. - Заповнити форму для вигаданого шостого клієнта та натиснути Save — переконатися, що в tblCustomers з'явився новий рядок із введеними значеннями.
1. Створення форми
- Insert → UserForm у VBE, потім перейменуйте її через поле
(Name)у вікні властивостей наfrmAddCustomer— не через поле Caption, яке змінює лише текст у заголовку. - Перетягніть по одній парі Label + TextBox для кожного з полів: Company Name, Contact та Email; по одній парі Label + ComboBox для City та Status.
- Перейменовуйте кожен елемент керування одразу після додавання — це звичка, на якій наголошував розділ. Label не потребують імен, зручних для коду, оскільки ви ніколи не звертаєтесь до них у коді, але кожен TextBox/ComboBox/Button повинен мати таке ім'я.
2. UserForm_Initialize та cmdCancel_Click
- Двічі клацніть на порожньому фоні форми (не на елементі керування), щоб перейти до
UserForm_Initialize— подвійний клік поcmdCancelодразу відкриєcmdCancel_Click. - Обидві процедури наведені у розділі — введіть їх без змін.
3. Тестування за допомогою тимчасової кнопки
- Ця кнопка не обов'язково має бути на формі — розмістіть її на будь-якому аркуші через Developer → Insert → Button (Form Control), або просто запустіть однорядковий
Subу VBE замість додавання кнопки на аркуш. frmAddCustomer.Show— це весь код, необхідний для відображення форми.
4. Перевірка повного збереження
- Заповніть усі поля та виберіть значення з обох випадаючих списків перед натисканням Save — порожній вибір у ComboBox призведе до запису порожньої клітинки.
- Перевірте
tblCustomersпісля цього — має з'явитися новий рядок з ID у стиліC00x.
Private Sub UserForm_Initialize()
' runs once, automatically, when the form is first shown
cboCity.AddItem "Chicago"
cboCity.AddItem "Boston"
cboCity.AddItem "Austin"
cboCity.AddItem "Seattle"
cboCity.AddItem "Denver"
cboStatus.AddItem "Active"
cboStatus.AddItem "Inactive"
cboStatus.AddItem "Prospect"
End Sub
Private Sub cmdCancel_Click()
Unload Me
End Sub
Private Sub cmdSave_Click()
Dim tbl As ListObject
Dim newRow As ListRow
Set tbl = ThisWorkbook.Worksheets("Customers").ListObjects("tblCustomers")
Set newRow = tbl.ListRows.Add
newRow.Range(1, 1).Value = "C0" & (tbl.ListRows.Count + 100)
newRow.Range(1, 2).Value = txtCompanyName.Value
newRow.Range(1, 3).Value = txtContact.Value
newRow.Range(1, 4).Value = txtEmail.Value
newRow.Range(1, 5).Value = cboCity.Value
newRow.Range(1, 6).Value = cboStatus.Value
MsgBox txtCompanyName.Value & " was added successfully."
Unload Me
End Sub
Для перевірки запустіть це з будь-якого звичайного модуля (не з коду самої UserForm):
Sub ShowAddCustomerForm()
frmAddCustomer.Show
End Sub
Натисніть F5, коли курсор знаходиться всередині ShowAddCustomerForm — форма має відкритися, і після її заповнення та натискання Save у tblCustomers з'явиться новий рядок.
Дякуємо за ваш відгук!
Запитати АІ
Запитати АІ
Запитайте про що завгодно або спробуйте одне із запропонованих запитань, щоб почати наш чат
Introduction to UserForms
UserForms мають обмежену або відсутню функціональність у Excel для Mac — VBA IDE на Mac не підтримує повноцінне проєктування UserForm у багатьох версіях, що може спричинити саме таку незрозумілу поведінку.
MsgBox та InputBox підходять для простих питань так/ні та однорядкових відповідей, але для додавання клієнта зазвичай потрібно кілька полів одночасно — назва компанії, контактна особа, місто, статус. Для цього використовується UserForm: невелике спеціальне вікно з власними підписами, текстовими полями, випадаючими списками та кнопками, яке створюється у VBE та повністю керується вашим кодом.
Створення форми
У VBE клацніть правою кнопкою миші на вашому проєкті в Project Explorer і виберіть Insert → UserForm. З'явиться порожня область для дизайну, а також плаваюча панель інструментів із елементами керування, які можна перетягувати на форму.
Мітки, текстові поля, комбіновані списки та кнопки
Кожен елемент керування, який ви перетягуєте на форму, отримує стандартну назву на кшталт TextBox1 або CommandButton1 — функціонально, але беззмістовно, коли на формі вже шість чи сім елементів. Найважливіша звичка в цьому розділі відображається у вікні властивостей: перейменовуйте кожен елемент одразу після додавання, використовуючи короткий префікс, що ідентифікує його тип (txt для TextBox, cbo для ComboBox, cmd для CommandButton, opt для OptionButton, chk для CheckBox, lst для ListBox), а далі — описову назву. txtCompanyName буде однозначно зрозумілим у коді навіть через три тижні; TextBox1 — ні.
Мітки — це прості, неінтерактивні текстові підписи ("Company Name:") — користувач їх бачить, але не може вводити текст чи натискати на них. Текстові поля призначені для введення довільного тексту. Комбіновані списки відображають випадаючий перелік варіантів, саме для цього використовуються cboCity та cboStatus — обмеження вибору міста та статусу відомим списком замість того, щоб дозволяти користувачу вільно вводити "chicago", "Chicago,IL" чи "CHI" для одного й того ж у різних записах.
Написання коду для форми
Двічі клацніть будь-який елемент керування на поверхні дизайну, щоб одразу перейти до його коду — VBA автоматично створює процедуру події з іменем ControlName_EventName, і код, написаний у ній, виконується щоразу, коли ця подія відбувається для цього елемента керування. Для кнопки типовою подією є Click:
Private Sub UserForm_Initialize()
' runs once, automatically, when the form is first shown
cboCity.AddItem "Chicago"
cboCity.AddItem "Boston"
cboCity.AddItem "Austin"
cboCity.AddItem "Seattle"
cboCity.AddItem "Denver"
cboStatus.AddItem "Active"
cboStatus.AddItem "Inactive"
cboStatus.AddItem "Prospect"
End Sub
Private Sub cmdCancel_Click()
Unload Me
End Sub
UserForm_Initialize — це спеціальна процедура події, яка спрацьовує автоматично в момент завантаження форми — ще до того, як користувач щось побачить — тому саме тут доцільно заповнювати ComboBox-и за допомогою .AddItem, а не вручну через вікно властивостей, особливо якщо вибірки можуть змінюватися або надходити з аркуша. Unload Me у cmdCancel_Click повністю закриває форму; Me завжди посилається на форму, в якій виконується код, тому цей рядок працює без змін незалежно від того, як ви згодом перейменуєте саму форму.
Приклад: Збереження нового клієнта
Ось процедура для кнопки Save — саме вона записує новий рядок у tblCustomers:
Private Sub cmdSave_Click()
Dim tbl As ListObject
Dim newRow As ListRow
Set tbl = ThisWorkbook.Worksheets("Customers").ListObjects("tblCustomers")
Set newRow = tbl.ListRows.Add
newRow.Range(1, 1).Value = "C" & Format(tbl.ListRows.Count + 1, "000")
newRow.Range(1, 2).Value = txtCompanyName.Value
newRow.Range(1, 3).Value = txtContact.Value
newRow.Range(1, 4).Value = txtEmail.Value
newRow.Range(1, 5).Value = cboCity.Value
newRow.Range(1, 6).Value = cboStatus.Value
MsgBox txtCompanyName.Value & " was added successfully."
Unload Me
End Sub
- Рядок
tbl = ThisWorkbook.Worksheets("Customers").ListObjects("tblCustomers")звертається з форми безпосередньо до книги — UserForm є просто ще одним фрагментом коду, тому всі властивості ListObjects застосовуються до неї без змін; tbl.ListRows.Addдодає справжній новий рядок у межах таблиці, а не записує дані за останньою використаною клітинкою вручну;txtCompanyName.Value,cboCity.Valueта інші зчитують поточне значення, яке користувач ввів або вибрав у відповідному елементі керування —.Valueє спільною властивістю майже для всіх типів елементів, тому цей підхід працює як для TextBox, так і для ComboBox;- Рядок генерації Customer ID — це спрощений приклад для цього завдання; для реального створення ідентифікаторів потрібно перевіряти наявність пропусків або повторів, чого цей рядок не робить;
- Unload Me наприкінці закриває форму лише після запису рядка — якщо закрити раніше, значення
txtCompanyName.Valueта інших елементів стануть недоступними, оскільки після закриття форми ці елементи більше не існують.
Мітка форми "Company Name" є лише зручнішою назвою для стовпця таблиці Customer — код записує txtCompanyName.Value саме в цей стовпець незалежно від підпису мітки, оскільки для VBA має значення лише ім'я TextBox, а не його підпис на екрані.
Customer ID відсутній на формі, оскільки він генерується автоматично кодом ("C0" & (tbl.ListRows.Count + 100)) замість введення користувачем — це відображає, як у реальних системах нові записи отримують автоматичну нумерацію, а не покладаються на вибір унікального ID людиною.
Завдання
- Додати новий UserForm, назвати його
frmAddCustomerі додати три TextBox (txtCompanyName,txtContact,txtEmail) та два ComboBox (cboCity, cboStatus), кожен з відповідною міткою. - Додати дві CommandButton,
cmdSaveіcmdCancel, і написати процедуриUserForm_InitializeтаcmdCancel_Clickточно як показано. - Написати
cmdSave_Clickяк показано, потім додати тимчасову кнопку в іншому місці книги з кодомfrmAddCustomer.Showдля тестування відкриття форми. - Заповнити форму для вигаданого шостого клієнта та натиснути Save — переконатися, що в tblCustomers з'явився новий рядок із введеними значеннями.
1. Створення форми
- Insert → UserForm у VBE, потім перейменуйте її через поле
(Name)у вікні властивостей наfrmAddCustomer— не через поле Caption, яке змінює лише текст у заголовку. - Перетягніть по одній парі Label + TextBox для кожного з полів: Company Name, Contact та Email; по одній парі Label + ComboBox для City та Status.
- Перейменовуйте кожен елемент керування одразу після додавання — це звичка, на якій наголошував розділ. Label не потребують імен, зручних для коду, оскільки ви ніколи не звертаєтесь до них у коді, але кожен TextBox/ComboBox/Button повинен мати таке ім'я.
2. UserForm_Initialize та cmdCancel_Click
- Двічі клацніть на порожньому фоні форми (не на елементі керування), щоб перейти до
UserForm_Initialize— подвійний клік поcmdCancelодразу відкриєcmdCancel_Click. - Обидві процедури наведені у розділі — введіть їх без змін.
3. Тестування за допомогою тимчасової кнопки
- Ця кнопка не обов'язково має бути на формі — розмістіть її на будь-якому аркуші через Developer → Insert → Button (Form Control), або просто запустіть однорядковий
Subу VBE замість додавання кнопки на аркуш. frmAddCustomer.Show— це весь код, необхідний для відображення форми.
4. Перевірка повного збереження
- Заповніть усі поля та виберіть значення з обох випадаючих списків перед натисканням Save — порожній вибір у ComboBox призведе до запису порожньої клітинки.
- Перевірте
tblCustomersпісля цього — має з'явитися новий рядок з ID у стиліC00x.
Private Sub UserForm_Initialize()
' runs once, automatically, when the form is first shown
cboCity.AddItem "Chicago"
cboCity.AddItem "Boston"
cboCity.AddItem "Austin"
cboCity.AddItem "Seattle"
cboCity.AddItem "Denver"
cboStatus.AddItem "Active"
cboStatus.AddItem "Inactive"
cboStatus.AddItem "Prospect"
End Sub
Private Sub cmdCancel_Click()
Unload Me
End Sub
Private Sub cmdSave_Click()
Dim tbl As ListObject
Dim newRow As ListRow
Set tbl = ThisWorkbook.Worksheets("Customers").ListObjects("tblCustomers")
Set newRow = tbl.ListRows.Add
newRow.Range(1, 1).Value = "C0" & (tbl.ListRows.Count + 100)
newRow.Range(1, 2).Value = txtCompanyName.Value
newRow.Range(1, 3).Value = txtContact.Value
newRow.Range(1, 4).Value = txtEmail.Value
newRow.Range(1, 5).Value = cboCity.Value
newRow.Range(1, 6).Value = cboStatus.Value
MsgBox txtCompanyName.Value & " was added successfully."
Unload Me
End Sub
Для перевірки запустіть це з будь-якого звичайного модуля (не з коду самої UserForm):
Sub ShowAddCustomerForm()
frmAddCustomer.Show
End Sub
Натисніть F5, коли курсор знаходиться всередині ShowAddCustomerForm — форма має відкритися, і після її заповнення та натискання Save у tblCustomers з'явиться новий рядок.
Дякуємо за ваш відгук!