TOP

VBA-Lekcja 9. Procedury i funkcje

W każdym języku programowania istnieją takie pojęcia jak procedury i funkcje. Zostały one również uwzględnione we wbudowanym języku programowania VBA dla Excel.

  • Funkcja to procedura zwracająca wynik. Wywołanie funkcji jest wyrażeniem i może być użyte w innych wyrażeniach lub po prawej stronie instrukcji przypisania (oznaczone w VBA jako "Function");
  • Procedura to dowolna procedura, która nie jest funkcją. Oznaczone w VBA jako „Sub” (od słowa „podprogram”).

  • Procedury (Public - Private)

    W tym momencie wszystkie utworzone przez nas procedury są typu Public, co oznacza, że są dostępne z dowolnego modułu.

    1. Sub example()  
    2.   
    3. 'Identyczne z:  
    4. Public Sub example()  

    Aby procedura była dostępna tylko w określonym module, stosuje się słowo kluczowe Private:

    1. Private Sub example()  

    Uruchamianie procedury ze środka innej procedury

    Aby wykonać procedurę z poziomu innej procedury, wystarczy wpisać jej nazwę.

    Oto bardzo prosty przykład:

    1. Private Sub warning()  
    2.     MsgBox "Caution !!!" '"OSTRZEŻENIE!"  
    3. End Sub  
    4.   
    5. Sub macro_test()  
    6.     If Range("A1") = "" Then  
    7.         warning '=> wykonaj procedurę „warning”  
    8.     End If  
    9.     'itp...  
    10. End Sub  

    Argumenty

    Argumenty umożliwiają wykorzystanie wartości z procedury w podprocedurze (pamiętaj, że domyślnie zmienne są dostępne tylko z procedury, w której zostały zadeklarowane).

    1. Private Sub warning(var_text As String)  
    2.     MsgBox "Caution : " & var_text & " !"  
    3. End Sub  
    4.   
    5. Sub macro_test()  
    6.     If Range("A1") = "" Then  
    7.         warning "empty cell"               '„pusta komórka”  
    8.     ElseIf Not IsNumeric(Range("A1")) Then  
    9.         warning "non-numerical value"      '„wartość nienumeryczna”  
    10.     End If  
    11. End Sub  

    Do procedury „warning” dodano argument, w tym przypadku jest to zmienna „var_text” typu „String” (wstążka):

    1. Private Sub warning(var_text As String)  

    Ta procedura przyjmuje argument, więc aby ją wykonać, musimy umieścić wartość po „warning”:

    1. warning "empty cell"  

    Gdy chcemy napisać kilka argumentów, wówczas należy je oddzielić przecinkami.

    Opcjonalne argumenty

    Domyślnie, jeśli procedura posiada argumenty, to należy je podać, a jeśli nie zostaną podane, to procedura nie zostanie wykonana.

    Opcjonalny argument można dodać po obowiązkowym, używając słowa kluczowego Opcjonalne. Przykład:

    1. Private Sub dialog_boxes(last_name As StringOptional first_name, Optional age)  

    Tę procedurę można teraz wykonać z opcjonalnym argumentem lub bez niego, jak tutaj:

    1. 'Przykład 1: wyświetl nazwisko:  
    2. dialog_boxes last_name1  
    3.     
    4. 'Przykład 2: wyświetlamy nazwisko i imię:  
    5. dialog_boxes last_name1, first_name1  
    6.     
    7. 'Przykład 3: wyświetl nazwisko i wiek:  
    8. dialog_boxes last_name1, , age1  
    9.     
    10. 'Przykład 4: wyświetl nazwisko, imię i wiek:  
    11. dialog_boxes last_name1, first_name1, age1  

    Argumenty należy wprowadzić we właściwej kolejności.

    Aby sprawdzić, czy w procedurze występuje opcjonalny argument, używamy funkcji IsMissing. Ta funkcja jest kompatybilna tylko z niektórymi typami funkcji (typu Variant) i jest to krytyczne, ponieważ nie zadeklarowano typu opcjonalnych argumentów (niezadeklarowany typ = Variant).

    Oto przykład wykorzystujący dwa fragmenty kodu omówione powyżej:

    1. Sub macro_test()  
    2.   
    3.     Dim last_name1 As String, first_name1 As String, age1 As Integer  
    4.      
    5.     last_name1 = Range("A1")  
    6.     first_name1 = Range("B1")  
    7.     age1 = Range("C1")  
    8.   
    9.     'Przykład 1: wyświetl nazwisko:  
    10.     dialog_boxes last_name1  
    11.      
    12.     'Przykład 2: wyświetlamy nazwisko i imię:  
    13.     dialog_boxes last_name1, first_name1  
    14.      
    15.     'Przykład 3: wyświetl nazwisko i wiek:  
    16.     dialog_boxes last_name1, , age1  
    17.      
    18.     'Przykład 4: wyświetl nazwisko, imię i wiek:  
    19.     dialog_boxes last_name1, first_name1, age1  
    20.   
    21. End Sub  
    22.   
    23. Private Sub dialog_boxes(last_name As StringOptional first_name, Optional age)  
    24.      
    25.     If IsMissing(age) Then 'Jeśli brakuje zmiennej wieku...  
    26.          
    27.         If IsMissing(first_name) Then 'Jeśli brakuje zmiennej imię_imię, to  
    28.                                       'zostanie wyświetlone tylko nazwisko  
    29.            MsgBox last_name  
    30.         Else 'W przeciwnym razie zostanie wyświetlone nazwisko i imię  
    31.            MsgBox last_name & " " & first_name  
    32.         End If  
    33.          
    34.     Else 'Jeśli zmienna wieku jest obecna...  
    35.   
    36.         If IsMissing(first_name) Then 'Jeśli brakuje zmiennej imię_imię, to  
    37.                                       'wyświetli się nazwisko i wiek  
    38.            MsgBox last_name & ", " & age & " years old"  
    39.         Else 'W przeciwnym razie zostanie wyświetlone nazwisko, imię i wiek  
    40.            MsgBox last_name & " " & first_name & ", " & age & " years old"  
    41.         End If  
    42.      
    43.     End If  
    44.          
    45. End Sub  

    Widzieć zdjęcie poniżej (przykład 1):

    ByRef - ByVal

    Domyślnie argumenty są typu ByRef, co oznacza, że jeśli zmienna zostanie przekazana jako argument, zostanie również przekazane odwołanie do niej. Innymi słowy, jeśli zmienna została zmieniona przez inną podprocedurę, zostanie ona również zmieniona w procedurze zewnętrznej, która wywołuje tę podprocedurę.

    Przykład:

    1. Sub macro_test()  
    2.     Dim var_number As Integer  
    3.       
    4.     var_number = 30  
    5.     calcul_square var_number  
    6.      
    7.     MsgBox var_number  
    8. End Sub  
    9.   
    10. Private Sub calcul_square(ByRef var_value As Integer'ByRef jest opcjonalne  
    11.                                                       '(jest wartością domyślną)  
    12.     var_value = var_value * var_value  
    13. End Sub  

    Aby było jasne, poniżej znajduje się przykład tego, co się stanie, jeśli makro zostanie uruchomione:

    1. var_number = 30  
    2. 'Początkowa wartość zmiennej „var_number” wynosi 30  
    3.   
    4. calcul_square var_number  
    5. 'Podprocedura jest uruchamiana z argumentem „var_number”.  
    6.   
    7. Private Sub calcul_square(ByRef var_value As Integer)  
    8. 'Zmienna „var_value” służy w pewnym stopniu do szybkiego dostępu do zmiennej „var_number”,  
    9. 'co oznacza, że jeśli zmienna „var_value” zostanie zmieniona, zmienna „var_number” również zostanie zmieniona  
    10. '(i nie muszą mieć tej samej nazwy)  
    11. var_value = var_value * var_value  
    12. 'Zmienia się wartość zmiennej „var_value” (a więc jednocześnie zmienia się także „var_number”)  
    13.   
    14. End Sub  
    15. 'Koniec podprocedury  
    16.   
    17. MsgBox var_number  
    18. 'Zmienna „var_number” została zmieniona i w oknie dialogowym będzie teraz wyświetlana liczba 900  

    Drugą metodą jest użycie ByVal.

    W przeciwieństwie do ByRef, które przekazuje referencję (etykietę), ByVal przekazuje wartość, co oznacza, że wartość przekazana jako argument nie została zmodyfikowana.

    Poniżej możesz zobaczyć, jak działa poprzedni kod i ByVal:

    1. var_number = 30  
    2. 'Początkowa wartość zmiennej „var_number” wynosi 30  
    3.   
    4. calcul_square var_number  
    5. 'Podprocedura jest uruchamiana z argumentem „var_number”.  
    6.   
    7. Private Sub calcul_square(ByVal var_value As Integer)  
    8. 'Zmienna „var_value” kopiuje wartość zmiennej „var_number” (obie zmienne nie są ze sobą powiązane)  
    9.   
    10. var_value = var_value * var_value  
    11. 'Wartość zmiennej „var_value” uległa zmianie  
    12.   
    13. End Sub  
    14. 'Koniec podprocedury (w tym przykładzie podprocedura nie ma na nic wpływu)  
    15.   
    16. MsgBox var_number  
    17. 'Zmienna „var_number” nie została zmieniona, dlatego w oknie dialogowym zostanie wyświetlona liczba 30  

    O czym musisz pamiętać: Użyj ByVal, gdy zmienna nie powinna być zmieniana.

    Funkcje

    Główna różnica między procedurą a funkcją polega na tym, że funkcja zwraca wartość.

    Oto prosty przykład:

    1. Function square(var_number)  
    2.     square = var_number ^ 2 'Funkcja „kwadrat” zwraca wartość „pierwiastka kwadratowego”.  
    3. End Function  
    4.   
    5. Sub macro_test()  
    6.     Dim result As Double  
    7.     result = square(9.876) 'Zmiennej wynikowej przypisuje się wartość obliczoną przez funkcję  
    8.     MsgBox result 'Wyświetlany jest wynik (w tym przypadku kwadrat 9,876)  
    9. End Sub  

    Funkcji można używać w arkuszu, tak jak każdej innej funkcji w Excel.

    Na przykład, aby uzyskać kwadrat wartości wprowadzonej w komórce A1: