Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Вивчайте Introduction to UserForms | Взаємодія з користувачем
Excel VBA для автоматизації бізнесу

Introduction to UserForms

Свайпніть щоб показати меню

Note
Примітка

UserForms мають обмежену або відсутню функціональність у Excel для Mac — VBA IDE на Mac не підтримує повноцінне проєктування UserForm у багатьох версіях, що може спричинити саме таку незрозумілу поведінку.

MsgBox та InputBox підходять для простих питань так/ні та однорядкових відповідей, але для додавання клієнта зазвичай потрібно кілька полів одночасно — назва компанії, контактна особа, місто, статус. Для цього використовується UserForm: невелике спеціальне вікно з власними підписами, текстовими полями, випадаючими списками та кнопками, яке створюється у VBE та повністю керується вашим кодом.

Створення форми

У VBE клацніть правою кнопкою миші на вашому проєкті в Project Explorer і виберіть Insert → UserForm. З'явиться порожня область для дизайну, а також плаваюча панель інструментів із елементами керування, які можна перетягувати на форму.

Рисунок 5.3

Мітки, текстові поля, комбіновані списки та кнопки

Кожен елемент керування, який ви перетягуєте на форму, отримує стандартну назву на кшталт 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
Покроковий розбір коду
expand arrow
  • Рядок tbl = ThisWorkbook.Worksheets("Customers").ListObjects("tblCustomers") звертається з форми безпосередньо до книги — UserForm є просто ще одним фрагментом коду, тому всі властивості ListObjects застосовуються до неї без змін;
  • tbl.ListRows.Add додає справжній новий рядок у межах таблиці, а не записує дані за останньою використаною клітинкою вручну;
  • txtCompanyName.Value, cboCity.Value та інші зчитують поточне значення, яке користувач ввів або вибрав у відповідному елементі керування — .Value є спільною властивістю майже для всіх типів елементів, тому цей підхід працює як для TextBox, так і для ComboBox;
  • Рядок генерації Customer ID — це спрощений приклад для цього завдання; для реального створення ідентифікаторів потрібно перевіряти наявність пропусків або повторів, чого цей рядок не робить;
  • Unload Me наприкінці закриває форму лише після запису рядка — якщо закрити раніше, значення txtCompanyName.Value та інших елементів стануть недоступними, оскільки після закриття форми ці елементи більше не існують.
Note
Примітка

Мітка форми "Company Name" є лише зручнішою назвою для стовпця таблиці Customer — код записує txtCompanyName.Value саме в цей стовпець незалежно від підпису мітки, оскільки для VBA має значення лише ім'я TextBox, а не його підпис на екрані.

Note
Примітка

Customer ID відсутній на формі, оскільки він генерується автоматично кодом ("C0" & (tbl.ListRows.Count + 100)) замість введення користувачем — це відображає, як у реальних системах нові записи отримують автоматичну нумерацію, а не покладаються на вибір унікального ID людиною.

Завдання

  1. Додати новий UserForm, назвати його frmAddCustomer і додати три TextBox (txtCompanyName, txtContact, txtEmail) та два ComboBox (cboCity, cboStatus), кожен з відповідною міткою.
  2. Додати дві CommandButton, cmdSave і cmdCancel, і написати процедури UserForm_Initialize та cmdCancel_Click точно як показано.
  3. Написати cmdSave_Click як показано, потім додати тимчасову кнопку в іншому місці книги з кодом frmAddCustomer.Show для тестування відкриття форми.
  4. Заповнити форму для вигаданого шостого клієнта та натиснути Save — переконатися, що в tblCustomers з'явився новий рядок із введеними значеннями.
Підказка
expand arrow

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.
Розв'язок
expand arrow
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 з'явиться новий рядок.

Тестування форми
Все було зрозуміло?

Як ми можемо покращити це?

Дякуємо за ваш відгук!

Секція 5. Розділ 2

Запитати АІ

expand

Запитати АІ

ChatGPT

Запитайте про що завгодно або спробуйте одне із запропонованих запитань, щоб почати наш чат

Introduction to UserForms

Note
Примітка

UserForms мають обмежену або відсутню функціональність у Excel для Mac — VBA IDE на Mac не підтримує повноцінне проєктування UserForm у багатьох версіях, що може спричинити саме таку незрозумілу поведінку.

MsgBox та InputBox підходять для простих питань так/ні та однорядкових відповідей, але для додавання клієнта зазвичай потрібно кілька полів одночасно — назва компанії, контактна особа, місто, статус. Для цього використовується UserForm: невелике спеціальне вікно з власними підписами, текстовими полями, випадаючими списками та кнопками, яке створюється у VBE та повністю керується вашим кодом.

Створення форми

У VBE клацніть правою кнопкою миші на вашому проєкті в Project Explorer і виберіть Insert → UserForm. З'явиться порожня область для дизайну, а також плаваюча панель інструментів із елементами керування, які можна перетягувати на форму.

Рисунок 5.3

Мітки, текстові поля, комбіновані списки та кнопки

Кожен елемент керування, який ви перетягуєте на форму, отримує стандартну назву на кшталт 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
Покроковий розбір коду
expand arrow
  • Рядок tbl = ThisWorkbook.Worksheets("Customers").ListObjects("tblCustomers") звертається з форми безпосередньо до книги — UserForm є просто ще одним фрагментом коду, тому всі властивості ListObjects застосовуються до неї без змін;
  • tbl.ListRows.Add додає справжній новий рядок у межах таблиці, а не записує дані за останньою використаною клітинкою вручну;
  • txtCompanyName.Value, cboCity.Value та інші зчитують поточне значення, яке користувач ввів або вибрав у відповідному елементі керування — .Value є спільною властивістю майже для всіх типів елементів, тому цей підхід працює як для TextBox, так і для ComboBox;
  • Рядок генерації Customer ID — це спрощений приклад для цього завдання; для реального створення ідентифікаторів потрібно перевіряти наявність пропусків або повторів, чого цей рядок не робить;
  • Unload Me наприкінці закриває форму лише після запису рядка — якщо закрити раніше, значення txtCompanyName.Value та інших елементів стануть недоступними, оскільки після закриття форми ці елементи більше не існують.
Note
Примітка

Мітка форми "Company Name" є лише зручнішою назвою для стовпця таблиці Customer — код записує txtCompanyName.Value саме в цей стовпець незалежно від підпису мітки, оскільки для VBA має значення лише ім'я TextBox, а не його підпис на екрані.

Note
Примітка

Customer ID відсутній на формі, оскільки він генерується автоматично кодом ("C0" & (tbl.ListRows.Count + 100)) замість введення користувачем — це відображає, як у реальних системах нові записи отримують автоматичну нумерацію, а не покладаються на вибір унікального ID людиною.

Завдання

  1. Додати новий UserForm, назвати його frmAddCustomer і додати три TextBox (txtCompanyName, txtContact, txtEmail) та два ComboBox (cboCity, cboStatus), кожен з відповідною міткою.
  2. Додати дві CommandButton, cmdSave і cmdCancel, і написати процедури UserForm_Initialize та cmdCancel_Click точно як показано.
  3. Написати cmdSave_Click як показано, потім додати тимчасову кнопку в іншому місці книги з кодом frmAddCustomer.Show для тестування відкриття форми.
  4. Заповнити форму для вигаданого шостого клієнта та натиснути Save — переконатися, що в tblCustomers з'явився новий рядок із введеними значеннями.
Підказка
expand arrow

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.
Розв'язок
expand arrow
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 з'явиться новий рядок.

Тестування форми
Все було зрозуміло?

Як ми можемо покращити це?

Дякуємо за ваш відгук!

Секція 5. Розділ 2
some-alt