In qualsiasi linguaggio di programmazione esistono concetti come procedure e funzioni. Sono stati inclusi anche nel linguaggio di programmazione integrato VBA per Excel.
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()
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
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.
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):
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.
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: