ВГОРУ

VBA-Урок 12.2. Елементи управління (Controls)

Елементи управління (Controls) мають всі види властивостей і з ними пов'язано багато подій, але зараз ми розглянемо лише кілька з них, які використовуються у програмуванні на VBA.


Давайте почнемо з додавання 3-х елементів управління - Label, TextBox та CommandButton:

Відредагуємо назву і властивості цього елементу управління (використовуючи властивість Caption, яка містить текст), щоби отримати наступний результат:

Зараз, коли ми введемо номер і натиснемо ОК - нічого не станеться.

Щоби створити якусь дію, ми додамо подію, що запише введене значення з текстового вікна до комірки А1 і закриє Форму.

Ви можете доступитися до опцій, що показані нижче, двічі клацнувши по елементі управління:

Даний випадаючий список містить різні елементи управління та цю Форму.

Виберіть кнопку (Button) і подію Click:

Private Sub CommandButton_validate_Click()

     Range("A1") = Textbox_number.Value
     'Textbox_number є назвою текстового вікна (text box)
     'Value є властивістю, що містить значення текстового вікна
    
     Unload Me
     'Unload закриває форму (UserForm)
     'Ми використовуємо Me замість назви форми (тому що, цей код є в середині UserForm, яку ми хочемо закрити)
End Sub

Введене значення зараз вже буде збережене в комірці А1 перед закриттям цієї Форми (UserForm).

Додайте другий підпис (Label) і відредагуйте наступні властивості: Caption, Forecolor (color : red) та Visible (False, щоби сховати елемент управління по замовчуванню) :

Тепер давайте додамо подію, яка буде запускатися, коли значення в текстовому полі буде змінюватися користувачем. Подія відобразить повідомлення про помилку, якщо значення не являється цифровим.

Private Sub Textbox_number_Change()
     If IsNumeric(Textbox_number.Value) Then 'ЯКЩО являється цифровим значенням...
         Label_error.Visible = False 'Назва (Label) схована
     Else 'ІНАКШЕ...
         Label_error.Visible = True 'Назва відображається
     End If
End Sub

Введене значення буде тестуватися кожен раз при введені чергового символу.

Нам ще потрібно добавити перевірку (валідацію) введених значень на формі. Будемо показувати повідомлення, якщо значення не є числом:

Private Sub CommandButton_validate_Click()
     If IsNumeric(Textbox_number.Value) Then 'ЯКЩО являється цифровим значенням...
         Range("A1") = Textbox_number.Value 'Копіюєм в A1
         Unload Me 'Закриваєм
     Else 'ІНАКШЕ...
         MsgBox "Incorrect value" 'Неправильне значення
     End If
End Sub

Для того, щоби не залишати праву сторону форми порожньою, коли там немає повідомлення про помилку, ми можемо зменшити її розмір, відкоригувавши властивість Width цієї форми:

Private Sub Textbox_number_Change()
     If IsNumeric(Textbox_number.Value) Then 'ЯКЩО являється цифровим значенням...
         Label_error.Visible = False 'Назва (Label) схована
         Me.Width = 156 'Ширина форми
     Else 'ІНАКШЕ...
         Label_error.Visible = True 'Назва відображається
         Me.Width = 244 'Ширина форми
     End If
End Sub

Ви можете завантажити Excel файл з прикладом: userform1.xls

Ось результат:

Checkboxes

Далі є приклад як використовувати CheckBox:

Коли чекбокс (прапорець) відмічений/невідмічений, значення повязаної комірки може бути змінено через використання події Click:

Private Sub CheckBox1_Click() 'Номер 1
     If CheckBox1.Value = True Then 'ЯКЩО вибрано...
        Range("A2") = "Checked"
     Else 'ЯКЩО не вибрано...
        Range("A2") = "Unchecked"
     End If
End Sub

Private Sub CheckBox2_Click() 'Номер 2
     If CheckBox2.Value = True Then 'ЯКЩО вибрано...
        Range("B2") = "Checked"
     Else 'ЯКЩО не вибрано...
        Range("B2") = "Unchecked"
     End If
End Sub

Private Sub CheckBox3_Click() 'Номер 3
     If CheckBox3.Value = True Then 'ЯКЩО вибрано...
        Range("C2") = "Checked"
     Else 'ЯКЩО не вибрано...
        Range("C2") = "Unchecked"
     End If
End Sub

В цьому прикладі, чекбокси початково є невідміченими, коли Форма відкривається вперше.

Щоби проставити галочку в кожен чекбокс, коли значення відповідної комірки є "Відмічено" ("Checked"), ми запустимо перевірку при активації форми, використовуючи UserForm_Initialize:

Private Sub UserForm_Initialize() 'Якщо поставлена "галочка"
     If Range("A2") = "Checked" Then
         CheckBox1.Value = True
     End If
     
     If Range("B2") = "Checked" Then
         CheckBox2.Value = True
     End If
     
     If Range("C2") = "Checked" Then
         CheckBox3.Value = True
     End If
End Sub

Тут ви можете подивитись приклад в готовому Excel файлі: userform2.xls

Кнопки опцій (Option Buttons)

При використанні кнопок опцій (Option Buttons або, іноді, ще називають Radio Buttons) користувач може вибрати тільки одну опцію на "групу" на відміну від чекбоксів, де користувач може проставити декілька галочок одночасно.

Щоби створити "групу", спочатку вставте Frame, а потім OptionButton:

Тут ви можете подивитись приклад в готовому Excel файлі: userform3.xls

При надсиланні форми, будуть введені дані в комірку, що повязана з вибраною назвою колонки (column_value) та рядком (row_value).

Для того, щоби знати які опції були вибрані, ми могли би зробити те саме що і в попередньому прикладі (з чекбоксами), але ми використаємо цикл, щоби зменшити розмір коду.

Ми будемо використовувати цикл For Each, це тип циклу, який ми ще до цього не розглядали. Цей цикл дозволяє виконувати інструкції для кожного обєкту в "групі обєктів":

Private Sub CommandButton1_Click()
     Dim column_value As String, row_value As String
     
     'Цикл для кожного елемента управління Frame_column
     For Each column_button In Frame_column.Controls
         'Якщо значення елемента управління = True (тоді, якщо вибрано) ...
         If column_button.Value Then
            'Змінна "column_value" приймає значення тексту кнопки
            column_value = column_button.Caption
         End If
     Next
     
     'Цикл для іншого блоку
     For Each row_button In Frame_row.Controls
         If row_button.Value Then
             row_value = row_button.Caption
         End If
     Next

     Range(column_value & row_value) = "Cell chosen!"  ' "Комірка вибрана!"
     
     'Закрити (Unload) форму (Me)
     Unload Me
End Sub

Зараз наша форма вводить значення "Комірка вибрана!" в комірку, що була вибрана.

Щоби уникнути помилки, нам необхідно перевірити чи користувач вибрав правильно з двох наборів опцій.

В цьому прикладі, коли форма ще не завершена, кнопка "Підтвердження" ("Confirm") буде виділена сірим кольором (деактивованою). Це не є найпростіше рішення, але це хороший приклад того, чому функції/процедури є користними в середині форми (UserForm).

Відредагуйте текст та властивість Enabled, щоби деактивувати кнопку.

Результат буде наступний:

В попередньому коді ми використали два For Each цикла, щоби дістати значення опційних кнопок (Option Buttons). Зараз нам потрібно використати ті самі значення для кнопки "Підтвердження" ("Confirm") та подію Click для десяти опцій.

Для цього нам не потрібно копіювати цикли для кожної події, ми викличемо їх через функцію.

Почнемо з попереднього коду та модифікуючи його, ми досягнемо цього результату:

 Private Function column_value()
 'Функція, що вертає текстове значення для вибранної кнопки (column_value)
     For Each column_button In Frame_column.Controls
         If column_button.Value Then
             column_value = column_button.Caption
         End If
     Next
 End Function

 Private Function row_value()
 'Функція, що вертає текстове значення для вибранної кнопки (row_value)
     For Each row_button In Frame_row.Controls
         If row_button.Value Then
             row_value = row_button.Caption
         End If
     Next
 End Function

 Private Sub CommandButton1_Click() 'Дія, що стається коли ви клацаєте ("Підтвердіть свій вибір")
     Range(column_value & row_value) = "Cell chosen!"  ' "Комірка вибрана!"
     'column_value та row_value є значеннями, що вертаються цими функціями
     Unload Me
 End Sub

Все що нам залишилось зробити, це створити процедуру, що перевіряє чи кнопки опцій були вибрані коректно (через виклик двох функцій), і яка активує цю кнопку коли потрібно.

Знову ж, перевірка виконується в окремій процедурі, щоби уникнути копіювання коду 10 разів для кожної події кожної опційної кнопки:

Private Sub activate_button()
 'Активація кнопки, якщо умова успішно перевірена
     If column_value <> "" And row_value <> "" Then
     'column_value та row_value є значеннями, що повертаються цими функціями
         CommandButton1.Enabled = True
         CommandButton1.Caption = "Confirm your selection"  ' "Підтвердіть свій вибір"
     End If
End Sub

Private Sub OptionButton11_Click()
     activate_button 'Запускаємо процедуру "activate_button"
End Sub
Private Sub OptionButton12_Click()
     activate_button
End Sub
Private Sub OptionButton13_Click()
     activate_button
End Sub
Private Sub OptionButton14_Click()
     activate_button
End Sub
Private Sub OptionButton15_Click()
     activate_button
End Sub
Private Sub OptionButton16_Click()
     activate_button
End Sub
Private Sub OptionButton17_Click()
     activate_button
End Sub
Private Sub OptionButton18_Click()
     activate_button
End Sub
Private Sub OptionButton19_Click()
     activate_button
End Sub
Private Sub OptionButton20_Click()
     activate_button
End Sub

Тут ви можете подивитись приклад в готовому Excel файлі: userform3b.xls