TOP

VBA-Lekcja 12.2. Sterowanie (Controls)

Kontrole (Controls) mają wszelkiego rodzaju właściwości i wiele powiązanych z nimi zdarzeń, ale na razie przyjrzymy się tylko kilku, które są używane w programowaniu na VBA.


Zacznijmy od dodania 3 kontrolek - Label, TextBox i CommandButton:

Edytuj nazwę i właściwości tej kontrolki (używając właściwości Caption zawierającej tekst), aby uzyskać następujący wynik:

Teraz gdy wpiszemy numer i klikniemy OK nic się nie dzieje.

Aby utworzyć akcję dodamy zdarzenie, które zapisze wprowadzoną wartość z pola tekstowego do komórki A1 i zamknie Formularz.

Dostęp do opcji pokazanych poniżej można uzyskać, klikając dwukrotnie element sterujący:

Ta lista rozwijana zawiera różne elementy sterujące i ten formularz.

Wybierz przycisk (Button) i zdarzenie Click:

Private Sub CommandButton_validate_Click()

     Range("A1") = Textbox_number.Value
     'Numer_pola tekstowego to nazwa pola tekstowego
     'Value to właściwość zawierająca wartość pola tekstowego
    
     Unload Me
     'Unload zamyka formularz (UserForm)
     'Używamy Me zamiast nazwy formularza (ponieważ ten kod znajduje się w środku UserForm, który chcemy zamknąć)
End Sub

Wprowadzona wartość zostanie już zapisana w komórce A1 przed zamknięciem tego formularza (UserForm).

Dodaj drugi podpis (Label) i edytuj następujące właściwości: Caption, Forecolor (kolor: czerwony) i Visible (False, aby ukryć domyślną kontrolkę):

Dodajmy teraz zdarzenie, które zostanie wywołane w przypadku zmiany wartości w polu tekstowym przez użytkownika. Zdarzenie wyświetli komunikat o błędzie, jeśli wartość nie jest liczbowa.

Private Sub Textbox_number_Change()
     If IsNumeric(Textbox_number.Value) Then 'JEŻELI jest wartością liczbową...
         Label_error.Visible = False 'Tytuł (Label) jest ukryty
     Else 'W PRZECIWNYM RAZIE...
         Label_error.Visible = True 'Nazwa zostanie wyświetlona
     End If
End Sub

Wprowadzona wartość będzie sprawdzana przy każdym wpisaniu kolejnego znaku.

Pozostaje jeszcze dodać weryfikację (walidację) wprowadzonych wartości w formularzu. Jeśli wartość nie jest liczbą, wyświetlimy komunikat:

Private Sub CommandButton_validate_Click()
     If IsNumeric(Textbox_number.Value) Then 'JEŻELI jest wartością liczbową...
         Range("A1") = Textbox_number.Value 'Skopiuj do A1
         Unload Me 'Zamykam
     Else 'W PRZECIWNYM RAZIE...
         MsgBox "Incorrect value" 'niewłaściwa wartość
     End If
End Sub

Aby nie pozostawić pustej prawej strony formularza w przypadku braku komunikatu o błędzie, możemy zmniejszyć jego rozmiar dostosowując właściwość Width tego formularza:

Private Sub Textbox_number_Change()
     If IsNumeric(Textbox_number.Value) Then 'JEŻELI jest wartością liczbową...
         Label_error.Visible = False 'Tytuł (Label) jest ukryty
         Me.Width = 156 'Szerokość formularza
     Else 'W PRZECIWNYM RAZIE...
         Label_error.Visible = True 'Nazwa zostanie wyświetlona
         Me.Width = 244 'Szerokość formularza
     End If
End Sub

Możesz pobrać przykładowy plik Excel: userform1.xls

Oto wynik:

Checkboxes

Oto przykład użycia CheckBox:

Gdy pole wyboru jest zaznaczone/odznaczone, wartość powiązanej komórki można zmienić za pomocą zdarzenia Click:

Private Sub CheckBox1_Click() 'Numer 1
     If CheckBox1.Value = True Then 'JEŚLI wybrano...
        Range("A2") = "Checked"
     Else 'JEŚLI nie wybrano...
        Range("A2") = "Unchecked"
     End If
End Sub

Private Sub CheckBox2_Click() 'Numer 2
     If CheckBox2.Value = True Then 'JEŚLI wybrano...
        Range("B2") = "Checked"
     Else 'JEŚLI nie wybrano...
        Range("B2") = "Unchecked"
     End If
End Sub

Private Sub CheckBox3_Click() 'Numer 3
     If CheckBox3.Value = True Then 'JEŚLI wybrano...
        Range("C2") = "Checked"
     Else 'JEŚLI nie wybrano...
        Range("C2") = "Unchecked"
     End If
End Sub

W tym przykładzie pola wyboru są początkowo odznaczone przy pierwszym otwarciu formularza.

Aby zaznaczyć każde pole wyboru, gdy wartość odpowiedniej komórki jest „Zaznaczona” („Checked”), uruchomimy sprawdzanie podczas aktywacji formularza za pomocą narzędzia UserForm_Initialize:

Private Sub UserForm_Initialize() 'Jeśli zaznaczone
     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

Tutaj możesz zobaczyć przykład w gotowym pliku Excel: userform2.xls

Przyciski opcji (Option Buttons)

Korzystając z przycisków opcji (Option Buttons lub czasami nazywanych także Radio Buttons), użytkownik może wybrać tylko jedną opcję na „grupę”, w przeciwieństwie do pól wyboru, w których użytkownik może zaznaczyć kilka pól jednocześnie.

Aby utworzyć „grupę”, najpierw wstaw Frame, a następnie OptionButton:

Tutaj możesz zobaczyć przykład w gotowym pliku Excel: userform3.xls

Podczas wysyłania formularza dane zostaną wpisane do komórki powiązanej z wybraną nazwą kolumny (column_value) i wierszem (row_value).

Aby dowiedzieć się, które opcje zostały wybrane, moglibyśmy zrobić to samo, co w poprzednim przykładzie (z checkboxami), ale użyjemy pętli, aby zmniejszyć rozmiar kodu.

Będziemy używać pętli For Each, która jest rodzajem pętli, którego wcześniej nie omawialiśmy. Ta pętla umożliwia wykonanie instrukcji dla każdego obiektu w „grupie obiektów”:

Private Sub CommandButton1_Click()
     Dim column_value As String, row_value As String
     
     'Pętla dla każdej kontrolki Frame_column
     For Each column_button In Frame_column.Controls
         'Jeśli wartość kontrolna = True (wtedy, jeśli została wybrana) ...
         If column_button.Value Then
            'Zmienna „column_value” przyjmuje wartość tekstową przycisku
            column_value = column_button.Caption
         End If
     Next
     
     'Przejdź do kolejnego bloku
     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!"  '„Wybrano komórkę!”
     
     'Zamknij (Rozładuj) formularz (Ja)
     Unload Me
End Sub

Nasz formularz wprowadza teraz wartość „Wybrano komórkę!” w wybranej komórce.

Aby uniknąć błędu, musimy sprawdzić, czy użytkownik dokonał prawidłowego wyboru z dwóch zestawów opcji.

W tym przykładzie, gdy formularz nie jest jeszcze wypełniony, przycisk Potwierdź („Confirm”) będzie wyszarzony (wyłączony). Nie jest to najłatwiejsze rozwiązanie, ale jest dobrym przykładem tego, dlaczego funkcje/procedury są przydatne w środku formularza (UserForm).

Edytuj tekst i właściwość Enabled, aby wyłączyć przycisk.

Wynik będzie następujący:

W poprzednim kodzie wykorzystaliśmy dwie pętle For Each do pobrania wartości przycisków opcji (Option Buttons). Teraz musimy użyć tych samych wartości dla przycisku Potwierdź („Confirm”) i zdarzenia Click dla dziesięciu opcji.

Aby to zrobić, nie musimy kopiować pętli dla każdego zdarzenia, wywołamy je poprzez funkcję.

Zaczynając od poprzedniego kodu i modyfikując go, osiągniemy taki wynik:

 Private Function column_value()
 'Funkcja zwracająca wartość tekstową dla wybranego przycisku (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()
 'Funkcja zwracająca wartość tekstową dla wybranego przycisku (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() 'Akcja, która ma miejsce po kliknięciu („Potwierdź swój wybór”)
     Range(column_value & row_value) = "Cell chosen!"  '„Wybrano komórkę!”
     'column_value i row_value to wartości zwracane przez te funkcje
     Unload Me
 End Sub

Pozostało nam już tylko stworzyć procedurę, która sprawdzi, czy przyciski opcji zostały wybrane poprawnie (poprzez wywołanie dwóch funkcji) i w razie potrzeby aktywuje ten przycisk.

Ponownie weryfikacja odbywa się w ramach osobnej procedury, aby uniknąć 10-krotnego kopiowania kodu dla każdego zdarzenia każdego przycisku opcji:

Private Sub activate_button()
 'Aktywacja przycisku, jeśli warunek został pomyślnie przetestowany
     If column_value <> "" And row_value <> "" Then
     'column_value i row_value to wartości zwracane przez te funkcje
         CommandButton1.Enabled = True
         CommandButton1.Caption = "Confirm your selection"  '„Potwierdź swój wybór”
     End If
End Sub

Private Sub OptionButton11_Click()
     activate_button 'Rozpoczynamy procedurę „aktywuj_przycisk”.
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

Tutaj możesz zobaczyć przykład w gotowym pliku Excel: userform3b.xls