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

Робота з елементами керування форми

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

TextBoxes і ComboBoxes охоплюють більшість випадків введення даних, але деякі інші елементи керування природніше виражають певні типи вибору — і правильне зчитування їхніх значень має кілька важливих нюансів, які варто знати, перш ніж покладатися на них.

Рисунок 5.5

CheckBoxes

Властивість Value для CheckBox — це звичайне булеве значення: True, якщо встановлено прапорець, і False, якщо ні:

If chkWelcomeEmail.Value = True Then
    MsgBox "A welcome email would be sent here."
End If

Кожен CheckBox на формі повністю незалежний від інших — встановлення chkWelcomeEmail не впливає на chkNewsletter, що саме і потрібно, коли вибори не є взаємовиключними.

OptionButtons

OptionButtons працюють навпаки: у межах однієї групи вибір одного автоматично знімає вибір з усіх інших — саме така поведінка потрібна для вибору Status на скріншоті, оскільки клієнт не може бути одночасно і Active, і Inactive. Щоб дізнатися, який саме вибрано, потрібно перевірити значення кожного окремо:

Dim status As String
If optActive.Value = True Then
    status = "Active"
ElseIf optInactive.Value = True Then
    status = "Inactive"
ElseIf optProspect.Value = True Then
    status = "Prospect"
End If

Взаємовиключність забезпечується автоматично і повністю обробляється VBA — не потрібно писати код для зняття вибору з інших двох, коли вибрано один. Проте важливо правильно групувати: OptionButtons виключають одне одного лише в межах одного контейнера (самої форми або Frame, розміщеного на ній), тому дві окремі групи OptionButtons на одній формі — наприклад, Status і Priority — мають бути розміщені у двох різних Frame, інакше VBA розглядатиме їх як одну взаємовиключну групу.

ListBoxes

ListBox відображає кілька варіантів одночасно без необхідності відкривати список, як у випадку зі списком City на рисунку 5.5. Заповнюється так само, як ComboBox, за допомогою .AddItem, а вибір зчитується через .Value або .ListIndex:

Private Sub UserForm_Initialize()
    lstCities.AddItem "Chicago"
    lstCities.AddItem "Boston"
    lstCities.AddItem "Austin"
End Sub
 
Private Sub cmdAssign_Click()
    If lstCities.ListIndex = -1 Then
        MsgBox "Please select a city first."
        Exit Sub
    End If
    MsgBox "Assigning to: " & lstCities.Value
End Sub

ListIndex — це позиція вибраного елемента, починаючи з 0 для першого — і важливо, що значення -1 означає, що ще нічого не вибрано, саме це перевіряє cmdAssign_Click, щоб зловити користувача, який натиснув кнопку, не вибравши місто. .Value повертає вибраний текст безпосередньо, що зазвичай зручніше, ніж числова позиція, яку дає .ListIndex.

Multi-Page Forms

Елемент MultiPage (вкладки Details / Preferences у верхній частині рисунка 5.5) групує пов’язані елементи керування на окремих сторінках однієї фізичної форми — корисно, коли на формі забагато полів для комфортного розміщення на одному екрані. Кожна сторінка визначається за позицією, і лише елементи на поточній видимій сторінці мають значення для користувача, хоча всі вони існують і доступні для читання з коду незалежно від того, яка сторінка відкрита:

Private Sub MultiPage1_Change()
    If MultiPage1.Value = 1 Then
        MsgBox "Now viewing Preferences"
    End If
End Sub

MultiPage1.Value використовує таке ж нумерування з нуля, як і ListIndex — перша сторінка має значення 0, друга (Preferences на рисунку 5.5) — 1, а подія Change спрацьовує автоматично щоразу, коли користувач натискає іншу вкладку.

Завдання

  1. Додати Frame з трьома OptionButton (optActive, optInactive, optProspect) до frmAddCustomer, замінивши попередній ComboBox cboStatus, і написати блок If...ElseIf, як показано вище, для зчитування вибору.
  2. Додати дві незалежні CheckBox (chkWelcomeEmail, chkNewsletter) і переконатися під час тестування, що вибір однієї не впливає на іншу.
  3. Додати ListBox (lstCities), який заповнюється у UserForm_Initialize, і написати перевірку, що показує помилку, якщо користувач намагається продовжити без вибору (ListIndex = -1).
  4. Додаткове завдання: розмістити поля Company Name, Contact та Email на одній сторінці MultiPage з назвою "Details", а CheckBox і OptionButton — на другій сторінці з назвою "Preferences".
Підказка
expand arrow

1. Заміна cboStatus на Frame з OptionButton

  • Спочатку видаліть cboStatus та його мітку з форми — ви замінюєте його, а не додаєте поруч.
  • Перетягніть елемент Frame на форму, потім перетягніть усі три OptionButton всередину меж Frame — саме ця вкладеність робить їх взаємовиключними як одну групу.
  • Перейменуйте кожен OptionButton окремо у вікні властивостей; сам Frame може мати простий підпис, наприклад "Status", але не потребує зручної для коду назви, якщо ви не плануєте звертатися до нього напряму.
  • Для зчитування вибору потрібно перевіряти .Value кожного OptionButton окремо через If...ElseIf — немає єдиної властивості, яка показує, "який саме з групи обраний".
  • Оскільки cboStatus.Value більше не існує, у cmdSave_Click потрібно створити змінну status на основі OptionButton і записати її у newRow замість попереднього значення.

2. Додавання двох незалежних CheckBox

  • Вони розміщуються безпосередньо на формі (не у Frame) — CheckBox поза спільним контейнером ніколи не впливають одна на одну незалежно від групування.
  • Для "перевірки під час тестування" просто виберіть одну, потім іншу, і переконайтеся, що жодна не знімає вибір з першої.

3. Додавання та перевірка ListBox

  • Заповнюйте його так само, як і cboCity — багаторазові виклики .AddItem у UserForm_Initialize.
  • ListIndex = -1 означає, що нічого ще не вибрано — це саме та умова, яку потрібно перевірити перед збереженням.
  • Ця перевірка має бути у тому ж блоці валідації, що й інші обов'язкові поля, додаючи повідомлення до того ж рядка errors.

4. Додаткове завдання з MultiPage

  • Перетягніть елемент MultiPage на форму — за замовчуванням він містить дві сторінки, саме стільки й потрібно.
  • Перейменуйте кожну сторінку через контекстне меню → Page Order, або виберіть вкладку сторінки та змініть підпис у полі Caption у вікні властивостей (Caption визначає текст на вкладці; є окреме поле (Name), якщо потрібно звертатися до сторінки у коді).
  • Щоб перемістити існуючі елементи на сторінку, перетягніть їх фізично на видиму область цієї сторінки у режимі конструктора — посилання на елементи у коді не змінюються, оскільки ім'я елемента не залежить від сторінки, на якій він розташований.
Розв'язок
expand arrow
Private Sub UserForm_Initialize()
    cboCity.AddItem "Chicago"
    cboCity.AddItem "Boston"
    cboCity.AddItem "Austin"
    cboCity.AddItem "Seattle"
    cboCity.AddItem "Denver"

    lstCities.AddItem "Chicago"
    lstCities.AddItem "Boston"
    lstCities.AddItem "Austin"
    lstCities.AddItem "Seattle"
    lstCities.AddItem "Denver"
End Sub

Private Sub cmdCancel_Click()
    Unload Me
End Sub

Private Sub cmdSave_Click()
    Dim tbl As ListObject
    Dim newRow As ListRow
    Dim errors As String
    Dim status As String

    ' --- Reset field colors ---
    txtCompanyName.BackColor = vbWhite
    txtContact.BackColor = vbWhite
    txtEmail.BackColor = vbWhite

    ' --- Required field checks ---
    If Trim(txtCompanyName.Value) = "" Then
        errors = errors & "- Company Name is required" & vbNewLine
        txtCompanyName.BackColor = RGB(255, 199, 206)
    End If

    If Trim(txtContact.Value) = "" Then
        errors = errors & "- Contact is required" & vbNewLine
        txtContact.BackColor = RGB(255, 199, 206)
    End If

    If Trim(txtEmail.Value) = "" Then
        errors = errors & "- Email is required" & vbNewLine
        txtEmail.BackColor = RGB(255, 199, 206)
    End If

    ' --- Status via OptionButtons ---
    If optActive.Value = True Then
        status = "Active"
    ElseIf optInactive.Value = True Then
        status = "Inactive"
    ElseIf optProspect.Value = True Then
        status = "Prospect"
    Else
        errors = errors & "- Please select a Status" & vbNewLine
    End If

    ' --- ListBox check ---
    If lstCities.ListIndex = -1 Then
        errors = errors & "- Please select a city from the list" & vbNewLine
    End If

    If errors <> "" Then
        MsgBox "Please fix the following:" & vbNewLine & errors, vbExclamation
        Exit Sub
    End If

    ' --- All checks passed — safe to save now ---
    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 = status

    If chkWelcomeEmail.Value = True Then
        MsgBox "A welcome email would be sent to " & txtEmail.Value & "."
    End If

    MsgBox txtCompanyName.Value & " was added successfully."
    Unload Me
End Sub

Примітки щодо тестування:

  • Пункт 2 (CheckBox) не має окремої перевірки — просто натисніть chkWelcomeEmail та chkNewsletter незалежно й переконайтеся, що кожна перемикається без впливу на іншу.
  • Пункт 4 (MultiPage) — це лише зміна макета, жодних змін у коді не потрібно, оскільки кожен елемент зберігає свою назву незалежно від сторінки, на якій він розташований.
  • Зверніть увагу, що cboCity.Value все ще використовується для фактичного збереження (newRow.Range(1, 5)), тоді як lstCities існує окремо як незалежний контроль для перевірки згідно з завданням — вони не пов'язані між собою, якщо ви самостійно не реалізуєте це.
Все було зрозуміло?

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

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

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

Запитати АІ

expand

Запитати АІ

ChatGPT

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

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