TOP

VBA-Lezione 9. Procedure e funzioni

In qualsiasi linguaggio di programmazione esistono concetti come procedure e funzioni. Sono stati inclusi anche nel linguaggio di programmazione integrato VBA per Excel.

  • Una funzione è una routine che restituisce un risultato. Una chiamata di funzione è un'espressione e può essere utilizzata in altre espressioni o sul lato destro di un'istruzione di assegnazione (denotata in VBA come "Function");
  • Una procedura è qualsiasi routine che non sia una funzione. Contrassegnato in VBA come "Sub" (dalla parola "subroutine").

  • Procedure (Public - Private)

    A questo punto tutte le procedure che abbiamo creato sono di tipo Public, ovvero accessibili da qualsiasi modulo.

     Sub example()
     
     'Uguale a:
     Public Sub example()
    

    Per rendere la procedura disponibile solo in un determinato modulo viene utilizzata la parola chiave Private:

    Private Sub example()
    

    Esecuzione di una procedura dal centro di un'altra procedura

    Per eseguire una procedura dall'interno di un'altra procedura, è sufficiente inserirne il nome.

    Ecco un esempio molto semplice di questo:

    Private Sub warning()
        MsgBox "Caution !!!" '"AVVERTIMENTO!"
    End Sub
    
    Sub macro_test()
        If Range("A1") = "" Then
            warning '=> esegui la procedura "warning"
        End If
        'eccetera...
    End Sub
    

    argomenti

    Gli argomenti consentono di utilizzare i valori di una procedura in una sottoprocedura (ricordate che per impostazione predefinita le variabili sono disponibili solo dalla procedura in cui sono state dichiarate).

    Private Sub warning(var_text As String)
        MsgBox "Caution : " & var_text & " !"
    End Sub
    
    Sub macro_test()
        If Range("A1") = "" Then
            warning "empty cell"               '"cella vuota"
        ElseIf Not IsNumeric(Range("A1")) Then
            warning "non-numerical value"      '"valore non numerico"
        End If
    End Sub
    

    Alla procedura è stato aggiunto un argomento "warning", in questo caso si tratta di una variabile "var_text" di tipo "String" (ribbon):

    Private Sub warning(var_text As String)
    

    Questa routine accetta un argomento, quindi dobbiamo inserire un valore dopo "warning" per eseguirla:

    warning "empty cell"
    

    Quando vogliamo scrivere più argomenti, allora dovrebbero essere separati da virgole.

    Argomenti facoltativi

    Per impostazione predefinita, se la procedura ha argomenti, questi devono essere forniti, altrimenti la procedura non verrà eseguita.

    È possibile aggiungere un argomento facoltativo dopo uno obbligatorio, utilizzando la parola chiave Opzionale. Esempio:

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

    Questa procedura può ora essere eseguita con o senza un argomento opzionale, come qui:

     'Esempio 1: visualizzare il cognome:
     dialog_boxes last_name1
       
     'Esempio 2: visualizziamo il cognome e il nome:
     dialog_boxes last_name1, first_name1
       
     'Esempio 3: visualizzare il cognome e l'età:
     dialog_boxes last_name1, , age1
       
     'Esempio 4: visualizzare cognome, nome ed età:
     dialog_boxes last_name1, first_name1, age1
    

    Gli argomenti devono essere inseriti nell'ordine corretto.

    Per verificare se in una procedura è presente un argomento facoltativo, utilizziamo la funzione IsMissing. Questa funzione è compatibile solo con alcuni tipi di funzione (di tipo Variant) e questo è fondamentale perché il tipo degli argomenti opzionali non è stato dichiarato (tipo non dichiarato = Variant).

    Ecco un esempio che utilizza i due frammenti di codice discussi sopra:

    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")
    
        'Esempio 1: visualizzare il cognome:
        dialog_boxes last_name1
       
        'Esempio 2: visualizziamo il cognome e il nome:
        dialog_boxes last_name1, first_name1
       
        'Esempio 3: visualizzare il cognome e l'età:
        dialog_boxes last_name1, , age1
       
        'Esempio 4: visualizzare cognome, nome ed età:
        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 'Se manca la variabile età...
           
            If IsMissing(first_name) Then 'Se manca la variabile first_name, allora
            							  'verrà visualizzato solo il cognome
               MsgBox last_name
            Else 'Altrimenti verranno visualizzati il cognome e il nome
               MsgBox last_name & " " & first_name
            End If
           
        Else 'Se la variabile età è presente...
    
            If IsMissing(first_name) Then 'Se manca la variabile first_name, allora
                                          'verranno visualizzati il cognome e l'età
               MsgBox last_name & ", " & age & " years old"
            Else 'Altrimenti verranno visualizzati il cognome, il nome e l'età
               MsgBox last_name & " " & first_name & ", " & age & " years old"
            End If
       
        End If
           
    End Sub
    

    Vedere immagine qui sotto (esempio 1):

    ByRef - ByVal

    Per impostazione predefinita, gli argomenti sono di tipo ByRef, il che significa che se una variabile viene passata come argomento, verrà passato anche un riferimento ad essa. In altre parole, se una variabile è stata modificata da un'altra sottoprocedura, verrà modificata anche nella procedura esterna che richiama quella sottoprocedura.

    Esempio:

    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 è facoltativo
                                                          '(è il valore predefinito)
        var_value = var_value * var_value
    End Sub
    

    Per maggiore chiarezza, di seguito è riportato un esempio di cosa accadrà se si avvia l'esecuzione della macro:

     var_number = 30
     'Il valore iniziale della variabile "var_number" è 30
    
     calcul_square var_number
     'La procedura secondaria viene eseguita con "var_number" come argomento
    
     Private Sub calcul_square(ByRef var_value As Integer)
     'La variabile "var_value" serve in una certa misura per un rapido accesso alla variabile "var_number",
     'ciò significa che se viene modificata la variabile "var_value", verrà modificata anche la variabile "var_number".
     '(e non devono avere lo stesso nome)
     var_value = var_value * var_value
     'Viene modificato il valore della variabile "var_value" (e quindi contemporaneamente viene modificato anche "var_number")
    
     End Sub
     'Fine della sottoprocedura
    
     MsgBox var_number
     'La variabile "var_number" è stata modificata, quindi nella finestra di dialogo verrà ora visualizzato 900
    

    Il secondo metodo consiste nell'utilizzare ByVal.

    A differenza di ByRef, che passa un riferimento (etichetta), ByVal passa un valore, il che significa che il valore passato come argomento non è stato modificato.

    Di seguito puoi vedere come funzionano il codice precedente e ByVal:

     var_number = 30
     'Il valore iniziale della variabile "var_number" è 30
    
     calcul_square var_number
     'La procedura secondaria viene eseguita con "var_number" come argomento
    
     Private Sub calcul_square(ByVal var_value As Integer)
     'La variabile "var_value" copia il valore della variabile "var_number" (le 2 variabili non sono correlate)
    
     var_value = var_value * var_value
     'Il valore della variabile "var_value" è cambiato
    
     End Sub
     'Fine della sottoprocedura (in questo esempio la sottoprocedura non ha alcun effetto)
    
     MsgBox var_number
     'La variabile "var_number" non è stata modificata e quindi nella finestra di dialogo verrà visualizzato 30
    

    Cosa devi ricordare: usa ByVal quando la variabile non deve essere modificata.

    Funzioni

    La differenza principale tra una procedura e una funzione è che una funzione restituisce un valore.

    Qui c'è un semplice esempio:

    Function square(var_number)
        square = var_number ^ 2 'La funzione "quadrato" restituisce il valore "radice quadrata".
    End Function
    
    Sub macro_test()
        Dim result As Double
        result = square(9.876) 'Alla variabile di risultato viene assegnato il valore calcolato dalla funzione
        MsgBox result 'Viene visualizzato il risultato (in questo caso il quadrato di 9.876)
    End Sub
    

    La funzione può essere utilizzata su un foglio di lavoro proprio come qualsiasi altra funzione in Excel.

    Ad esempio, per ottenere il quadrato del valore immesso nella cella A1: