› Sviluppare funzionalita su Microsoft Office con VBA › Variabili: dichiararle o no
-
AutoreArticoli
-
Mi è capitato in quasi tutti i th , dove è intervenuto vecchio frac,
che consigliava di dichiarare le variabili nel codice VBA.Ma perchè?, era la domanda che mi ponevo. Sfogliando le pagine del libro "Excel® 2013 Power Programming with VBA" di John Walkenbach, ho trovato, per cosi dire, la risposta.Le variabili non dichiarate,vengono considerate come Variant( questo lo sapevamo 🙂 ), pero il libro riporta due routine , che posto, dove si puo vedere il tempo che intercorre fra l'eleborazione della routine con le variabili dichiarate e quella dove le variabili non sono dichiarate.Qui n una routine dove le variabili sono dichiarete è molto veloce rispetto a quella dove non si dichiarano.Sub TimeTest1() ' VARIABLES DECLARED Dim x As Long, y As Long Dim A As Double, B As Double, C As Double Dim i As Long, j As Long Dim StartTime As Date, EndTime As Date ' Store the starting time StartTime = Timer ' Perform some calculations x = 0 y = 0 For i = 1 To 10000 x = x + 1 y = x + 1 For j = 1 To 10000 A = x + y + i B = y - x - i C = x / y * i Next j Next i ' Get ending time EndTime = Timer ' Display total time in seconds MsgBox Format(EndTime - StartTime, "0.0") End Sub Sub TimeTest2() ' VARIABLES NOT DECLARED ' Store the starting time StartTime = Timer ' Perform some calculations x = 0 y = 0 For i = 1 To 10000 x = x + 1 y = x + 1 For j = 1 To 10000 A = x + y + i B = y - x - i C = x / y * i Next j Next i ' Get ending time EndTime = Timer ' Display total time in seconds MsgBox Format(EndTime - StartTime, "0.0") End SubQual è il punto di avere gusti diversi, se non mostrare che i cervelli lavorano diversamente, che pensiamo diversamente? ( Alan Turing)
Sempre il mare, uomo libero, amerai!
( Charles Baudelaire )Dichiarare una variabile di un certo tipo significa allocarle uno spazio in memoria. Quindi il compilatore predispone un certo quantitativo di bytes (dipende dal tipo dichiarato) destinato ad accogliere i dati attesi. Pertanto è come prenotare una stanza in hotel: quando il dato arriva la trova già pronta, mentre ciò non avviene quando le variabili non sono predichiarate (parliamo di VBA, non di altri linguaggi dove le cose stanno un po' diversamente).
Naturalmente ciò incide sulle prestazioni (le performances sono molto importanti in quasi tutti i programmi).
Ma incide anche sull'affidabilità: ci sono esempi in cui omettere Option Explicit può essere anche dannoso e portare a risultati non previsti. Mi ricordo su questo una vecchia discussione (una lezione veramente) di scossa (se posso la cerco).
Ho trovato quel vecchio thread di scossa (2015). Ne riporto i passi essenziali perchè è naturalmente tutto vero e attuale:
Scrive scossa:
...Vorrei far riflettere sull'importanza di usare Option Explicit e di dichiarare le variabili in modo "esplicito" e "preciso", quindi non limitarsi al semplice Dim miaVariabile, ma specificarne anche il tipo.
Per farlo mi servo di due codici molto semplici ed elementari.
Aprite una nuova cartella di Excel.
In A1 di un foglio scrivete Pippo poi mettete questo codice in un modulo standard e provate ad eseguirlo passo-passo (con F8) e leggendo i commenti nel codice:Option Explicit Sub provaDim() Dim Rng As Range Set Rng = Range("A1") 'ora Rng "rappresenta" la cella A1 MsgBox "tipo: " & TypeName(Rng) & vbCrLf & Rng.Value Rng = 45 'assegno alla cella A1 il valore 45 'perché un oggetto Range per default espone la proprietà Value MsgBox "tipo: " & TypeName(Rng) & vbCrLf & Rng 'questa istruzione è perfettamente valida MsgBox Rng.Address Set Rng = Nothing End SubTutto ha funzionato come doveva funzionare.
Ora proviamo a vedere cosa succede se non dichiariamo la variabile Rng o se la dichiariamo senza specificarne il tipo, sempre provando passo-passo (con F8) questo codice:
Option Explicit Sub provaSenzaDim() Dim Rng Set Rng = Range("A1") 'ora Rng è un Range che "rappresenta" la cella A1 MsgBox "tipo: " & TypeName(Rng) & vbCrLf & Rng.Value Rng = 45 'credendo di assegnare alla cella A1 il valore 45 'in realtà lo converto in integer MsgBox "tipo: " & TypeName(Rng) & vbCrLf & Rng 'e questa istruzione restituisce un errore 'poiché Rng non è più una variabile-oggetto MsgBox Rng.Address Set Rng = Nothing End SubCome vedete, nel secondo codice, avendo dichiarato la variabile Rng solo con Dim (che per default la imposta a Variant), abbiamo combinato un disastro!
Pensate, in un codice un po' più complesso, come è subdolo e difficile da individuare un simile errore!Spero di essere riuscito a mettere un tarlo nella testa dei "pigri" e dei detrattori della dichiarazione delle variabili e di Option Explicit.
C'è un'altra considerazione che dovrebbe nascere dall'osservazione del secondo codice.
Se anziché
Rng = 45
avessi scritto l'istruzione in modo "ortodosso"Rng.Value = 45
indicando quindi esplicitamente la proprietà Value, anche se è la proprietà dell'oggetto range esposta per default, avrei effettivamente assegnato alla cella A1 il valore 45.Quindi: non siate pigri, specificate sempre la proprietà a cui vi volete riferire, anche a costo di apparire ridondanti, il tempo speso in fase di scrittura si ripagherà in minor tempo speso per il debug.
Questa accortezza, insieme a Option Explicit (e conseguente dichiarazione delle variabili) vi porterà in poco tempo e quasi automaticamente a scrivere codice migliore.
Ho quotato tutto perchè davvero sempre attuale. Vi prego, indicate sempre Option Explicit in testa ai vostri moduli. Impostate questa direttiva in modo automatico (nell'editor: Strumenti - Opzioni - Editor > spunta su Dichiarazioni di variabili obbligatoria)!
Di solito io non le dichiaro mai, ma solo per pigrizia, e talvolta capita che il codice non funziona e sono costretto a dichiararne alcune. Quindi non prendete esempio da me ed abituatevi a dichiararle anche se nella maggior parte dei casi non noterete vantaggi tangibili.
patel wrote:Di solito io non le dichiaro mai
😯
patel wrote:Quindi non prendete esempio da me
😀
Bè nulla è obbligatorio, solo caldamente consigliato, e di solito si fa per evitare mal di testa durante il debug e arrabbiature alla ricerca del codice che non gira.
però c'è il rovescio della medaglia, anche una dichiarazione sbagliata può dare problemi, quindi occorre sapere bene quello che si fa
Ciao
Negli ultimi anni su suggerimenti di amici di questo forum, sto sempre più cercando di dichiarare le variabili.
A volte per velocità mi capita di non fare una dichiarazione completa ma le battezzo solamente senza specificare il tipo. (io ho fleggato l'option explicit automatico)
Volevo sottolineare che anche solo lo sforzo di dichiararle mi aiuta ad impostare il codice e in aggiunta mi aiuta nell'evitare e errori di battitura che potrebbero essere generati senza la diciarazione obbligatoria delle variabili.
Devo dire che talvolta (soprattutto con variabili di fogli) ho avuto qualche problema...ad identificare la corretta definizione (sheet, sheets, worksheet,...)
Un grande ringraziamento a tutti
Ciao
Luca
Anche un semplice
Dim a, b, cè valido e sufficiente però è inefficiente e non esime da errori.Senza specificare il tipo (As qualcosa) le variabili vengono comunque inizializzate a ricevere qualsiasi tipo, al momento dell'assegnazione (diventano cioè Variant e diventano mutevoli).
Provate il pezzetto di codice:
Option Explicit Sub test() Dim var var = 15 MsgBox var var = "testo" MsgBox var var = 20 / 3 MsgBox var End SubDi volta in volta, la variabile Variant "var" assume tipi differenti e il compilatore non batte ciglio, cambia il tipo di dato senza farsi problemi.
I problemi se li farebbe, e giustamente, predichiarando un tipo di dato: cambiate la dichiarazione con
Dim var As Integere vedete cosa succede.Nota al volo: dichiarare
Dim a, b, c as integerNON tipizza le tre variabili a Integer ma solo "c", le prime due restano Variant. Quindi occhio anche a questo aspetto del problema.Questo solo per restare in VBA base, mentre per quello che riguarda gli oggetti specifici di un'applicazione, non sono tipi di dato veri e propri ma definizione di tipi oggetto.
Dichiarare
Dim r as Rangenon vuol dire niente in VBA, ma ha senso in Excel (e solo in Excel) e la fatica cui si riferisce Luca è rivolta al fatto di sapere in anticipo con quale oggetto vogliamo trattare. Al limite andrebbe bene perfino Object (che è il tipo predefinito di VBA per ogni tipo di oggetto), con l'osservazione, ancora una volta, che identificare un tipo corretto fa allocare la giusta quantità di byte in memoria con conseguente risparmio di spazio e tempo di esecuzione.Fine del sermone 😀
-
AutoreArticoli
