TOP

VBA-Lecția 9. Proceduri și funcții

În orice limbaj de programare există concepte precum proceduri și funcții. De asemenea, au fost incluse în limbajul de programare încorporat VBA pentru Excel.

  • O funcție este o rutină care returnează un rezultat. Un apel de funcție este o expresie și poate fi folosit în alte expresii sau în partea dreaptă a unei instrucțiuni de atribuire (notat în VBA ca "Function");
  • O procedură este orice rutină care nu este o funcție. Marcat în VBA ca „Sub” (din cuvântul „subrutină”).

  • Proceduri (Public - Private)

    În acest moment, toate procedurile pe care le-am creat sunt de tip Public, ceea ce înseamnă că sunt accesibile din orice modul.

     Sub example()
     
     'Identic cu:
     Public Sub example()
    

    Pentru a face procedura disponibilă doar într-un anumit modul, se folosește cuvântul cheie Private:

    Private Sub example()
    

    Executarea unei proceduri de la mijlocul altei proceduri

    Pentru a executa o procedură dintr-o altă procedură, introduceți pur și simplu numele acesteia.

    Iată un exemplu foarte simplu în acest sens:

    Private Sub warning()
        MsgBox "Caution !!!" '"AVERTIZARE!"
    End Sub
    
    Sub macro_test()
        If Range("A1") = "" Then
            warning '=> executați procedura „warning”
        End If
        'etc...
    End Sub
    

    Argumente

    Argumentele fac posibilă utilizarea valorilor dintr-o procedură într-o subprocedură (rețineți că, implicit, variabilele sunt disponibile doar din procedura în care au fost declarate).

    Private Sub warning(var_text As String)
        MsgBox "Caution : " & var_text & " !"
    End Sub
    
    Sub macro_test()
        If Range("A1") = "" Then
            warning "empty cell"               '"celula goala"
        ElseIf Not IsNumeric(Range("A1")) Then
            warning "non-numerical value"      '„valoare non-numerică”
        End If
    End Sub
    

    A fost adăugat un argument la procedura „warning”, în acest caz este o variabilă „var_text” de tip „String” (panglică):

    Private Sub warning(var_text As String)
    

    Această rutină ia un argument, așa că trebuie să punem o valoare după „warning” pentru a o executa:

    warning "empty cell"
    

    Când vrem să scriem mai multe argumente, atunci acestea ar trebui separate prin virgule.

    Argumente opționale

    În mod implicit, dacă procedura are argumente, atunci acestea trebuie furnizate, iar dacă nu sunt furnizate, atunci procedura nu va fi executată.

    Un argument opțional poate fi adăugat după unul obligatoriu, folosind cuvântul cheie Opțional. Exemplu:

    Private Sub dialog_boxes(last_name As String, Optional first_name, Optional age)
    

    Această procedură poate fi acum executată cu sau fără un argument opțional, ca aici:

     'Exemplul 1: afișați numele de familie:
     dialog_boxes last_name1
       
     'Exemplul 2: afișăm numele și prenumele:
     dialog_boxes last_name1, first_name1
       
     'Exemplul 3: afișați numele de familie și vârsta:
     dialog_boxes last_name1, , age1
       
     'Exemplul 4: afișați numele de familie, prenumele și vârsta:
     dialog_boxes last_name1, first_name1, age1
    

    Argumentele trebuie introduse în ordinea corectă.

    Pentru a testa dacă un argument opțional este prezent într-o procedură, folosim funcția IsMissing. Această funcție este compatibilă doar cu unele tipuri de funcții (de tip Variant) și acest lucru este critic deoarece tipul argumentelor opționale nu a fost declarat (tip nedeclarat = Variant).

    Iată un exemplu care utilizează cele două fragmente de cod discutate mai sus:

    Sub macro_test()
    
        Dim last_name1 As String, first_name1 As String, age1 As Integer
       
        last_name1 = Range("A1")
        first_name1 = Range("B1")
        age1 = Range("C1")
    
        'Exemplul 1: afișați numele de familie:
        dialog_boxes last_name1
       
        'Exemplul 2: afișăm numele și prenumele:
        dialog_boxes last_name1, first_name1
       
        'Exemplul 3: afișați numele de familie și vârsta:
        dialog_boxes last_name1, , age1
       
        'Exemplul 4: afișați numele de familie, prenumele și vârsta:
        dialog_boxes last_name1, first_name1, age1
    
    End Sub
    
    Private Sub dialog_boxes(last_name As String, Optional first_name, Optional age)
       
        If IsMissing(age) Then 'Dacă variabila vârstă lipsește...
           
            If IsMissing(first_name) Then 'Dacă variabila first_name lipsește, atunci
            							  'va fi afișat doar numele de familie
               MsgBox last_name
            Else 'În caz contrar, vor fi afișate numele de familie și prenumele
               MsgBox last_name & " " & first_name
            End If
           
        Else 'Dacă este prezentă variabila vârstă...
    
            If IsMissing(first_name) Then 'Dacă variabila first_name lipsește, atunci
                                          'vor fi afișate numele de familie și vârsta
               MsgBox last_name & ", " & age & " years old"
            Else 'În caz contrar, vor fi afișate numele de familie, prenumele și vârsta
               MsgBox last_name & " " & first_name & ", " & age & " years old"
            End If
       
        End If
           
    End Sub
    

    Vedea poza de mai jos (exemplul 1):

    ByRef - ByVal

    În mod implicit, argumentele sunt de tip ByRef, ceea ce înseamnă că dacă o variabilă este transmisă ca argument, va fi transmisă și o referință la aceasta. Cu alte cuvinte, dacă o variabilă a fost modificată printr-o altă sub-procedură, aceasta va fi modificată și în procedura exterioară care apelează acea sub-procedură.

    Exemplu:

    Sub macro_test()
        Dim var_number As Integer
        
        var_number = 30
        calcul_square var_number
       
        MsgBox var_number
    End Sub
    
    Private Sub calcul_square(ByRef var_value As Integer) 'ByRef este opțional
                                                          '(este valoarea implicită)
        var_value = var_value * var_value
    End Sub
    

    Pentru a fi clar, mai jos este un exemplu despre ceea ce se va întâmpla dacă macro-ul începe să se execute:

     var_number = 30
     'Valoarea inițială a variabilei „var_number” este 30
    
     calcul_square var_number
     'Sub-procedura este rulată cu „var_number” ca argument
    
     Private Sub calcul_square(ByRef var_value As Integer)
     'Variabila „var_value” servește într-o oarecare măsură pentru acces rapid la variabila „var_number”,
     'ceea ce înseamnă că dacă variabila „var_value” este modificată, variabila „var_number” va fi, de asemenea, modificată
     '(și nu trebuie să aibă același nume)
     var_value = var_value * var_value
     'Valoarea variabilei „var_value” este modificată (și, prin urmare, „var_number” este modificată în același timp)
    
     End Sub
     'Sfârșitul subprocedurii
    
     MsgBox var_number
     'Variabila „var_number” a fost schimbată, astfel încât 900 va fi acum afișat în dialog
    

    A doua metodă este să utilizați ByVal.

    Spre deosebire de ByRef, care transmite o referință (etichetă), ByVal transmite o valoare, ceea ce înseamnă că valoarea transmisă ca argument nu a fost modificată.

    Mai jos puteți vedea cum funcționează codul anterior și ByVal:

     var_number = 30
     'Valoarea inițială a variabilei „var_number” este 30
    
     calcul_square var_number
     'Sub-procedura este rulată cu „var_number” ca argument
    
     Private Sub calcul_square(ByVal var_value As Integer)
     'Variabila „var_value” copiază valoarea variabilei „var_number” (cele 2 variabile nu sunt legate)
    
     var_value = var_value * var_value
     'Valoarea variabilei „var_value” s-a schimbat
    
     End Sub
     'Sfârșitul sub-procedurii (în acest exemplu, subprocedura nu are efect asupra nimicului)
    
     MsgBox var_number
     'Variabila „var_number” nu a fost modificată și, prin urmare, 30 va fi afișat în caseta de dialog
    

    Ce trebuie să rețineți: Folosiți ByVal când variabila nu trebuie schimbată.

    Funcții

    Principala diferență dintre o procedură și o funcție este că o funcție returnează o valoare.

    Iată un exemplu simplu:

    Function square(var_number)
        square = var_number ^ 2 'Funcția „pătrat” returnează valoarea „rădăcină pătrată”.
    End Function
    
    Sub macro_test()
        Dim result As Double
        result = square(9.876) 'Variabilei rezultat i se atribuie valoarea care a fost calculată de funcție
        MsgBox result 'Rezultatul este afișat (în acest caz pătratul 9,876)
    End Sub
    

    Funcția poate fi utilizată pe o foaie de lucru la fel ca orice altă funcție din Excel.

    De exemplu, pentru a obține pătratul valorii introduse în celula A1: