Sei sulla pagina 1di 191

EXCEL MACRO 2013

Paolo Guccini
© Apogeo - IF - Idee editoriali Feltrinelli s.r.l.
Socio Unico Giangiacomo Feltrinelli Editore s.r.l.

ISBN edizione cartacea: 9788850332175

Il presente file può essere usato esclusivamente per finalità di carattere personale. Tutti i contenuti
sono protetti dalla Legge sul diritto d'autore.

Nomi e marchi citati nel testo sono generalmente depositati o registrati dalle rispettive case
produttrici.

L'edizione cartacea è in vendita nelle migliori librerie.

Seguici su Twitter @apogeonline


Introduzione

Programmare le macro è contemporaneamente una sfida e un gioco, ed è molto più semplice di


quanto si possa pensare: vederle produrre i risultati desiderati è una soddisfazione notevole; infatti
si può orgogliosamente dire “questo l’ho fatto io!”.
Per chi utilizza con dimestichezza Excel, il mondo delle macro è un passaggio obbligato per
arricchire il foglio elettronico di nuove caratteristiche e funzionalità, di automatismi creati
appositamente per le proprie esigenze.
All’apparenza, le macro sono un mondo molto lontano e per nulla simile a quanto si è esplorato
e conosciuto sul foglio di lavoro. La realtà è molto più semplice ed è sufficiente pensare a quando,
in una cella, si richiama una funzione quale Somma(): non si sa come essa operi, ma si possono
prevedere i risultati che produrrà.
In pratica, come si può realizzare una funzione per il foglio di lavoro che, analogamente alla
funzione nativa Somma(), provveda, per esempio, ad addizionare i valori di un intervallo di celle per
quelle che, tra loro, hanno un valore superiore a 100? è sufficiente premere i tasti ALT+F11 e
digitare all’interno di un modulo una specifica macro, come si vedrà nel Capitolo 3.

Finalità
Questo libro ha un taglio pratico e ha l’obiettivo di indicare con semplicità le tecniche da
adottare nell’ultilizzo delle macro, per ottenere rapidamente i risultati desiderati. L’aspetto più
importante è comprendere che le immense potenzialità delle macro possono essere sfruttate
iniziando con la creazione di quelle più semplici, per aumentarne progressivamente la complessità
fino a realizzare macro (anche dette funzioni o routine) molto articolate, in grado di aprire un
documento, cercare un’informazione, chiedere all’utente cosa fare e agire di conseguenza.

Convenzioni utilizzate nel libro


Nel libro sono presenti alcune note che identificano tipi particolari di informazioni relative agli
argomenti trattati.
NOTA Una nota contiene informazioni interessanti, talvolta tecniche, relative all’argomento trattato. Talvolta riporta
approfondimenti e curiosità.
I termini più importanti compaiono in corsivo alla loro prima occorrenza, nei paragrafi in cui
vengono definiti.
Alcune parole sono stampate in uno stile grafico diverso dal testo corrente per evidenziare che
appartengono a categorie specifiche; di seguito sono riportate le convenzioni adottate.
Menu, comandi, pulsanti, finestre e in genere i nomi degli elementi di interfaccia sono scritti
in corsivo.
Una combinazione di tasti è rappresentata nel formato tasto+tasto; questa codifica significa
che i tasti elencati e separati dal segno + devono essere premuti contemporaneamente.
Una sequenza di comandi da eseguire da menu è segnalata con lo stile grafico:
Strumenti/Opzioni/Generale.
Comandi e istruzioni dei linguaggi di programmazione sono scritti con un carattere
monospaziato.
Capitolo 1

Macro: un modo per dire “programma”

VBA: come iniziare con facilità


In Excel, la macro è un programma scritto con il linguaggio VBA (Visual Basic for Application),
un linguaggio standard che, una volta apprese le caratteristiche principali, permette di essere
utilizzato per realizzare macro o, meglio, programmi, anche in altri software di Microsoft Office
quali Word e Outlook.
Scrivere macro in Excel è relativamente semplice poiché il linguaggio di programmazione VBA
può essere appreso e utilizzato in tempi contenuti. Soprattutto, in Excel è disponibile
un’invidiabile strumento: il registratore di macro.
Esso costituisce lo strumento più semplice e utile per chi desidera avvicinarsi al linguaggio
VBA, in quanto consente di memorizzare tutte le operazioni che vengono normalmente eseguite
dall’utente e trasformarle automaticamente in un vero e proprio programma VBA, il quale può
essere guardato e analizzato per imparare come realizzare le varie istruzioni.
In questo modo, è immediatamente possibile familiarizzare con il VBA e i suoi vari aspetti.

Prima di iniziare: impostare il livello di sicurezza


Fra le versioni 2013, 2010 e le precedenti vi sono differenze nel modo in cui Excel si comporta
con i file contenenti macro: esse sono state pensate per aumentare la sicurezza contro i macro-
virus, ovvero virus scritti in linguaggio VBA e inseriti in file xls. Questo innalzamento dei criteri
di sicurezza, pensati soprattutto per l’utente medio, provvedono a inibire il funzionamento delle
macro, evitando che possano essere eseguiti dei macro-virus.
Ne consegue che neppure le nostre macro potranno funzionare. Diventa quindi indispensabile
sapere come gestire i livelli di sicurezza di Excel. I passi per impostarli sono sono:
aprire il menu File;
selezionare l’ultima voce: Opzioni;
nella finestra Opzioni di Excel, selezionare Centro Protezione;
nella parte destra della finestra fare clic sul pulsante Impostazioni Centro Protezione;
appare la finestra Centro Protezione nella quale si deve selezionare Impostazioni Macro;
infine, viene visualizzata la finestra Centro protezione, ove si può impostare i comportamenti
relativi alla sicurezza che Excel adotterà.

NOTA Nella versione 2010, la procedura è analoga, mentre per la versione 2007 si agisce attraverso il pulsante
Office, ovvero quel pulsante tondo posto in altro a sinistra che ha sostituito il menu File, si accede a un menu in cui
è presente il pulsante Opzioni di Excel, che apre una finestra in cui occorre selezionare, dall’elenco di sinistra, la
voce Centro protezione. Il pulsante Impostazioni Centro protezione consente di accedere alla finestra successiva,
all’interno della quale si può definire il livello di sicurezza.

Figura 1.1 A sinistra il menu File aperto.

Figura 1.2 Un clic sul pulsante Opzioni di Excel visualizza la finestra che consente di gestire varie configurazioni.
Figura 1.3 In questa finestra è possibile definire il comportamento che Excel terrà quando viene aperta una cartella
contenente macro.

La finestra Centro protezione ha un elenco a sinistra in cui sono presenti diverse voci (Figura
1.3) che consentono di configurare altrettanti insiemi di parametri relativi alla sicurezza e alla
privacy: quella riguardante il livello di sicurezza è Impostazioni macro, che consente di scegliere
quattro diversi livelli, elencati di seguito.
Disattiva tutte le macro senza notifica: è il massimo livello di sicurezza, in cui ogni macro
viene disattivata senza avvisare l’utente. In questo modo nessuna macro funzionerà, riducendo
drasticamente ogni rischio di infezione da virus basati sulle macro.
Disattiva tutte le macro con notifica: ogni volta che viene aperto un documento Excel
contenente macro, sarà visualizzato un messaggio per chiedere se si preferisce attivare o
disattivare le macro contenute. Questa scelta rappresenta un eccellente compromesso tra
sicurezza e la possibilità di utilizzare macro, dal momento che viene mantenuto il controllo
sull’apertura di documenti contenenti macro: è l’utente stesso che decide quale documento
può godere del privilegio di avere le macro attivate. Occorre notare che la scelta non è
permanente: ogni volta che lo stesso documento viene aperto, l’utente riceverà la medesima
richiesta di conferma.
Disattiva tutte le macro tranne quelle con firma digitale: le macro possono contenere una
firma digitale, una sorta di identificativo univoco di colui che le ha create. Questa scelta non
è attualmente una delle più convenienti poiché le macro non hanno quasi mai questa firma e
quindi vengono immediatamente disattivate.
Attiva tutte le macro: questa selezione è utilizzabile solo su un computer che non è esposto a
rischi di virus, in quanto ogni documento che viene aperto gode della facoltà di eseguire
automaticamente le macro contenute al suo interno; quindi se esso contiene un virus che il
software antivirus non ha rilevato, il computer ne verrà infettato.
Per chi vuole realizzare e utilizzare macro, la scelta più conveniente è Disattiva tutte le macro
con notifica. Dopo avere fatto clic su OK ed essere tornati al foglio di Excel, è possibile
occuparsi della realizzazione della prima macro.

Avviare il registratore
Il registratore di macro si avvia mediante la voce Visualizza della barra multifunzione (la
versione 2007 utilizzava il menu Sviluppo/Registra), che, come ultimo elemento, ha il gruppo
Macro nel quale appare un pulsante composto da due parti: il pulsante vero e proprio con la sua
icona e, immediatamente sotto, la scritta Macro: essa è in realtà un secondo pulsante che attiva un
menu (Figura 1.4) nel quale va selezionata la voce Registra Macro.

Figura 1.4 Il menu attivabile con la parte inferiore del pulsante Macro, accessibile dalla voce Visualizza della barra
multifunzione.

Verrà visualizzata una finestra (Figura 1.5), che contiene le opzioni illustrate di seguito.

Figura 1.5 La finestra di inizio creazione di una macro mediante il registratore.

La casella Nome macro: consente di assegnare un nome che renda la macro facilmente
individuabile e aiuti a comprenderne lo scopo.
La casella Tasto di scelta rapida: se la macro che si sta per memorizzare verrà utilizzata di
frequente, allora può essere utile associare a essa una combinazione di tasti basata su
Ctrl+lettera oppure Ctrl+Maiusc+lettera; questa opzione consentirà di eseguirla velocemente
senza utilizzare la finestra di avvio delle macro.
La lista Memorizza macro in: consente di indicare la cartella nella quale la macro sarà
memorizzata. Esistono tre possibilità: la cartella corrente, una nuova che viene
automaticamente creata e quella personale; quest’ultima è la cartella che Excel apre
automaticamente a ogni esecuzione, per cui ogni macro memorizzata al suo interno sarà
sempre visibile e disponibile per essere eseguita su tutti i documenti di Excel.
La casella Descrizione: consente di inserire una nota descrittiva della macro; verrà
visualizzata sulla parte inferiore della finestra utilizzata per richiamare le macro per
l’esecuzione.
Dopo aver fatto clic sul pulsante OK il registratore di macro è attivo e si può iniziare a eseguire
le operazioni che si desidera memorizzare.

Macro con riferimenti relativi e assoluti


I concetti di riferimenti relativi e assoluti applicati a una macro riguardano la modalità con cui
essi saranno memorizzati dal registratore: è possibile ottenere macro che utilizzino solo uno dei
due sistemi, oppure entrambi.
Questo aspetto è fondamentale per ottenere macro che possano essere utilizzate in più parti del
foglio: per esempio, se si realizza una macro che provvede ad assegnare una determinata
formattazione alle celle, non si dovranno utilizzare riferimenti assoluti altrimenti questa opererà
sempre sulle stesse celle. Per passare da un tipo di riferimento all’altro si utilizza il pulsante Usa
riferimenti relativi (visibile nella Figura 1.4): se esso appare bordato significa che è attivo,
quindi i riferimenti saranno memorizzati in formato relativo, altrimenti verrà utilizzato il sistema
assoluto.

Fine della registrazione


Qualsiasi operazione venga eseguita sarà memorizzata fino al momento in cui la registrazione
non viene interrotta mediante l’apposito pulsante Interrompi registrazione, il quale sostituisce
temporaneamente Registra macro nel menu visibile nella Figura 1.4. A questo punto ogni altra
operazione non verrà memorizzata, mentre la macro è pronta per essere riutilizzata.

Eseguire una macro registrata


Per eseguire una macro occorre selezionare la voce Visualizza della barra multifunzione e fare
clic sul pulsante Macro (quindi senza attivare il menu della Figura 1.4): si attiva la finestra Macro
che mostra nella parte centrale un elenco di tutte le macro disponibili (Figura 1.6).
Dopo avere selezionato quella che si desidera eseguire, occorre fare clic sul pulsante Esegui: la
finestra Macro si chiuderà e la macro verrà eseguita. Se la macro utilizza i riferimenti relativi,
allora considererà la cella attiva sul foglio di lavoro attivo come punto di partenza.

Figura 1.6 La finestra Macro elenca tutte le macro disponibili.

Registrare la prima macro


Dopo avere ricordato gli aspetti delle macro che è utile tenere presenti quando si desidera
crearne una riutilizzabile, e le loro principali caratteristiche, è giunto il momento di realizzare la
prima macro in VBA servendosi del registratore.
Lo scopo della macro sarà molto semplice: applicare una formattazione alle celle contenenti un
valore superiore a 75. La procedura da eseguire è illustrata di seguito.
Rendere attiva la prima cella che deve essere formattata (altrimenti la macro memorizzerà gli
spostamenti).
Avviare il registratore di macro (Figura 1.4) selezionando Registra macro.
All’interno della finestra Macro, assegnare un nome di identificazione significativo della
macro ed eventualmente altre informazioni, quali una descrizione del lavoro che essa svolge e
il tasto di selezione rapida.
Fare clic sul pulsante OK per avviare la registrazione della macro.
Attivare il sistema di riferimenti relativi utilizzando il pulsante Usa riferimenti relativi
visibile nella scheda Sviluppo, per fare in modo che la macro non memorizzi i riferimenti alla
cella specifica e quindi possa essere utilizzata per formattare anche altre celle. Agendo sui
pulsanti presenti nella scheda Home, applicare la formattazione desiderata, per esempio:
dimensione del carattere 12 punti, allineamento centrato, grassetto.
Terminata l’impostazione della formattazione desiderata, premere il tasto Giù per fare in
modo che la cella attiva diventi quella immediatamente seguente a quella corrente. In questo
modo la macro applicherà la formattazione e renderà attiva la cella immediatamente seguente
a quella corrente: questo consentirà un risparmio di tempo se anche la successiva nuova cella
attiva deve essere formattata attraverso questa macro.
Fermare il registratore di macro mediante il pulsante Interrompi registrazione.
Ora la macro è stata registrata ed è pronta per essere utilizzata: nella scheda Sviluppo è presente
il pulsante Macro, che attiva una finestra al cui interno sono presenti tutte le macro disponibili per
essere eseguite attraverso un doppio clic sul nome o sul pulsante Esegui.

Il codice della macro


La macro viene memorizzata utilizzando il linguaggio Visual Basic for Excel, per cui è lecito
attendersi che il risultato del precedente lavoro abbia prodotto un piccolo programma in questo
linguaggio. Infatti, il programma ottenuto è il seguente:
Sub FormattaAllineaCentroGrassetto12punti()

‘ FormattaAllineaCentroGrassetto12punti Macro


With Selection
.HorizontalAlignment = xlCenter
.VerticalAlignment = xlBottom
.WrapText = False
.Orientation = 0
.AddIndent = False
.IndentLevel = 0
.ShrinkToFit = False
.ReadingOrder = xlContext
.MergeCells = False
End With
With Selection.Font
.Name = “Calibri”
.Size = 12
.Strikethrough = False
.Superscript = False
.Subscript = False
.OutlineFont = False
.Shadow = False
.Underline = xlUnderlineStyleNone
.ThemeColor = xlThemeColorLight1
.TintAndShade = 0
.ThemeFont = xlThemeFontMinor
End With
Selection.Font.Bold = True
ActiveCell.Offset(1, 0).Range(“A1”).Select
End Sub

Probabilmente può risultare poco o per nulla comprensibile, ma già dai prossimi capitoli
diventerà più chiaro e interpretabile.
Se avete fretta, però, un veloce sguardo può fornire qualche informazione:
la prima riga contiene l’istruzione Sub che indica l’inizio della macro e il nome, ovvero
FormattaAllineaCentroGrassetto12punti;

le successive sono commenti, in quanto il primo carattere è un apice (lo stesso carattere
utilizzato normalmente anche come accento);
With è un’istruzione molto comoda, poiché permette di semplificare la scrittura e lettura dei

programmi, infatti indica che le istruzioni successive fino a End With fanno riferimento alla
stessa entità, in questo caso a Selection, ovvero alla cella o alle celle correntemente
selezionate;
il carattere punto anteposto alle istruzioni indica che l’istruzione è relativa all’entità
precedentemente indicata in With. La riga
.HorizontalAlignment = xlCenter

poteva essere scritta anche nella forma estesa:


Selection.HorizontalAlignment = xlCenter

In questo esempio, l’impiego dell’istruzione With e del carattere punto consente di non dover
ripetere in ogni istruzione il nome Selection.
Il significato è relativamente semplice: l’oggetto Selection ha una proprietà di nome
HorizontalAlignment al quale si deve assegnare il valore xlCenter, ovvero la selezione dovrà avere

l’allineamento orizzontale di tipo centrato.


Al termine si deve trovare l’istruzione complementare di Sub, ovvero End Sub.
Se ancora non è tutto chiaro, è perché sono necessarie le informazioni che verranno presentate
nei capitoli seguenti.
Capitolo 2

L’ambiente di Visual Basic Editor

In questo capitolo verranno analizzati diversi aspetti, compreso il più semplice e veloce sistema
per realizzare le macro attraverso il registratore, nonché l’utilizzo dell’ambiente di sviluppo di
VBA (Visual Basic for Application) di Excel.
Prima di continuare, è utile indicare alcuni termini che nel corso della trattazione diverranno
familiari.
Istruzione: riga di testo scritta nel linguaggio di programmazione, che consente al
programmatore di definire un’azione, un calcolo o un’operazione che deve essere svolta dal
computer.
Routine: è un’insieme di istruzioni Visual Basic strutturate per ottenere un determinato
risultato o elaborazione; è il termine più corretto per identificare una macro.
Subroutine: sinonimo di routine che veniva un tempo utilizzato per indicare parti di
programma richiamate dalla routine principale; attualmente, non vi è più una distinzione
linguistica tra i due termini. Per chiarezza espositiva, nel seguito della trattazione con il
termine subroutine si farà riferimento a quelle routine che prevedono parametri e di
conseguenza non appaiono tra le macro richiamabili dalla finestra macro.
Funzione: simile alla routine, riceve generalmente valori che elabora per restituire un
risultato. Per esempio, le funzioni trigonometriche quali sen() e cosen() sono funzioni. Si
differenzia dalla routine per il fatto che può essere utilizzata all’interno di un’espressione e
restituisce sempre un valore.
Chiamata: indica l’istruzione che esegue una routine o una funzione.
Programma: è un insieme strutturato di istruzioni abitualmente raggruppate in diverse
subroutine e funzioni, che svolge un compito ben preciso. In ambiente Excel è anche un
termine utilizzato in sostituzione della parola macro.
Modulo: concettualmente simile a un documento, al cui interno si inseriscono i programmi o
una loro parte. La suddivisione di un programma in vari moduli, spesso, è dovuta alla volontà
del programmatore di suddividere in più parti il programma in base a concetti di omogeneità;
per esempio, si può avere un modulo con tutte le funzioni create per eseguire calcoli
finanziari, o con le routine che gestiscono l’accesso ai database, uno con le funzioni a uso
generale, come quelle che eseguono particolari elaborazioni sul testo, e un altro ancora
contenente le routine principali del programma che richiamano quelle contenute negli altri
moduli.
Classe: è un programma che nasce per interagire con altre classi, o programmi, attraverso una
serie di comportamenti, detti metodi, al fine di mettere a loro disposizione funzionalità
collaudate che il linguaggio di programmazione non possiede. È anche dotato di proprietà,
ovvero caratteristiche. Esempi di metodo possono essere la richiesta di stampare i dati che la
classe gestisce, oppure di ordinarli alfabeticamente, mentre esempi di proprietà possono
essere il tipo di carattere o il colore che la classe utilizza per visualizzare i dati.
Metodo: è un’azione che la classe può eseguire; ogni classe è dotata di metodi definiti dal
programmatore, che si dividono in pubblici, ovvero richiamabili dalla classe stessa, da altre
o da altri programmi, e privati, richiamabili solo dalla classe stessa. Il metodo è un insieme
di istruzioni racchiuse tra Sub ed End Sub.
Proprietà: caratteristica di una classe che può essere impostata o acquisita. Essa viene
realizzata utilizzando un insieme di istruzioni racchiuse tra Function ed End Function.
Codice: spesso viene utilizzato come sinonimo d’insieme di istruzioni, funzioni (Function) e
routine (Sub) costituenti il programma. È frequente leggere la frase equivalente: codice
sorgente.
Form: termine per indicare le finestre che vengono costruite dal programmatore utilizzando
gli strumenti messi a disposizione nell’ambiente di Visual Basic Editor.
Controllo: relativamente ai form, i controlli sono gli oggetti che possono essere collocati
all’interno di una finestra, come pulsanti, caselle di testo, caselle di spunta ed elenchi a
discesa.
Debug: attività del programmatore atta a individuare ed eliminare le anomalie che
abitualmente i programmi presentano durante la fase di sviluppo e nel periodo di collaudo; è
la parte più delicata e stressante in quanto, talvolta, gli errori sono difficili da individuare,
soprattutto se il loro presentarsi sembra non seguire regole ma appare casuale e inspiegabile.
IDE (Integrated Developement Environment): acronimo dell’espressione inglese che
definisce, in questo caso, l’ambiente di sviluppo di Microsoft Visual Basic for Excel.
Finestra ancorabile: tipo di finestra i cui trascinamenti producono proposte automatiche di
allineamento ai bordi della finestra che la contiene, o il suo inserimento in particolari
contenitori rappresentati da un bordo più spesso di una normale finestra.
Esecuzione passo passo: è una modalità di debug del programma che viene eseguito non
interamente bensì per ogni singola istruzione; il programmatore deve premere il tasto F8
affinché l’elaborazione proceda. È una tecnica utilizzata per capire in quale sequenza sono
eseguite le varie istruzioni, quando si è in presenza di condizioni o cicli che non si
comportano come atteso.
Punto d’interruzione: istruzione alla quale è stata associata una segnalazione, che appare
graficamente come un pallino rosso alla sua sinistra, e viene interpretata da Visual Basic
Editor come un ordine di sospendere l’esecuzione del programma. Molto spesso i
programmatori vi fanno riferimento con il termine inglese breakpoint.
Ciclo: serie di istruzioni che viene continuamente ripetuta. L’equivalente termine inglese, che
gli sviluppatori di software usano spesso, è loop.
Indentazione: rientranza dal margine sinistro che si utilizza, in quasi tutti i linguaggi, per
identificare visivamente una serie di istruzioni come appartenente a un gruppo particolare
quale, per esempio, un ciclo. Il suo utilizzo non influisce minimamente sul programma e la sua
esecuzione, ma aiuta sensibilmente la lettura e comprensione del programma stesso.
Default: valore predefinito, che viene assegnato automaticamente in mancanza di altre
assegnazioni esplicite. Per esempio, il grigio è il colore di default dello sfondo delle finestre.

NOTA Per indentare rapidamente un intero gruppo di istruzioni è sufficiente selezionarle e premere il tasto Tab; per
ridurre l’indentazione, ovvero per spostare il testo verso sinistra, si utilizza lo stesso tasto tenendo premuto il tasto
Caps lock, cioè quello che raffigura un lucchetto.

Visual Basic Editor


Oltre al registratore, Visual Basic Editor è l’unico strumento disponibile per operare sulle
macro. In particolare, mette a disposizione un ricco repertorio di strumenti per creare, modificare,
eseguire il debug e le macro. Per esempio, consente di:
creare finestre di dialogo che richiedono all’utente parametri o visualizzano informazioni;
creare barre di comando con i relativi pulsanti e associare a essi macro che verranno eseguite
quando l’utente vi farà clic sopra;
creare macro che richiamano altre macro;
automatizzare operazioni, come nel caso di apertura o chiusura della cartella;
pilotare altri software che supportano sia VBA sia Word.

Lanciare Visual Basic Editor


L’avvio di Visual Basic Editor avviene utilizzando due differenti sistemi, tra loro equivalenti e
intercambiabili:
mediante il pulsante Modifica presente sulla finestra Macro (Figura 1.6);
attivando la barra multifunzione Sviluppo (come indicato a fine del capitolo);
la combinazione di tasti Alt+F11.
A questo punto Visual Basic Editor appare come una nuova finestra, il cui nome è composto dal
nome stesso del programma più quello della cartella di lavoro attiva al momento in cui è stato
lanciato.

Le finestre che compongono Visual Basic Editor


Una volta avviato, Visual Basic Editor si presenta come una finestra indipendente da Excel,
all’interno della quale ne compaiono altre tre:
Progetto
Proprietà
Codice
Le prime due sono dotate di un particolare comportamento che automaticamente le avvicina al
bordo della finestra dell’editor quando vengono spostate, e ridistribuisce lo spazio disponibile
ridimensionandole opportunamente, se necessario coinvolgendo anche le altre. Inoltre,
l’operazione di ingrandire la finestra Codice a tutto schermo sarà eseguita rispettando le altre due,
ovvero esse non saranno coperte, bensì verrà utilizzata solamente l’area lasciata disponibile.

La finestra Progetto
La finestra Progetto (Figura 2.1) contiene un elenco in cui sono visibili tutti gli oggetti aperti in
Excel e i loro componenti. Normalmente sono presenti gli oggetti elencati di seguito.
VBAProject (Cartel1): identifica un progetto di VBA, ovvero un insieme di oggetti, e il nome tra
parentesi è quello della cartella in cui esso è memorizzato, in questo caso Cartel1.
Foglio1 (Foglio1): identifica un oggetto di tipo foglio di lavoro contenuto nella cartella il cui

nome appare tra parentesi. Tutti i fogli di lavoro appaiono identificati dalla parola “Foglio”
seguita da un numero, ma è importante non confondere questo con il nome che appare sulla
linguetta nella finestra di Excel e che nella finestra Progetto si trova tra parentesi; per ogni
foglio di lavoro della cartella sono presenti altrettante voci.
Questa_cartella_di_lavoro: indica la cartella Excel, ovvero il file. Nelle precedenti versioni
di Excel era chiamata ThisWorkbook.

NOTA Se le finestre Progetto e Proprietà vengono spostate e diventano autonome dalle altre, acquisiranno la
caratteristica di rimanere sempre in primo piano, ovvero non verranno mai coperte da altre finestre di Visual Basic
Editor.
Figura 2.1 La finestra Progetto. Il numero di oggetti “Fogliox” varia in relazione al numero di fogli contenuti nella cartella.

È importante capire la struttura di questi dati: essi hanno una forma quasi gerarchica; la finestra
Progetto contiene gli oggetti di Excel, come la cartella Cartel2 al cui interno si trovano gli oggetti
Foglio1, Foglio2, Foglio3. Questa struttura è evidenziata dalla rappresentazione grafica:
dall’icona di VBAProject (Cartel2) parte una linea verticale alla quale sono legate le icone dei
fogli.
Se si trattasse di una struttura rigidamente gerarchica, l’oggetto Questa_cartella_di_ lavoro
(ThisWorkbook) non dovrebbe essere allo stesso livello dei fogli di lavoro che contiene, come invece
accade. Questa caratteristica non rappresenta comunque un problema nella creazione delle macro.
Si osservi l’icona a forma di quadrato al cui interno può esserci un più o un meno; facendovi
clic sopra è possibile ampliare o ridurre la lunghezza dell’elenco poiché tali segni aprono o
chiudono la categoria, alla stregua del comportamento adottato dal programma Gestione risorse di
Windows.
Questa finestra è utile per muoversi tra gli oggetti e i moduli presenti nelle cartelle, mentre le
altre finestre visualizzano le informazioni dell’oggetto che viene selezionato in questa.

La finestra Proprietà
La finestra Proprietà visualizza le cosiddette proprietà dell’oggetto che è selezionato, per
esempio l’elemento nella finestra Progetto o un altro oggetto. Per chi non ha esperienza di
programmazione a oggetti è utile anticipare che si tratta di una tecnica che assegna agli oggetti i
comportamenti descritti con le macro; per esempio, per l’oggetto pulsante, alla proprietà Caption
può essere associata la scritta che appare su di esso, oppure la proprietà BackColor, il colore che
esso deve avere.
La finestra Proprietà (Figura 2.2) appare costituita da una griglia composta da due colonne e un
numero di righe e di contenuto che varia in relazione al tipo di oggetto selezionato nella finestra
Progetto. Per esempio, l’oggetto VBAProject ha una sola proprietà mentre Foglio e
Questa_cartella_di_lavoro (ThisWorkbook) ne hanno molte di più.
La finestra è organizzata nel modo seguente:
nella colonna di sinistra appare il nome della proprietà;
nella colonna di destra è visibile il valore assegnato alla proprietà.
Nella parte superiore sono visibili due linguette che servono a modificare il modo di elencare le
proprietà nella griglia:
Alfabetico. Le proprietà appaiono rispettando l’ordine alfabetico;
Per categoria. Le proprietà sono raggruppate per categorie funzionali e, al loro interno,
alfabeticamente. Quando si sceglie questa forma di elencazione, alla griglia viene aggiunta a
sinistra una nuova colonna, che contiene un’icona per gestire il collasso delle proprietà
appartenenti a tale categoria.
Non cambia molto, ma la possibilità di avere le proprietà raggruppate in base al loro scopo si
rivela estremamente utile quando si utilizzano oggetti che ne possiedono molte.

Figura 2.2 La finestra Proprietà.

NOTA Il numero di proprietà di un oggetto è stabilito dal suo creatore e si possono incontrare oggetti dotati anche
di centinaia di proprietà.

Nella barra dei pulsanti nel riquadro Progetto (evidenziati in Figura 2.2) sono presenti tre
pulsanti, illustrati di seguito.
Visualizza codice: attiva la finestra Codice dell’oggetto selezionato.
Visualizza oggetto: visualizza l’oggetto selezionato; nel caso di un foglio di lavoro il
controllo passa a Excel, che visualizzerà il foglio di lavoro selezionato.
Espandi/Comprimi cartelle: cambia la modalità di visualizzazione degli oggetti, passando da
una forma strutturata per tipologie a una più lineare, in cui sotto l’oggetto di tipo VBAProject
appaiono gli altri oggetti non raggruppati in base al loro tipo.

La finestra Codice
Solitamente, quando viene creata una macro attraverso il registratore, Excel provvede a
memorizzarla all’interno della cartella che è stata selezionata nell’elenco Memorizza macro in.
Più precisamente, all’interno della cartella viene creato un modulo, ovvero un particolare
documento, che la finestra Codice consente di vedere.
Ogni modulo può contenere una o più macro (oppure nessuna) e il suo contenuto è accessibile e
leggibile attraverso Visual Basic Editor, in quanto le macro sono memorizzate con il linguaggio
VBA. La parte centrale della finestra è costituita da un’area simile al programma Appunti o
Wordpad di Windows, ove è possibile scrivere le macro.
Ogni macro appare separata dalle altre da una linea orizzontale, la quale non possiede alcuna
utilità o valenza se non per il programmatore che, in questo modo, è facilitato e meno distratto nel
suo lavoro.
È anche possibile visualizzare solamente una macro per volta anziché averle tutte visibili e
separate dalla linea. Infatti, utilizzando il pulsante Visualizza routine si impone a Visual Basic
Editor di limitare la visualizzazione alla sola macro al cui interno si trova il cursore; tale pulsante
si trova a sinistra della barra di scorrimento orizzontale della finestra Codice.
La visualizzazione delle altre macro avviene selezionandole dall’elenco posto nella parte
superiore destra della finestra. Per tornare alla modalità di visualizzazione di tutto il modulo, è
sufficiente fare clic sul pulsante Visualizza modulo intero, che è ugualmente collocato nella parte
inferiore sinistra della finestra.

Uno sguardo all’insieme


Visual Basic Editor è un programma che si compone di tre finestre in relazione tra loro. Tramite
la finestra Progetto si seleziona su quale oggetto si desidera lavorare, Proprietà ne visualizza le
proprietà, mentre Codice contiene le macro.

I menu di Visual Basic Editor


Fino alla versione 2007, i programmi di Office avevano un’interfaccia standard, condivisa
praticamente da tutti i software creati per Windows. Poi Microsoft ha introdotto le barre
multifunzione che hanno radicalmente mutato la situazione. Nelle versioni 2013 e 2010 esistono
differenze anche con la barra di Excel 2007 e queste modifiche hanno comportato qualche
problema agli utenti, ma si tratta di aspetti grafici, perché le macro non ne risentono se non in casi
estremamente specifici. Inoltre, l’interfaccia dell’ambiente VBA è invariata.

Figura 2.3 Visual Basic Editor con la finestra Codice aperta nella parte sinistra. Si noti il nome corrente della finestra.

NOTA Ogni istanza di Visual Basic Editor di Excel opera solamente sugli oggetti aperti nell’istanza di Excel
utilizzata per lanciarla. In altre parole, se Excel viene eseguito due volte contemporaneamente, si ottengono due
diverse istanze, quindi sarà possibile richiamare Visual Basic Editor da entrambe creandone così due nuove,
ciascuna delle quali potrà accedere e gestire solo gli oggetti dell’istanza di Excel da cui è stata eseguita, salvo che
le macro non vengano memorizzate nella cartella macro personale come indicato nel capitoletto ”Avviare il
registratore”.

Sfruttando questa peculiarità e per non annoiare i lettori che hanno già conseguito un ottimo
livello di conoscenza, verranno presentati di seguito i vari menu e sottomenu che sono specifici di
Visual Basic Editor.

Il menu File
Salva (nome). Consente di salvare le modifiche apportate alle macro.
Importa file. Apre un finestra di dialogo nella quale è possibile indicare un file macro, form o
classi che verranno aggiunti al progetto corrente. Può risultare utile per importare all’interno
di una cartella il lavoro memorizzato in altre cartelle e precedentemente copiato al suo
esterno mediante il menu File/Esporta file.
Esporta file. Consente di estrarre dalla cartella un oggetto di Visual Basic; questa operazione
non elimina l’oggetto contenuto nella cartella, ma ne esegue una copia. Si tratta di una
funzione utile per archiviarlo separatamente, farlo pervenire ad altre persone senza inviare
l’intera cartella e copiarlo all’interno di altre cartelle in modo tale che possano avvalersene
senza che la cartella originaria sia aperta.
Rimuovi (nome). Provvede a eliminare dalla cartella l’oggetto selezionato; si tratta di una
funzione che va impiegata con attenzione in quanto non è possibile annullarla. Comunque,
prima di eseguire la cancellazione, il programma provvede ad aprire una finestra di dialogo
che richiede se si desidera salvarlo in un file separato. Se la risposta è sì, verrà presentata
l’usuale finestra Esporta file analogamente a quanto accade con File/Esporta file.
Stampa. Permette di stampare un form o il programma.

Il menu Modifica
Il menu Modifica è un altro dei menu obbligatori per le applicazioni Windows. Da notare che
molti comandi di questo menu sono attivi solo se la finestra Codice è attiva.
Aumenta rientro. Permette di spostare a destra di quattro spazi le istruzioni evidenziate o la
riga sulla quale è presente il cursore; questo comando risulta particolarmente utile quando si
deve racchiudere un blocco di istruzioni all’interno di altre, quali If oppure With.

NOTA Il numero di caratteri d’indentazione utilizzati dai comandi File/Aumenta rientro e File/Riduci rientro è
personalizzabile attraverso il percorso Strumenti/Opzioni, che apre una finestra nella quale è presente la casella
Rientro tabulazione contenente tale valore.

Riduci rientro. Identico al comando Aumenta rientro, ma agisce riducendo l’indentazione di


quattro caratteri.
Elenca proprietà/metodi. Apre un elenco sotto al cursore, in cui appaiono tutte le proprietà o i
metodi dell’oggetto selezionato o posto a sinistra del cursore stesso (Figura 2.4). La scelta
avviene scorrendo l’elenco con il mouse o i tasti freccia oppure, più velocemente, digitando
una o più iniziali. L’elenco viene via via modificato posizionandosi sugli elementi che
iniziano con tali caratteri; la scelta si conclude premendo il tasto Invio, che copia la voce
all’interno della finestra Codice, nella posizione del cursore.
Questa tecnica permette di evitare la digitazione, guadagnando tempo e riducendo
sostanzialmente la possibilità di errore, in quanto non è più possibile scrivere male il nome di una
proprietà.
NOTA Per i più esperti, risulterà utilissimo l’impiego del tasto Tab per modificare l’indentazione di un blocco di
istruzioni: basta selezionare il gruppo di istruzioni e utilizzare Tab o Maiusc+Tab ed esse verranno spostate verso
destra o sinistra.
Figura 2.4 L’elenco Elenca proprietà/metodi aperto.

L’utilizzo della combinazione di tasti Ctrl+J rende estremamente semplice il suo utilizzo,
sostituendo l’uso poco pratico di questo comando. È da notare che l’elenco viene automaticamente
attivato quando si digita un carattere che sintatticamente prevede la successiva presenza di una
proprietà o un metodo, come nel caso del carattere punto.
Elenca costanti. Apre un elenco contenente i valori ammissibili per assegnare un valore
all’oggetto posto a sinistra dell’uguale che precede il cursore.
Informazioni rapide. Apre un riquadro nel quale sono presenti informazioni sulla funzione o
subroutine selezionata nella finestra Codice, riepilogandone le caratteristiche (Figura 2.5).

Figura 2.5 Esempio del contenuto della casella Informazioni rapide.

Informazioni parametri. Apre un riquadro nel quale sono presenti informazioni sulla funzione
o subroutine selezionata nella finestra Codice.
Completa parola. Per sveltire la digitazione delle istruzioni è disponibile questo comando,
che si comporta in maniera analoga al comando Modifica/Elenca proprietà/metodi.
Segnalibri. Permette di marcare una linea in modo da poter tornare celermente a essa. Non è
possibile associare nomi ai vari segnalibri per identificarli e li si può scorrere solamente in
sequenza, avanti e indietro. Essi vengono graficamente rappresentati da un rettangolo azzurro
che appare sul bordo sinistro della finestra Codice. Operativamente, per creare un segnalibro
per una determinata istruzione, si deve portare il cursore su di essa e selezionare Modifica/
Segnalibri/Imposta/rimuovi segnalibro; per rimuoverlo si utilizza la medesima procedura. La
navigazione avviene mediante Modifica/Segnalibri/Segnalibro Successivo e
Modifica/Segnalibri/Segnalibro Precedente. Il percorso Modifica/Segnalibri/Rimuovi
Segnalibri provvede a eliminare tutti i segnalibri esistenti, mentre il testo presente sulle
rispettive linee non viene modificato.

Il menu Visualizza
Il menu Visualizza contiene, tra gli altri, i comandi necessari per aprire alcune finestre utili nella
fase di debug del codice, nonché per fare riapparire le finestre di Visual Basic Editor qualora
siano state chiuse.
Codice. Apre la finestra Codice relativa all’oggetto selezionato nella finestra Progetto.
Oggetto. Visualizza l’oggetto selezionato nella finestra Progetto. Per esempio, se nella finestra
Progetto è selezionato un oggetto di tipo UserForm, questo comando lo visualizzerà.
Definizione. Consente di individuare la posizione ove una variabile è stata definita. Per
utilizzarlo è necessario fare clic sulla variabile e richiamare questo comando, che
visualizzerà l’area ricercata. Questo comando è attivo se lo è anche la finestra Codice.
Ultima posizione. Si comporta come il comando Definizione, ma per ricercare la successiva
posizione nel codice ove la variabile appare rispetto alla posizione attuale.
Visualizzatore oggetti. Apre una finestra nella quale sono elencati tutti gli oggetti e le relative
caratteristiche, in particolare le proprietà, le subroutine, gli eventi. Una caratteristica molto
utile è la possibilità di eseguire ricerche. Per esempio, inserendo la parola color nella casella
posta a sinistra del pulsante raffigurante un binocolo e facendo clic su di esso, il
Visualizzatore oggetti elencherà tutti gli oggetti che contengono un riferimento a tale parola.
Finestra Immediata. Apre una finestra, con le caratteristiche di ancorabilità già viste per
Progetto e Proprietà, che è utilizzata durante il debug di un programma. In particolare, quando
l’elaborazione viene temporaneamente sospesa, è possibile digitare al suo interno comandi
per analizzare i valori delle variabili o delle espressioni, ma anche modificarli attraverso
normali istruzioni in linguaggio Visual Basic (Figura 2.6). Per esempio, sono legittime le
istruzioni:
Print Now()
? Now()

che sono tra loro equivalenti e richiamano la funzione now() che restituisce la data e l’ora del
computer, mentre l’istruzione:
Longitudine = 2

provoca la modifica di una variabile di nome Longitudine impostandolo a 2.


Figura 2.6 La finestra Immediata.

Finestra Variabili locali. Apre la finestra ancorabile Variabili locali nella quale appaiono
tutte le variabili definite o visibili dalla funzione o subroutine attiva.
Finestra Espressioni di controllo. Apre una finestra ancorabile al cui interno è possibile
inserire espressioni che verranno continuamente analizzate, mostrandone il risultato.
Stack di chiamate. Visualizza la finestra ancorabile Stack di chiamate, che contiene un elenco
nel quale appaiono le funzioni e le subroutine che in un dato momento sono attive, ovvero in
esecuzione.

NOTA Questa finestra è fondamentale durante le operazioni di debug: quando il programma raggiunge un punto di
interruzione, infatti, attraverso di essa è possibile comprendere la catena di chiamate in successione delle routine
e funzioni. In tal modo, si può ricostruire il motivo per cui il programma è giunto su questa istruzione e analizzare i
valori delle variabili nelle varie routine e funzioni chiamanti.

Gestione progetti. Apre l’omonima finestra ancorabile, descritta all’inizio di questo capitolo,
che mostra tutti gli oggetti aperti da Excel.
Finestra Proprietà. Apre l’omonima finestra ancorabile, descritta all’inizio di questo capitolo;
il suo scopo consiste nel visualizzare le proprietà dell’oggetto selezionato.
Casella degli strumenti. Apre una barra degli strumenti contenente gli oggetti che possono
essere collocati in un form, come le caselle di testo o i pulsanti.
Ordine di tabulazione. Apre una finestra al cui interno appare un elenco che mostra l’ordine
con cui gli oggetti saranno resi attivi, in sequenza, dal tasto Tab quando la finestra che li
contiene verrà aperta dal programma in esecuzione. L’ordine è normalmente definito
rispettando la cronologia dell’inserimento degli oggetti sulla finestra, ma spesso occorre
intervenire manualmente per modificarlo in base alla logica con cui l’utente vuole avvalersi
dei componenti.
Barre degli strumenti. Contiene un sottomenu attraverso il quale è possibile definire quali
barre degli strumenti si desidera siano presenti all’interno della finestra di Visual Basic
Editor. Più rapidamente, è possibile ottenere lo stesso risultato facendo clic con il tasto
destro sulla barra dei menu o la barra degli strumenti.
Microsoft Excel. Passa al programma Excel senza chiudere o salvare i dati in Visual Basic
Editor. In alternativa a questo comando è possibile utilizzare la combinazione di tasti Alt+F11
oppure fare clic sul pulsante di Excel nella barra delle applicazioni di Windows.

Il menu Inserisci
Il menu Inserisci consente di creare nuovi oggetti all’interno di VBAProject corrente, oppure si
limita a introdurre le parti testuali di apertura e chiusura richieste dalle regole sintattiche. È dotato
di vari comandi.
Routine. Apre una finestra al cui interno è possibile indicarne il tipo; Visual Basic Editor
provvederà a inserire le parole chiave necessarie sostituendosi al programmatore, che ne
beneficia in termini di tempo e contro il rischio di dimenticarne delle parti. Generalmente, i
programmatori esperti preferiscono un approccio più diretto e provvedono a scrivere tutte le
parti a mano.
User Form. Crea un nuovo form senza controlli: il programmatore li inserirà selezionandoli
dalla Casella degli strumenti (Figura 2.7).

Figura 2.7 Dopo averla creata tramite Inserisci/UserForm, il nuovo UserForm appare privo di controlli.

Modulo. Crea un nuovo modulo vuoto al cui interno potranno essere inserite routine e
funzioni.
Modulo di classe. Crea un nuovo modulo vuoto al cui interno potranno essere creati i metodi
e le proprietà della nuova classe.
File. Apre una finestra di dialogo che permette di inserire in VBAProject corrente un file
contenente programmi in Visual Basic.
Il menu Formato
Il menu Formato fornisce gli strumenti necessari a gestire il posizionamento e l’allineamento
degli oggetti nei form tramite alcuni comandi.
Allinea. Dispone di un sottomenu nel quale sono presenti tre comandi per l’allineamento
orizzontale, tre per quello verticale e un altro per allineare lo spigolo superiore sinistro
dell’oggetto selezionato al più vicino punto della griglia.
Rendi uguale. Permette di uniformare le dimensioni dei controlli presenti su un form agendo
sulle loro dimensioni: altezza, larghezza o entrambe. L’impiego è semplice: si selezionano i
controlli di cui si desidera modificare le dimensioni e, come ultimo, l’oggetto a cui fare
riferimento per impostare le dimensioni dei precedenti; essi vengono distinti dal colore delle
maniglie: nere per gli oggetti che saranno ridimensionati, bianche per quelli di riferimento.
Adatta. Modifica le dimensioni di tutti i controlli selezionati affinché la superficie che
occupano nella finestra sia proporzionata al testo che contengono.
Adatta alla griglia. Modifica le dimensioni di tutti i controlli selezionati affinché gli spigoli
coincidano con i punti della griglia a essi più vicini. Per questi scopi si può anche agire
direttamente sulle rispettive proprietà, individuabili nel gruppo Posizione della scheda Per
categoria della finestra Proprietà.
Spaziatura orizzontale. Mette a disposizione un sottomenu che consente di modificare la
distanza orizzontale tra due controlli.
Spaziatura verticale. Mette a disposizione un sottomenu che consente di modificare la
distanza verticale.
Centra nel form. Attraverso i suoi sottomenu, permette di spostare i controlli selezionati in
una posizione centrale del form rispetto al suo asse orizzontale o verticale.
Disponi pulsanti. Questo comando è utile per spostare in modo automatico più pulsanti sul
lato destro oppure inferiore del form, al fine di creare un’omogeneità visiva.
Raggruppa. Permette di definire più controlli come facenti parte di un gruppo, ottenendo il
vantaggio di poter agire su tutti contemporaneamente senza doverli selezionare
individualmente ogni volta (Figura 2.8). Per disattivare il raggruppamento si seleziona
Formato/Annulla raggruppamento.
Annulla raggruppamento. Elimina la definizione di raggruppamento assegnata a più controlli
di un form attraverso Formato/Raggruppa.
Ordina. Serve per definire i piani di visualizzazione degli oggetti quando essi occupano la
stessa area della finestra sovrapponendosi. I controlli in primo piano sono quelli che
appaiono sopra agli altri, coprendo i sottostanti. I sottocomandi Porta Avanti e Porta Indietro
sono utili quando vi sono più controlli nella stessa area, in quanto permettono di agire sul
controllo selezionato spostandolo a un livello superiore o inferiore rispetto a quello
occupato.

Figura 2.8 Esempio di due controlli raggruppati attraverso Formato/Raggruppa.

Il menu Debug
Il menu Debug è probabilmente quello più utilizzato dagli sviluppatori che si avvalgono di
Visual Basic Editor, in quanto mette a disposizione gli strumenti per analizzare e modificare il
codice al fine di risolvere tutti quei piccoli e grandi problemi che si incontrano durante la
realizzazione di nuovi programmi, o anche semplicemente arricchendo quelli già esistenti di nuove
funzionalità. Esso si compone di vari comandi.
Compila VBAProject. Corrisponde alla richiesta di compilare il progetto corrente, ovvero di
analizzare tutto il programma e i suoi componenti per verificarne la correttezza nel suo
complesso.
Esegui istruzione. Durante l’esecuzione passo passo, questo comando ordina a Visual Basic
Editor di elaborare la prossima istruzione. Nel caso corrisponda a una chiamata a un’altra
routine o funzione, l’esecuzione passo passo viene applicata anche a essa; se invece si
desidera che venga elaborata interamente senza questa modalità, che però deve essere
riapplicata quando termina la routine chiamata ritornando dall’istruzione successiva a quella
corrente, allora si utilizza il comando Esegui istruzione/routine. Normalmente, invece di
selezionare questo menu, si preferisce premere il tasto F8.
Esegui istruzione/routine. Nell’elaborazione passo passo, permette di evitare che essa sia
applicata alle routine o funzioni richiamate da quella corrente. Si utilizza questo comando in
sostituzione di Esegui istruzione quando la routine che sta per essere chiamata è già stata
testata, o si è sicuri che essa non sia la causa del problema in questione. Per esempio, se
viene richiamata una routine già collaudata da lungo tempo è inutile applicarle l’esecuzione
passo passo; infatti, la probabilità che l’origine dell’errore ricercato vi sia contenuto è molto
scarsa, per cui è meglio concentrarsi sulle parti di codice più recenti.
Esci da istruzione/routine. Disattiva temporaneamente l’esecuzione passo passo fino a quando
non termina l’elaborazione dell’attuale routine o funzione; a quel punto viene ripristinata la
modalità passo passo. Questo sistema è utile quando si è entrati per errore, per esempio con
il tasto F8, in una routine che non si desidera analizzare oppure si è già visto ciò che si
voleva controllare e si preferisce tornare al punto in cui essa è stata richiamata, riprendendo
l’elaborazione passo passo.
Esegui fino al cursore. Disattiva temporaneamente l’esecuzione passo passo, permettendo a
Visual Basic di eseguire tutte le istruzioni che incontra fino a quando non raggiunge
l’istruzione sulla quale è stato dato questo comando, che è simile alla creazione di un punto di
interruzione temporaneo. Da notare che, se durante l’elaborazione vengono incontrate
istruzioni con punti di interruzione, essa verrà interrotta anche se non è stata ancora raggiunta
l’istruzione marcata con questo comando. Si riscontra la sua utilità quando, per esempio, si
stanno analizzando porzioni di codice che contengono cicli e non si desidera premere il tasto
F8 per tutta la loro durata; infatti, Esegui fino al cursore sospende la modalità passo passo
fino a quando non viene raggiunta l’istruzione desiderata.
Aggiungi espressione di controllo. Permette di impostare un’espressione o una condizione che
Visual Basic Editor analizza e della quale mostra il risultato nella finestra Espressioni di
controllo. È estremamente comoda per verificare il risultato di determinate variabili o
espressioni durante l’esecuzione del programma in modalità passo passo (Figura 2.9). Per
esempio, se vi sono variabili la cui somma deve sempre risultare 100 e il programma
presenta come difetto il non rispetto di questa regola, allora si può inserire l’espressione di
somma di tutte le variabili nella finestra Espressioni di controllo, in modo da poter
controllare costantemente se il risultato è sempre quello atteso ed eventualmente quando è
cambiato.
Figura 2.9 La finestra Aggiungi espressione di controllo.

Modifica espressione di controllo. Può capitare di voler modificare quanto inserito nella
finestra Espressioni di controllo: in tal caso si può utilizzare questo comando dopo aver
selezionato la voce da modificare.
Controllo immediato. Serve ad analizzare estemporaneamente il valore di una variabile, di
un’espressione o di una condizione evitando di creare un’espressione di controllo
nell’apposita finestra. Questo comando utilizza il testo selezionato nella finestra.
Imposta/rimuovi punto di interruzione. Serve per assegnare un punto d’interruzione
all’istruzione sulla quale è presente il cursore. Quando Visual Basic la incontrerà durante
l’esecuzione del programma, si fermerà evidenziandola. I programmatori utilizzano questo
sistema per iniziare l’analisi passo passo del programma quando esso raggiunge determinati
punti. L’istruzione alla quale è associato un punto d’interruzione appare con lo sfondo rosso
ed è contrassegnata da un punto rosso alla sua sinistra. Per eliminarlo si utilizza questo stesso
comando.
Rimuovi punti di interruzione. Provvede a eliminare tutti i punti d’interruzione presenti nel
modulo.
Imposta istruzione successiva. Può accadere che durante l’esecuzione passo passo si
individui un errore, ma potrebbe essere preferibile continuare l’esecuzione in quanto frutto di
un lungo periodo di debug che non si vuole perdere. A questo punto si potrebbe alterare la
normale sequenza logica delle istruzioni imponendo a Visual Basic Editor di proseguire
l’elaborazione da un punto diverso da quello attuale: ciò si ottiene facendo clic su tale
istruzione ed eseguendo il comando Debug/Imposta istruzione successiva.
Mostra istruzione successiva. Visualizza qual è l’istruzione successiva che verrà eseguita.
Il menu Esegui
Il menu Esegui è completamente replicato sulla barra degli strumenti Standard in quanto i suoi
comandi sono utilizzati con la massima frequenza.
Esegui Sub/UsersForm oppure Esegui Macro, in funzione del tipo di oggetto selezionato.
Esegue la routine attiva o avvia il form selezionato, altrimenti può aprire la finestra Macro al
fine di consentire al programmatore di indicare quella che desidera sia eseguita.
Interrompi. Permette d’interrompere temporaneamente l’esecuzione della routine. Si rivela
utile nei casi in cui il programma entri in cicli lunghi e si desideri vedere che cosa stia
accadendo.
Ripristina. Interrompe definitivamente l’esecuzione cancellando dalla memoria tutti i valori
associati alle variabili.
Modalità progettazione oppure Esci da modalità progettazione. Permette di attivare e
disattivare la modalità di progettazione.
Quando essa è attiva, non vengono elaborati gli eventi associati ai controlli né eseguito alcun
codice del progetto.

Il menu Strumenti
Il menu Strumenti mette a disposizione alcune opzioni utili per i progetti che devono essere
condivisi con altre persone o comunque distribuiti, in cui si desidera mantenere il segreto sulle
tecniche di programmazione o, comunque, rendere inaccessibile il codice. Dispone di alcuni
comandi.
Riferimenti. È una finestra contenente un elenco nel quale sono visibili tutti i software
installati sul computer e che possono essere utilizzati come risorse in un programma Visual
Basic. Per renderli disponibili è necessario attivare la casella di spunta che precede il nome
dell’elemento (Figura 2.10). Le loro caratteristiche potranno essere analizzate con il
Visualizzatore oggetti, che si attiva mediante Visualizza/Visualizzatore oggetti, mentre per
poterli inserire nei form è necessario inserirli nella Casella degli strumenti, che si apre
selezionando Visualizza/Casella degli strumenti attraverso Strumenti/Controlli aggiuntivi.
Controlli aggiuntivi. Apre una finestra al cui interno sono elencati tutti i componenti aggiuntivi
relativi a quanto selezionato mediante Strumenti/Riferimenti. Per renderli disponibili nella
Casella degli strumenti si deve attivare la casella di spunta che precede le voci desiderate:
essi prenderanno posto nella scheda attiva al momento in cui questo comando viene eseguito
(Figura 2.11).

NOTA Se il menu non è attivo, probabilmente non è attualmente selezionata un UserForm.


Macro. Apre la finestra Macro, mediante la quale è possibile avviare o eliminare le macro.

Figura 2.10 La finestra Riferimenti. Se presenti voci che iniziano con “MANCA”: indicano dei riferimenti che sono stati
selezionati per essere utilizzati nel progetto corrente, ma essi non sono più disponibili. Questo può accadere quando il
progetto è stato realizzato su un computer diverso da quello attualmente utilizzato oppure se determinati programmi sono
stati disinstallati.

Figura 2.11 La finestra Controlli aggiuntivi.

Opzioni. Questo comando apre una finestra nella quale è possibile personalizzare il
comportamento di Visual Basic Editor e alcune sue caratteristiche. Si compone di quattro
diverse schede. La scheda Editor tratta alcune caratteristiche come la gestione del rientro e la
sua dimensione, la visualizzazione separata delle varie routine e il controllo automatico della
sintassi delle istruzioni che vengono digitate nella finestra Codice.
NOTA Per creare nuove schede nella Casella degli strumenti, si deve fare clic con il tasto destro del mouse sopra
uno dei cavalierini in essa visibili e selezionare il comando Nuova pagina; in questo modo apparirà una nuova
scheda che, una volta resa attiva, potrà accogliere i nuovi componenti.

Nella scheda Editor è presente la casella Dichiarazione di variabili obbligatoria, che di


default è disattivata. Si consiglia di attivarla immediatamente perché inserisce
automaticamente l’istruzione Option Explicit nei vari moduli, la quale impone all’ambiente di
sviluppo di verificare che tutte le variabili siano state esplicitamente dichiarate. Se tale
istruzione, che deve essere la prima del modulo, non è presente, ogni volta che il programma
fa riferimento a una variabile che non è stata precedentemente dichiarata, Visual Basic
provvede a crearla; a prima vista è un vantaggio, ma nella realtà espone il programma a forti
probabilità di errori. Per esempio, se si utilizza una variabile di nome DataOdierna e in una
istruzione viene digitato per errore DataOderna (ovvero senza la lettera i), il programma le
considererà come due distinte variabili senza segnalarlo.
La scheda Formato editor consente literiori personalizzazioni in tema di visualizzazione del
codice.
La scheda Generale presenta varie opzioni, tutte sufficientemente autoesplicanti, ma alcune
meritano un approfondimento.
La casella di spunta Notifica prima di perdita stato è, di default, disattivata e serve a
visualizzare un messaggio di segnalazione che informa relativamente al fatto che Visual Basic
perderà tutte le informazioni contenute in memoria sullo stato dell’esecuzione del programma,
impedendo di continuarne l’esecuzione. La compilazione in background è una funzionalità che
permette di sfruttare i tempi di inutilizzo della CPU per svolgere il lavoro di compilazione
dei moduli del progetto, in modo da ottimizzare i tempi.
La scheda Ancoraggio permette di indicare quali finestre si desidera siano gestite come
ancorabili da Visual Basic Editor. Disattivando questa proprietà, le finestre interessate non
supportano più la modalità di ridimensionamento e completamento automatico dello spazio
disponibile nella finestra dell’IDE.
Proprietà di VBAProject. Questo comando permette di accedere alla finestra di proprietà del
progetto; al suo interno sono presenti due schede. Nella scheda Generale è possibile
assegnare un nome e una descrizione al progetto, oltre a un file di help, ovvero un file creato
con specifici software che sono in grado di generare formati compatibili con la Guida di
Windows. L’altra scheda, Protezione, consente di impostare una password per proteggere il
progetto. Per attivare la protezione e scegliere la password è necessario selezionare la
casella di spunta Proteggi progetto dalla visualizzazione.
Firma digitale. Autentica il programma con una specie d’impronta digitale e fornisce così
garanzie sulla relativa provenienza, in modo da poterlo utilizzare senza dubbi (Figura 2.12).
Per esempio, un programma potrebbe essere certificato anche per garantire l’assenza di virus
che, in quel caso, replicandosi modificherebbero la firma diventando più facilmente
individuabili.

Figura 2.12 Le finestre per l’assegnazione della firma digitale e l’elenco dei certificati ottenuti e utilizzabili per firmare il
programma.

Il menu Aggiunte
Il menu Aggiunte è molto semplice in quanto contiene una sola voce che permette di indicare le
risorse aggiuntive che si desidera siano disponibili in Excel.
Gestione aggiunte. Apre la finestra omonima, nella quale appaiono elencate le aggiunte
disponibili sul computer e se e come devono essere caricate, ovvero rese disponibili a Excel.
Le aggiunte sono identificabili attraverso la loro estensione che può essere .XLAM, XLA,
oppure .XLL. Per una gestione decisamente più comoda e funzionale, è meglio agire
attraverso la barra multifunzione File/Opzioni/Componenti aggiuntivi.

Il menu Finestra
Il menu Finestra si divide in tre parti: la prima contiene gli strumenti per la divisione della
finestra attualmente attiva, la seconda gli strumenti per modificare la visualizzazione di tutte le
finestre aperte, la terza l’elenco delle finestre aperte.

Il menu ?
Il menu ? contiene vari comandi per attivare sistemi di supporto per il programmatore. Alcuni di
essi sono già familiari agli utenti dei programmi Microsoft.
NOTA In genere, le estensioni non appaiono quando si sfogliano le cartelle con Gestione risorse o Risorse del
computer; questo perché l’impostazione di default di Windows prevede che esse siano nascoste all’utente per vari
motivi. Per cambiare tale impostazione si deve fare doppio clic sull’icona Risorse del computer e usare il comando
Visualizza/Opzioni per aprire la finestra Opzioni: al suo interno è presente la scheda Visualizza in cui va disattivata
la casella di spunta Non visualizzare le estensioni per i file registrati.

La Barra multifunzione per gli sviluppatori


Una barra estremamente utile di Excel 2013 per chi sviluppa macro è la barra Sviluppo perché
contiene l’accesso diretto ai principali strumenti necessari per gestire le macro, più altri utili per i
programmatori più esperti per la gestione di strumenti avanzati.
Essa è una barra standard presente nella normale installazione di Excel, ma, per default, non è
visibile. La sua presenza o assenza non modifica la gestione delle macro, per cui non è
indispensabile attivarla nei computer sui quali non si sviluppano le macro.
Per attivarla si procede come segue:
sulla barra multifunzione selezionare la voce File (Figura 1.1);
selezionare la voce Opzioni per aprire la finestra Opzioni di Excel (Figura 1.2);
selezionare la voce Personalizzazione barra multifunzione;
nel riquadro di destra (Schede Principali), attivare la voce Sviluppo (Figura 2.13);
chiudere con il pulsante OK.
A questo punto, la barra multifunzione di Excel conterrà un nuovo gruppo: Sviluppo (Figura
2.14).

Figura 2.13 La finestra Opzioni di Excel con parametri di Personalizzazione della barra multifunzione attraverso la quale è
possibile visualizzare il gruppo Sviluppo.
Figura 2.14 La barra multifunzione con il gruppo Sviluppo attivato.
Capitolo 3

Macro e subroutine

Quando si termina la registrazione di una nuova macro, essa è immediatamente pronta per essere
utilizzata. Ma dove viene memorizzata e come può essere modificata? In questo capitolo saranno
analizzati i vari aspetti di contorno della memorizzazione delle macro.

Le macro create con il registratore


Di seguito, verranno presentate alcune informazioni che potranno essere utili durante
l’apprendimento di Visual Basic Editor in relazione al registratore.

Il modulo che il registratore utilizza per le nuove macro


Ogni volta che si avvia il registratore di macro, Excel provvede a eseguire una serie di piccole
operazioni preliminari atte a definire alcune caratteristiche della macro.
Controlla se dall’avvio di Excel, all’interno della cartella selezionata nell’elenco Memorizza
macro in, è già stata registrata qualche macro e, in caso affermativo, utilizza lo stesso
modulo. In caso contrario, ne crea uno nuovo all’interno della cartella corrente e gli assegna
come nome la parola Modulo seguita da un numero sequenziale, che evita le omonimie con altri
moduli eventualmente già presenti nello stesso VBAProject.
Di default, assegna alla nuova macro un nome composto dalla parola Macro seguita da un
numero sequenziale, il cui scopo è evitare omonimie con altre macro presenti all’interno
dello stesso modulo.

Visualizzare le macro registrate


Per vedere il codice creato dal registratore di macro, è necessario prima attivare Visual Basic
Editor e poi accedere al modulo appropriato. Per essere esaustivi si devono compiere alcuni passi
che, una volta compresa la loro logica, appariranno molto più immediati e semplici di quanto non
sembri ora.
Da Excel, attivare il Visual Basic Editor attraverso il menu Sviluppo e il pulsante Visual
Basic (se Sviluppo non è visibile, vedere le indicazioni presenti alla fine del capitolo 2)
oppure tramite i tasti Alt+F11.
All’interno della finestra Progetto, individuare e aprire il VBAProject contenente la macro
registrata in base all’opzione selezionata nell’elenco Registra macro in della finestra Macro,
al momento in cui si è avviato il registratore. Se è stata selezionata la voce Cartella macro
personale, il VBAProject da aprire sarà quello alla cui destra appare tra parentesi il nome
PERSONAL.XLSB. Se è stata selezionata Questa cartella di lavoro, il VBAProject da aprire
sarà quello che riporta tra parentesi il nome della cartella attiva al momento della
registrazione. Inoltre, può essere stata utilizzata una nuova cartella: in tal caso, dopo la parola
VBAProject, apparirà sempre tra parentesi il nome PERSONAL.XLSB.
Selezionare con un doppio clic un modulo, individuabile sia dall’icona sia dal nome che, se
assegnato automaticamente da Excel, inizia con la parola Modulo seguita da un numero. Il
doppio clic apre la finestra Codice che contiene le macro di tale modulo.
Scorrere il contenuto della finestra Codice per individuare la macro ricercata, oppure
utilizzare l’elenco visibile nella parte alta sinistra della stessa finestra nella quale sono
contenuti i nomi di tutte le macro presenti nel modulo corrente. Se la macro ricercata non
compare nel modulo analizzato e ve ne sono altri appartenenti allo stesso VBAProject, allora
bisogna ripetere i due passi precedenti.
In alternativa, è anche possibile selezionare un VBAProject e richiamare il Visualizzatore di
oggetti, inserendo nella casella Testo da ricercare la radice del nome della macro che si desidera
individuare.

Modificare una macro


Il registratore di macro è uno strumento per creare nuove macro, registrando le varie operazioni
che l’utente esegue. Come indicato dal nome stesso, però, il suo compito è limitato esclusivamente
a tale operazione. Capita, tuttavia, di dover apportare alcune piccole modifiche alle macro
registrate, per cui diventa necessario vestire i panni del programmatore accedendo a Visual Basic
Editor e aprendo la macro da variare.

Rendere una macro sempre disponibile in tutti i file di


Excel
Per fare in modo che una macro sia utilizzabile da tutte le cartelle esistono diverse possibilità.
Al momento di registrarla, la si può memorizzare nella cartella PERSONAL.XLSB
selezionando nella finestra Macro la voce Cartella macro personale all’interno dell’elenco
Memorizza macro in. In questo modo ne esiste una sola versione, utilizzabile anche quando si
accede ad altre cartelle di lavoro Excel; di contro, se si utilizza un altro computer o si accede
con altro utente, il file PERSONAL.XLSB sarà diverso e quindi non conterrà la macro.
Copiare il modulo che contiene la macro in tutte le cartelle Excel che si desidera. In questo
modo esistono più copie che sono sempre utilizzabili quando le singole cartelle Excel
vengono aperte, indipendentemente dal computer o dall’utente che ha avviato la sessione
Windows; di contro, se viene riscontrato un difetto nella macro, diventa necessario aprire e
correggere tutti i file che la contengono.
Salvare la cartella Excel in formato modello nella finestra Salva o Salva con nome
sull’elenco Tipo file selezionando la voce Modello (*.xlt); ovviamente la macro sarà poi
disponibile a tutte le nuove cartelle che verranno create utilizzando questo modello (tramite
File/Nuovo).

Limitazioni sui nomi delle macro


Il nome che si assegna a una macro è sottoposto ad alcune limitazioni sintattiche che è utile
conoscere:
la sua lunghezza non può superare i 255 caratteri;
deve iniziare con una lettera;
sono ammesse tutte le combinazioni di lettere maiuscole, minuscole, cifre, carattere
underscore (_);
non è ammesso lo spazio, ma può essere sostituito dal carattere underscore oppure
dall’impiego combinato di maiuscole e minuscole; normalmente la prima lettera di ogni
parola che compone il nome della macro va scritta in maiuscolo e le seguenti in minuscolo.

NOTA Le vocali minuscole accentate sono ammesse ma è sconsigliabile impiegarle se si ipotizza che la macro
possa essere utilizzata su versioni internazionali di Excel.

Eliminare una macro


L’eliminazione di una macro da un modulo può avvenire mediante due metodi: il primo consiste
nel selezionarne il codice nella finestra Codice e cancellarlo, il secondo, più elegante e raffinato,
impiega la finestra macro e, dopo averla selezionata, la cancella attraverso il pulsante Elimina.

Eliminare un modulo
Per eliminare un modulo si opera all’interno della finestra Progetto, facendo clic con il tasto
destro del mouse sul modulo da eliminare al fine di visualizzare il menu contestuale nel quale è
presente il comando Rimuovi: selezionandolo, si apre una finestra che domanda se si desidera
effettuare un’esportazione del contenuto di tale modulo prima di procedere alla sua cancellazione.
In caso affermativo viene richiesto il nome da assegnare al nuovo file, altrimenti il modulo verrà
eliminato.

Le routine
Ora è arrivato il momento di vedere come scrivere una routine senza il registratore.

Il modulo ove scrivere le nuove routine


Tutte le routine vengono memorizzate all’interno di un modulo contenuto nella cartella
selezionata. Operativamente si procede nel modo descritto di seguito.
Da Excel si apre la cartella che dovrà contenere la nuova routine; se si desidera utilizzare la
cartella PERSONAL.XLSB non è necessario aprirla, in quanto si apre automaticamente ogni
volta che Excel viene eseguito.
Si avvia Visual Basic Editor.
Nella finestra Progetto, si seleziona mediante un clic il progetto relativo alla cartella
contenente la nuova routine, identificabile dal nome tra parentesi contenuto nella riga del
progetto.
Se la routine deve essere inserita in un modulo già esistente nel progetto, si apre il progetto
stesso facendo clic sul segno più che precede l’elemento nella finestra Progetto e lo si
seleziona.
Se la routine deve essere inserita in un modulo nuovo, si utilizza Inserisci/Modulo, per creare
una nuova voce di tipo modulo all’interno della finestra Progetto e aprire la sua finestra
Codice, che apparirà vuota. Se è stata attivata la dichiarazione obbligatoria delle variabili
attraverso la relativa casella di spunta accessibile da Strumenti/Opzioni, la finestra non sarà
vuota del tutto, ma conterrà l’istruzione Option Explicit.
A questo punto è possibile iniziare a scrivere la nuova routine.

Struttura della routine


Il linguaggio impone alcuni costrutti sintattici alle routine, inserendo due parole chiave che
dichiarano il loro punto d’inizio e fine.
Sub. Indica il punto d’inizio di una routine e deve essere seguita da uno spazio e dal nome che
si desidera assegnare alla routine stessa. Dopo il nome figurano due parentesi, una aperta e
una chiusa: servono a contenere l’elenco degli argomenti della routine. Il nome da dare alla
routine segue le stesse regole che vincolano l’assegnazione del nome delle macro.
End Sub. Figura nell’litima riga della routine e ne indica la fine.
Un esempio estremamente schematico di routine senza istruzioni e, di conseguenza, che non
svolge nessun compito è :
Sub EsempioSenzaCorpo()

End Sub

Tra le righe Sub ed End Sub vengono inserite le istruzioni che dovranno essere eseguite ogni volta
che la routine viene richiamata. Per esempio, la seguente routine apre una finestra di dialogo
utilizzando l’istruzione MsgBox (Figura 3.1), la quale conterrà l’orario acquisito dall’orologio di
Windows, poi, dopo aver fatto clic sul pulsante OK, comparirà un’altra finestra che visualizzerà la
frase “ Nella precedente finestra era visibile l’orario!” :
Sub EsempioConCorpo()

MsgBox Time

MsgBox “Nella precedente finestra era visibile l’orario!”

End Sub

Figura 3.1 La finestra di dialogo prodotta dall’istruzione MsgBox Time.

Scrivere le istruzioni di una routine


Le istruzioni delle routine vengono inserite dal programmatore nel rispetto delle regole del
linguaggio e in base alla propria logica, utilizzandole come strumenti che, opportunamente
strutturati tra loro, operano per ottenere un determinato risultato.
Ogni qualvolta si introduce un’istruzione errata, un’apposita finestra segnala l’errore, indicando
il tipo di problema, e il testo di tale istruzione viene evidenziato con il colore rosso.
Questo è un sistema estremamente utile e comodo per chi inizia a cimentarsi con tale linguaggio,
poiché aiuta a scrivere istruzioni corrette ed evita situazioni decisamente demotivanti quali
realizzare una lunga routine nella quale, per assurdo, non vi sia neppure un’istruzione corretta.

Il linguaggio
Disporre dell’ambiente di sviluppo non significa automaticamente poter scrivere le routine, in
quanto è indispensabile conoscere anche il linguaggio di programmazione. Questo argomento sarà
oggetto dei prossimi capitoli.
Capitolo 4

Tipi, variabili, matrici e costanti

Dati e informazioni possono essere suddivisi in categorie in base al loro tipo o natura, quali una
data, un orario, un numero, una parola o un’immagine.
Lo strumento per memorizzare permanentemente un dato è l’archivio, il file o il database, ma
spesso il programma necessita di gestire informazioni la cui vita non supera quella della durata del
programma stesso: per esempio, il pulsante premuto dall’utente in una finestra o se è stato scelto il
fax per stampare un documento. Per questo motivo vengono utilizzate le variabili.
Le categorie a disposizione del programmatore possono essere limitate o numerose in base al
tipo di linguaggio che si utilizza. Di seguito si vedrà, dunque, come VBA identifichi i vari tipi,
ovvero quali parole chiave utilizzare secondo le necessità.

Tipi di variabile
La Tabella 4.1 elenca i tipi di variabile numerica più comuni e le loro caratteristiche.
Tabella 4.1 Caratteristiche dei tipi di variabile numerica più comuni
Numero di
Parola Tipo di
Intervallo cifre
chiave informazione
decimali
Numeri interi
Byte Da zero a 255 Nessuno
positivi
Integer Numeri interi Da –32.768 a +32.767 Nessuno
Long Numeri interi Da –2.147.483.648 a +2.147.483.647 Nessuno
Currency Importo monetario Da –922.337.203.685.477,5808 a +922.337.203.685.477,5807 4
Numeri con
Valori negativi: da –3,402823E38 a –1,401298E-45; valori positivi: da
Single decimali in singola 6
+1,401298E-45 a +3,402823E38
precisione
Numeri con Valori negativi: da –1,79769313486231E308 a –4,94065645841247E-
Double decimali in doppia 324; valori positivi: da 4,94065645841247E-324 a 14
precisione 1,797693134862325E308

Variabili numeriche
Il Visual Basic fornisce varie possibilità per la gestione dei valori numerici, che vanno scelte di
volta in volta in accordo con il genere di informazione da memorizzare. A prima vista, potrebbe
apparire più comodo impiegare tipi generici che vadano bene per qualunque occasione come il
Double, ma in realtà questo è sconsigliabile per vari motivi; per esempio, i tipi che supportano la
parte decimale vengono elaborati a una velocità inferiore di quelli che non la gestiscono, quali
Integer o Byte, oppure, proprio in virtù della loro parte decimale, possono contenere valori che

comportano possibili problemi nelle istruzioni condizionali.


Di seguito sono elencati i vari tipi supportati da Visual Basic e le relative parole chiave
utilizzate per dichiararli attraverso l’istruzione Dim:
Sub EsempioIstruzioneDim()
Dim VariabileNumericaDiTipoIntero As Integer
Dim VariabileNumericaDiTipoByte As Byte
Dim VariabileNumericaDiTipoLungo As Long
Dim VariabileNumericaDiTipoMonetario As Currency
Dim VariabileNumericaDiTipoPrecisioneSingola As Single
Dim VariabileNumericaDiTipoPrecisioneDoppia As Double
End Sub

NOTA Il Visual Basic supporta anche il tipo Decimal che attualmente può essere utilizzato solo in modo indiretto
mediante il tipo Variant; il valore massimo che è in grado di memorizzare è +/–
79.228.162.514.264.337.593.543.950.335, ovvero con 28 cifre significative. È altresì possibile memorizzare valori
decimali con precisione fino alla 27a cifra decimale.

Variabili di tipo stringa


Per memorizzare dati testuali quali nomi, indirizzi e annotazioni si ricorre al tipo String.
Nel listato seguente vengono utilizzate tre variabili di tipo stringa: il valore Nome e Cognome viene
assegnato in base all’input dell’utente nella finestra aperta attraverso la funzione InputBox(), mentre
alla variabile Uniti viene assegnato un valore composto da Nome, uno spazio e Cognome:
Sub ChiedeNomeCognomePoiUnisce()
Dim Nome As String
Dim Cognome As String
Dim Uniti As String

Nome = InputBox(“Digitare il nome”)


Cognome = InputBox (“Digitare il cognome”)
Uniti = Nome + “ “ + Cognome
MsgBox Uniti
End Sub

NOTA Il termine “stringa” è utilizzato per indicare informazioni testuali. Per memorizzare un testo all’interno di una
variabile di tipo stringa, occorre racchiuderlo tra virgolette doppie; ovviamente le virgolette non saranno copiate
all’interno della variabile. Per esempio, “questa è una frase” è una stringa correttamente delimitata che può essere
assegnata a una variabile di tipo String o Variant.

Date e orari
Per memorizzare una data o un orario in una variabile è necessario definirla di tipo Date.

Gestire le date
Per assegnare un valore a una variabile di tipo Date mediante un’istruzione, si deve ricorrere a
una sintassi particolare che prevede di racchiudere la data tra una coppia di caratteri #. Per
esempio, il 31 dicembre 1999 può essere rappresentato nel modo seguente:
Dim UltimoDellAnno As Date
UltimoDellAnno = #12/31/1999# ‘ #mese/giorno/anno#

Come si può notare, il formato prevede l’inserimento invertito del mese e del giorno rispetto
alle abituali convenzioni italiane. Per agevolare la digitazione delle date è previsto un sistema
alternativo che verrà immediatamente convertito da Visual Basic Editor nel formato standard. È
possibile digitare le seguenti istruzioni che sono tra loro equivalenti:
Dim dt As Date
dt = #21/03/1980#
dt = #21 March 1980#
dt = #12 march,1980#

Il seguente esempio mostra come viene calcolata la differenza tra due date, la prima contenuta
nella variabile Nascita e impostata con il valore del 21 marzo 1980, la seconda ottenuta dalla
funzione Date() che restituisce la data corrente:
Sub GiorniVissutiFinoAdOggi()
Dim Nascita As Date
Dim GiorniVissuti As Integer

Nascita = #21/03/1980#
GiorniVissuti = Date() – Nascita
MsgBox “Hai già vissuto” & GiorniVissuti & “giorni!”
End Sub

NOTA È importante non utilizzare la funzione Date() come variabile assegnandole un valore, altrimenti verrà
aggiornato l’orologio di sistema in accordo a tale assegnazione: Date() è lo strumento per acquisire e impostare
tale orologio.

Gestire gli orari


Per memorizzare gli orari non esiste un tipo specifico, ma si ricorre ancora al tipo Date. Per
creare un’istruzione che assegni un predeterminato orario a una variabile Date si ricorre a una
sintassi simile a quella che abbiamo visto per assegnare le date, ovvero si scrive l’orario tra una
coppia di caratteri # e si impiega il carattere due punti per separarne le parti, aggiungendo anche il
suffisso AM oppure PM per indicare se l’orario si riferisce rispettivamente alla mattina o al
pomeriggio.
Nell’esempio seguente è disponibile una routine che calcola il tempo intercorso da un orario
predefinito, la mezzanotte, all’ora corrente e lo suddivide in ore, minuti e secondi assegnando tali
valori a tre variabili di tipo Integer:
Sub TempoTrascorsoDallaMezzanotteAdAdesso()
Dim OraAttuale As Date
Dim TempoTrascorso As Double
Dim OreTrascorse As Integer
Dim MinutiTrascorsi As Integer
Dim SecondiTrascorsi As Integer

OraAttuale = Time()
TempoTrascorso = OraAttuale - #12:00:00 AM# ‘mezzanotte
OreTrascorse = Int(TempoTrascorso * 24)
MinutiTrascorsi = Int((TempoTrascorso * 24 – _
Int(TempoTrascorso * 24)) * 60)
SecondiTrascorsi = (TempoTrascorso * 24 * 60 – _
Int(TempoTrascorso * 24 * 60)) * 60
MsgBox “Tempotrascorso: Ore=” & OreTrascorse & “, _
Minuti=” & MinutiTrascorsi & “, Secondi=” & _
SecondiTrascorsi
End Sub

NOTA La mezzanotte viene indicata con l’orario #12:00:00 AM# che quindi corrisponde alle ore 00:00:00.

Assegnare date e orari


Abbiamo visto come assegnare una data o un orario a una variabile, ma non è stata illustrata la
tecnica da utilizzare per assegnare entrambi i tipi di valore. Come potrebbe essere normale
attendersi, la sintassi è ricavabile da quella che regola i singoli tipi: si digita la data seguita
dall’orario e si racchiude entrambi all’interno di una coppia di caratteri #. Per esempio:
Dim FineSecolo As Date
FineSecolo = #12/31/1999 11:59:59 PM#

Comprendere la rappresentazione di date e orari


Al fine di riuscire a gestire al meglio orari e date, è importante comprendere come queste
informazioni siano memorizzate. La tecnica utilizzata è identica a quella implementata all’interno
di Excel.
La data viene memorizzata calcolando il numero di giorni trascorsi dal 31 dicembre 1899,
che costituisce la parte intera del valore assegnato alla variabile.
Gli orari sono considerati come frazione di un giorno, espressa in secondi e memorizzata
nella parte decimale del valore della variabile.
Per esempio, assegnare il valore numerico 1 a una variabile Date significa assegnarle la data del
31/12/1899, mentre assegnarle il valore 0,5 corrisponde alle ore 12:00. Più in dettaglio, il valore
che rappresenta un secondo è dato da 1 ÷ 24 ÷ 60 ÷ 60, ovvero da un giorno diviso 24 (il numero
delle ore in un giorno), diviso 60 (il numero dei minuti contenuti in un’ora) e ancora diviso per 60
(il numero di secondi contenuti in un minuto). È da sottolineare che le date anteriori a quella di
riferimento sono ammissibili e verranno memorizzate allo stesso modo, ma impiegando valori
negativi. Il Visual Basic è dotato di numerose funzioni per la manipolazione delle date e degli
orari e questi metodi sono assolutamente da preferire.

Variabili booleane o logiche


Un altro tipo di variabile è Boolean, che è in grado di rappresentare esclusivamente due valori:
False;
True.
Essi sono utilizzati in varie situazioni, ma costituiscono un buon sistema per rappresentare
determinate condizioni o situazioni, indicando se sono vere o false. Per esempio, potrebbe essere
utilizzata una variabile di nome NomeFileDiDefault per indicare che a un documento è stato assegnato
automaticamente il nome di default e che, al momento di salvarlo, si dovrà chiedere all’utente il
nome da utilizzare per archiviarlo:
Dim NomeFileDiDefault As Boolean
NomeFileDiDefault = True

L’utilizzo delle variabili booleane semplifica notevolmente la scrittura e la leggibilità delle


condizioni in quanto può essere omesso il controllo sul valore; in pratica, le seguenti istruzioni di
verifica sono tra loro identiche e intercambiabili:
If NomeFileDiDefault Then
If NomeFileDiDefault = True Then

Se invece si vuole testare il valore negativo di NomeFileDiDefault, è equivalente scrivere:


If Not NomeFileDiDefault Then
If NomeFileDiDefault = False Then

Variabili Variant
Variant può memorizzare tutti i tipi di valori ammessi da Visual Basic, infatti il linguaggio si fa
carico di eseguire tutte le operazioni di conversione necessarie.
Per esempio, le assegnazioni di valori di diverso tipo alla stessa variabile sono corrette come
appare nel seguente listato:
Sub EsempioVariabileVariant()
Dim V As Variant
V = “adesso V contiene una stringa”
V = True ‘ ora contiene un valore booleano
V = 123 ‘ in questo modo contiene un intero
V = #12/31/1999# ‘ ora contiene una data
V = “ora contiene nuovamente una stringa”
End Sub

Questi benefici hanno un costo per il programmatore, che perde il supporto del compilatore per
eventuali segnalazioni di errori nell’assegnazione di valori diversi da quelli previsti. Per esempio,
è possibile creare una variabile per memorizzare il risultato di una somma e assegnarle una stringa
per errore.
Sub EsempioDiAssegnazioniIndesiderate()
Dim V As Variant

V = 1 + 2 + 3
V = “stringa”
If V <> 6 Then
MsgBox “la variabile V non contiene il valore 6”
End If
End Sub

Variabili di tipo Object


I tipi Object individuano variabili che contengono oggetti; più specificatamente funzionano come
indici verso altre variabili. Per chi ha confidenza con il concetto di puntatori, occorre sottolineare
che questo tipo si comporta in modo simile.
In associazione al tipo Object si utilizza l’istruzione Set, che serve per assegnare il riferimento
mediante cui diventa possibile accedere al valore, alle proprietà e ai metodi. Nel seguente
esempio si utilizza la variabile Ptr come riferimento che sostituisce il secondo foglio di lavoro,
posto nella cartella attiva:
Sub InserisceUnValoreNellaCellaA1DelSecondoFoglio()
Dim Ptr As Object
Set Ptr = Sheets(2)
Ptr.Range(“A1”).Value = “Nuovo valore della cella”
End Sub

Overflow
L’overflow è un termine che in ambito informatico indica una situazione in cui un valore, che si
sta cercando di assegnare, eccede le capacità dell’oggetto di destinazione. Tipicamente, è la
situazione in cui si cerca di dare un valore più grande di quello che la variabile è in grado di
contenere. Per esempio, una variabile di tipo Integer non può contenere il valore 1.000.000 e il
tentativo di assegnazione fallirà:
Sub ErroreDiOverflow()
Dim VarA As Integer
VarA = 1000000
End Sub

NOTA L’errore di overflow viene segnalato esclusivamente durante l’esecuzione del programma (Figura 4.1). In
questo caso è necessario provvedere a dichiarare la variabile utilizzando un diverso tipo, come in questo esempio
i l Long. Per le variabili di tipo stringa a lunghezza costante, l’overflow non è segnalato e i caratteri in eccesso
vengono automaticamente troncati.

Figura 4.1 Messaggio di errore causato da un overflow nei dati.

Variabili
Il concetto di variabile è presente in tutti i linguaggi di programmazione, che lo implementano
con modalità estremamente simili, per cui la sua comprensione è utile anche per altri linguaggi.
La variabile può essere considerata come una sorta di scatola o contenitore di un’informazione
di un certo tipo, al quale si assegna un nome convenzionale attraverso cui si potrà accedere
all’informazione o sostituirla con un’altra.
In sintesi, una variabile è composta da:
un nome che deve iniziare con una lettera;
la definizione del tipo di informazione da memorizzare;
l’informazione.
Il nome e il tipo sono definiti attraverso l’istruzione Dim, mentre l’informazione viene inserita o
acquisita dalla variabile utilizzando il suo nome convenzionale. Nel listato seguente è mostrato un
esempio di routine che definisce una variabile di nome Var di tipo Integer, alla quale è assegnato il
valore 1; subito dopo l’istruzione If analizza il valore contenuto dalla variabile: se è uguale a 1, si
apre una finestra, tramite l’istruzione MsgBox, che riporta il suo valore:
Sub DefinisceVariabileDiTipoInteger()
Dim Var As Integer

Var = 1
If Var = 1 Then
MsgBox “La variabile di nome ‘Var’ vale 1”
End If
End Sub

Nomi di variabile
Il nome che si assegna alla variabile è soggetto ad alcune regole formali identiche a quelle che
regolano i nomi delle macro, ma a differenza di quest’ultime è possibile assegnare fino a 255
caratteri. Le lettere maiuscole e minuscole sono equivalenti, quindi i nomi EsitoControllo,
Esitocontrollo, ESITOCONTROLLO, esitocontrollo ed EsiToConTrOllo fanno riferimento alla stessa variabile.

Assegnare un valore alla variabile


Per assegnare un valore a una variabile è necessaria una riga in cui compare il nome della
variabile, il carattere uguale e il valore da assegnarle, che può anche essere un’espressione, una
formula o una funzione.
Le seguenti istruzioni costituiscono alcuni esempi di assegnazione di valori a variabili:
Var1 = Var2
Var1 = (Var2 * 2) / 3
Var1 = Var1 + 1
Var1 = 123

Più precisamente assegnano alla variabile Var1:


una copia del valore contenuto in Var2;
il risultato del doppio del valore di Var2 diviso 3;
una copia del valore di Var1 incrementato di 1 (in altre parole si incrementa direttamente di
un’unità il valore di Var1);
il valore 123.
Le seguenti istruzioni operano invece su variabili di tipo stringa:
VarStr = “questa e’ una stringa”
VarStr = VarStr & VarStr2
VarStr = VarStr & “! e anche ” & VarStr

E rispettivamente provvedono ad assegnare alla variabile VarStr:


la stringa “questa e’ una stringa” (le virgolette non vengono memorizzate nella variabile);
una copia del valore della variabile VarStr concatenata a una copia del valore della variabile
VarStr2; in altre parole significa accodare direttamente alla variabile VarStr il valore di VarStr2;

una copia del valore di VarStr seguita dalla stringa “! e anche ”, più un’literiore copia della
stringa VarStr; vale a dire “questa e’ una stringa! e anche questa e’ una stringa”.

Creare una variabile: la dichiarazione


In precedenza abbiamo accennato al fatto che Visual Basic può creare automaticamente le
variabili attraverso una dichiarazione implicita se non ha incontrato la relativa istruzione Dim,
oppure può interrompere l’elaborazione visualizzando un messaggio di errore.
Il secondo comportamento viene attivato attraverso l’istruzione Option Explicit che deve
comparire nella prima riga del modulo. Il suo utilizzo è estremamente utile, in quanto VBA è in
grado di individuare problemi che potrebbero far perdere molto tempo al programmatore.
La sintassi di base è la seguente:
Dim nomevariabile As tipo

dove nomevariabile rappresenta il nome da assegnare alla variabile mentre tipo corrisponde a una
delle parole chiave che identificano il tipo di dati che essa dovrà contenere. All’inizio di questo
capitolo sono stati riportati alcuni esempi per illustrare come si dichiarano le variabili dei vari
tipi.
Generalmente le istruzioni Dim costituiscono le prime istruzioni di ogni routine.

Vita e visibilità delle variabili


In relazione al punto in cui vengono dichiarate, le variabili hanno vita e visibilità differenti.
Infatti, se ne possono distinguere di vario tipo, illustrate di seguito.
Variabili locali: vengono dichiarate all’interno di una routine o una funzione e sono create
quando si incontra la relativa istruzione Dim; la variabile viene cancellata quando
l’elaborazione esce dalla routine.
Variabili di modulo: vengono dichiarate all’inizio del modulo e quindi all’esterno di
qualunque routine o funzione e sono create al momento di avvio dell’esecuzione di una
routine contenuta nello stesso modulo.
Variabili pubbliche: vengono dichiarate allo stesso modo delle variabili di modulo, ma la
dichiarazione utilizza la parola chiave Public in sostituzione di Dim. Vengono create quando si
esegue una qualunque routine contenuta nello stesso progetto. Si differenziano dalle variabili
di modulo per il diverso livello di visibilità.
La visibilità è un concetto molto importante anche se può non essere di immediata
comprensione. L’idea di base è che una variabile locale deve poter essere vista solo dalla routine
che l’ha dichiarata. Per esempio, il codice delle seguenti routine contiene un errore: PrimaRoutine
dichiara una variabile di nome A, poi richiama SecondaRoutine, che a sua volta dichiara una variabile
di nome B, le assegna un valore e poi tenta di assegnarne uno anche alla variabile A.
L’errore consiste nel fatto che quando viene eseguita SecondaRoutine, la variabile A non è più
accessibile; infatti non le appartiene, in quanto è una variabile locale di PrimaRoutine:
Sub PrimaRoutine()
Dim A As Integer

Call SecondaRoutine
A = 2
End Sub

Sub SecondaRoutine()
Dim B As Integer

B = 1
A = 1 ‘ errato: A non è visibile in questa routine
End Sub

Per fare in modo che la variabile A sia visibile a entrambe le routine, va dichiarata all’esterno di
queste, facendola divenire una variabile di modulo:
Option Explicit

Dim A As Integer ‘ accessibile da tutto il modulo


Sub PrimaRoutine()
Call SecondaRoutine
A = 2
End Sub

Sub SecondaRoutine()
Dim B As Integer

B = 1
A = 1 ‘ ok
End Sub

Per fare in modo che una variabile sia accessibile anche dalle routine contenute in moduli
diversi da quello in cui è dichiarata, si utilizzano le variabili pubbliche; per rendere la variabile A
di tipo pubblico, la si deve dichiarare tale all’inizio di un modulo, utilizzando la parola chiave
Public:

Option Explicit
Public A As Integer ‘ accessibile da qualunque routine del _
progetto

Stesso nome per visibilità diverse


È possibile dichiarare una variabile il cui nome coincida con quello utilizzato per le variabili di
routine diverse. Questo è consentito in quanto le variabili locali non possono essere viste dalle
altre routine, quindi non si creano ambiguità. Nel seguente esempio vi sono tre routine “a cascata”
ciascuna delle quali crea una variabile di nome VarA: si tratta a tutti gli effetti di tre variabili
distinte i cui rispettivi valori non sono influenzati dalle assegnazioni che avvengono nelle altre
routine:
Sub RoutineUno()
Dim VarA As Integer
VarA = 1
Call RoutineDue
End Sub

Sub RoutineDue()
Dim VarA As Integer

VarA = 2
Call RoutineTre
End Sub

Sub RoutineTre()
Dim VarA As Integer

Var A = 3
End Sub

Variabili di tipo definito dal programmatore


La creazione di una variabile basata su un nuovo tipo creato mediante l’istruzione Type, già
descritta, rispetta le usuali regole che governano questa operazione. Solo l’accesso ai vari
elementi che costituiscono la variabile impone una sintassi particolare, ma intuitiva, che inizia
riportando il nome della variabile seguita dai vari componenti, detti membri, definiti all’interno
dell’istruzione Type, separati dal punto:
Option Explicit

Type Persona
Cognome As String
Nome As String
DataNascita As Date
End Type
Sub EsempioTipoPersona()
Dim Presidente As Persona

Presidente.Cognome = “Rossi”
Presidente.Nome = “Luca”
Presidente.DataNascita = #12/31/1965#
End Sub

Si può vedere che la routine EsempioTipoPersona crea la variabile Presidente di tipo Persona e assegna
valori alle tre variabili membro, applicando la sintassi obbligatoria per questi casi. Nel seguente
esempio sono definiti i tipi Persona e CoppiaSposata, mentre la routine EsempioTipiDefinitiDalProgrammatore
crea una variabile di tipo CoppiaSposata e assegna valori alle variabili membro Marito e Moglie. Poiché
le variabili membro sono di tipo Persona, che è costituito da altre variabili membro, l’assegnazione
della stringa “Rossi” alla variabile Cognome della variabile Marito della variabile Prossimi-
InLunaDiMiele richiede che siano tutte indicate separandole con un punto:
Option Explicit ‘ inizio del modulo

Type Persona
Cognome As String
Nome As String
DataNascita As Date
End Type

Type CoppiaSposata
Marito As Persona
Moglie As Persona
End Type

Sub EsempioTipiDefinitiDalProgrammatore()
Dim ProssimiInLunaDiMiele As CoppiaSposata
ProssimiInLunaDiMiele.Marito.Cognome = “Rossi”
ProssimiInLunaDiMiele.Marito.Nome = “Luca”
ProssimiInLunaDiMiele.Marito.DataNascita = #12/31/1965#
ProssimiInLunaDiMiele.Moglie.Cognome = “Bianchi”
ProssimiInLunaDiMiele.Moglie.Nome = “Gabriella”
ProssimiInLunaDiMiele.Moglie.DataNascita = #1/1/1970#
End Sub

With per migliorare la leggibilità


L’istruzione With può essere applicata in vari contesti per migliorare la leggibilità di istruzioni
che operano sullo stesso oggetto, come accadeva nel precedente esempio con la variabile
ProssimiInLunaDiMiele. Essa permette di riportare un’unica volta il nome dell’oggetto e, sulle righe

successive, abbreviare quest’ultimo con il carattere punto. Si confronti la precedente routine


EsempioTipiDefinitiDalProgrammatore con la seguente che è del tutto equivalente:

Sub EsempioConWith()
Dim ProssimiInLunaDiMiele As CoppiaSposata
With ProssimiInLunaDiMiele
.Marito.Cognome = “Rossi”
.Marito.Nome = “Luca”
.Marito.DataNascita = #12/31/1965#
.Moglie.Cognome = “Bianchi”
.Moglie.Nome = “Gabriella”
.Moglie.DataNascita = #1/1/1970#
End With
End Sub

Inoltre è possibile annidare istruzioni With all’interno di altre With, come nel listato seguente che
è equivalente a quello visto in precedenza:
Sub EsempioConDoppioWith()
Dim ProssimiInLunaDiMiele As CoppiaSposata

With ProssimiInLunaDiMiele
With .Marito
.Cognome = “Rossi”
.Nome = “Luca”
.DataNascita = #12/31/1965#
End With
With .Moglie
.Cognome = “Bianchi”
.Nome = “Gabriella”
.DataNascita = #1/1/1970#
End With
End With
End Sub

NOTA Un errore ricorrente nell’utilizzo delle variabili basate sui tipi definiti dal programmatore consiste
nell’impiegare il nome del tipo al posto di quello della variabile (Figura 4.2). Per esempio, l’istruzione:
CoppiaSposata.Marito.Cognome = “Rossi”

NOTA è errata perché CoppiaSposata è un tipo (creato con l’istruzione Type) e non una variabile (creata con
l’istruzione Dim). Similmente, la seguente istruzione risulta errata perché si fa uso del tipo Persona al posto della
variabile Marito (Figura 4.3).

ProssimiInLunaDiMiele.Persona.Cognome = “Rossi”

Figura 4.2 È errato utilizzare un tipo al posto di una variabile.

Figura 4.3 Persona è un tipo e non una variabile membro di ProssimiInLunaDiMiele, quindi viene segnalato un errore.

Matrici o array
Le matrici o array sono strumenti che affiancano le variabili e si rivelano estremamente utili in
molteplici situazioni. Possono essere considerati come variabili in grado di memorizzare un
determinato numero di valori dello stesso tipo. Alle matrici si affianca il concetto di indice,
ovvero un numero o un’espressione numerica che consente di identificare ogni elemento della
matrice. Nella sintassi di Visual Basic, l’indice figura va racchiuso tra parentesi tonde,
immediatamente dopo il nome della matrice.
Le seguenti istruzioni rappresentano esempi sintatticamente corretti dell’uso degli indici relativi
alla matrice di stringhe Colori:
Dim Colori (10 * 4 + 1) As String
Dim i As Integer
Colori(1) = “Azzurro”
Colori(1) = Colori(1) & “!”
Colori(1+1) = “Rosso!”
i = 2
Colori(i + 1) = Colori(i)

NOTA Il valore utilizzato come indice nell’istruzione Dim per creare le matrici non è esattamente corrispondente al
numero complessivo di elementi che la matrice può contenere, in quanto dipende dalle impostazioni definite
attraverso l’istruzione Option Base; in questo caso, si potrebbe parlare con maggiore esattezza dell’indice
definendolo come l’ultimo elemento ammissibile per la matrice, ma sotto il profilo didattico ciò risulta fuorviante.

Dichiarazione delle matrici


Per creare una matrice si utilizzano le stesse regole che governano la dichiarazione delle
variabili, alle quali si aggiunge l’indicazione del numero massimo di elementi contenuti nella
matrice. Per esempio, l’istruzione seguente crea una matrice di nome NomeDeiMesi e di tipo String
capace di contenere 12 elementi:
Dim NomeDeiMesi(12) As String

Tali elementi saranno numerati da 0 a 11. Esiste la possibilità di ricorrere all’istruzione


Option Base 1

che impone al linguaggio di utilizzare la numerazione iniziando da 1 anziché da 0. Essa va posta


all’inizio del modulo vicino all’eventuale istruzione Option Explicit e mai all’interno delle
subroutine o funzioni. Il ricorso a questa istruzione è raro.

Matrici a due o più dimensioni


Le matrici analizzate fino a questo punto erano a una sola dimensione, ma il Visual Basic
consente di creare matrici a più dimensioni. Per esempio, una matrice in cui è riportata la quantità
di pioggia caduta ogni giorno di ogni mese dell’anno è una matrice a due dimensioni: 12 × 31
(mesi × giorni) anche se vi sono elementi che non potranno mai essere utilizzati, come il 31 del
secondo mese, ovvero febbraio.
La stessa matrice può essere utilizzata come base per l’esempio di una matrice tridimensionale,
nella quale una dimensione permette di gestire i cinque anni precedenti.
La matrice sarà composta da 5 × 12 × 31 elementi (anni × mesi × giorni). Senza andare molto
lontano, anche un foglio di lavoro di Excel è un esempio di matrice bidimensionale.
La sintassi per dichiarare matrici a più dimensioni è un’estensione di quella a una sola
dimensione e prevede di indicare le altre dimensioni dopo la prima, separandole con una virgola.
Per esempio, una matrice composta da dieci righe e cinque colonne viene dichiarata attraverso la
seguente istruzione:
Dim Matrice(10, 5) As Integer

Facendo un parallelo con le cartelle di Excel, se un foglio di lavoro può essere facilmente
considerato come una matrice bidimensionale, la loro successione può essere considerata come
un’ulteriore dimensione, ottenendo una matrice a tre dimensioni: foglio, colonna e riga. La
dichiarazione di una matrice di 2 × 3 × 4 elementi viene dichiarata mediante la seguente istruzione:
Dim Matrice(2, 3, 4) As Integer

Figura 4.4 Il numero di indici utilizzati per indicare un elemento è diverso dalle dimensioni della matrice.

Nel caso nella routine venisse utilizzata la matrice Matrice impiegando un numero di indici
diverso da quello utilizzato nella sua creazione, Visual Basic lo segnalerebbe con un’apposita
finestra (Figura 4.4).

Esempio di ciclo per accedere alle varie dimensioni


Il seguente listato rappresenta un esempio di una routine che crea una matrice di dimensione 2 ×
3 × 4 e inserisce in ogni elemento un numero calcolato sulla base del valore delle variabili a, b, c,
utilizzate nei cicli For/Next. È molto utile osservare l’utilizzo delle funzioni LBound e UBound che
restituiscono i limiti delle dimensioni della matrice. Il loro impiego consente al programmatore di
intervenire sul dimensionamento, senza doversi preoccupare di rivedere tutto il programma per
correggere gli eventuali cicli che operino su tale matrice:
Option Explicit
Option Base 1
Sub MatriceMultidimensionale()
Dim Matrice(2, 3, 4) As Long
Dim a, b, c As Integer
‘inserisce un valore in ogni elemento
For a = LBound(Matrice, 1) To UBound(Matrice, 1) ‘prima _
dimensione
For b = LBound(Matrice, 2) To UBound(Matrice, 2) _
‘seconda dimensione
For c = LBound(Matrice, 3) To UBound(Matrice, 3)_
‘ terza dimensione
Matrice(a, b, c) = (a * 10000 + b * 100 + c)
Next c
Next b
Next a
‘visualizza nella finestra immediata il valore di ogni _
elemento
For a = LBound(Matrice, 1) To UBound(Matrice, 1)
For b = LBound(Matrice, 2) To UBound(Matrice, 2)
For c = LBound(Matrice, 3) To UBound(Matrice, 3)
Debug.Print “Elemento “ & a & “,” & b & “,” _
& c & “ = “ & Matrice(a, b, c)
Next c
Next b
Next a
End Sub

La Figura 4.5 mostra la finestra Immediata che stampa i valori restituiti dalla matrice.

Figura 4.5 La finestra Immediata con i valori della matrice Matrice.

Le costanti
Le costanti sono valori inseriti nel programma che non devono essere modificati e sono
utilizzate con un nome convenzionale definito dal programmatore all’atto della loro dichiarazione.
Il rapporto tra le variabili e le costanti è stretto solo in apparenza, ma può aiutare a costruire un
parallelo: la differenza sostanziale risiede nel fatto che il valore assegnato a una variabile è
modificabile durante l’esecuzione del programma (rispettando sempre le regole di vita e
visibilità), invece il valore assegnato a una costante non può essere modificato nel corso
dell’esecuzione del programma, per cui rimane costante.
Per esempio, si potrebbe creare una variabile di nome PiGreco e assegnarle il valore
3,1415926535897932, ma potrebbe accadere di scrivere erroneamente un’istruzione che ne
modifica il valore e, una volta eseguita, altererebbe tutti i calcoli che utilizzassero tale variabile
all’interno di quel programma. Invece, se venisse definita una costante con lo stesso nome e lo
stesso valore, ogni istruzione che tentasse di modificarla causerebbe una segnalazione di errore
(Figura 4.6).
Figura 4.6 Il programma ha tentato di modificare il valore di una costante.

La dichiarazione delle costanti può essere effettuata mediante i seguenti elementi:


la parola chiave Const;
il nome da assegnare alla costante;
la parola chiave As;
la parola chiave che definisce il tipo di valore contenuto nella costante;
il carattere =;
il valore da assegnare alla costante.
Di seguito è riportato un esempio di dichiarazione di una costante di nome PiGreco, definita di
tipo Double, cui viene assegnato il valore:
Const PiGreco As Double = 3.14159265358979

Può anche accadere di incontrare forme più sintetiche di dichiarazione nelle quali non viene
indicato il tipo, quindi sarà il compilatore a decidere quale sia più corretto utilizzare in base al
valore indicato; la seguente istruzione creerà una costante il cui tipo sarà Double:
Const PiGreco = 3.14159265358979

Di seguito sono mostrati alcuni esempi di definizione di costanti, il cui contenuto è mostrato
nella Figura 4.7:
Option Explicit
Const TitoloApplicazione = “Questo e’ il mio programma”
Const VersioneProgramma = “3.11 Beta”
Const TitoloFinestaPrincipale = TitoloApplicazione & “_
“ & VersioneProgramma
Const DataDiScadenza = #12/31/2009#
Const OrarioFissatoComeInizio = #8:00:00 AM#
Figura 4.7 La finestra Variabili locali mostra il contenuto delle costanti di una routine durante la fase di di debug.

È interessante osservare che le costanti possono essere definite tramite l’impiego combinato di
altre costanti, come mostrato nell’esempio precedente.

Visibilità delle costanti


Le costanti sono generalmente create all’inizio del modulo sotto la parola chiave Option Explicit;
in questo modo sono visibili e quindi utilizzabili da tutte le routine del modulo.
È anche possibile creare costanti che siano visibili solo da una routine, in questo caso devono
essere dichiarate all’interno della routine stessa. Il loro utilizzo è generalmente limitato a sostituire
quei valori che hanno un significato solo all’interno della routine e che, se dichiarati all’inizio del
modulo, potrebbero causare un sovraffollamento di costanti e quindi un inutile aggravio per chi
dovesse guardare il codice.
Se invece il problema fosse inverso e si avesse la necessità di condividere una costante tra più
moduli, allora si dovrebbe utilizzare la parola chiave Public posta prima di Const.
NOTA La parola chiave Public modifica lievemente la sintassi dichiarativa delle variabili rispetto alle costanti: per le
variabili pubbliche si utilizza la sola parola chiave Public eliminando quindi Dim, mentre per le costanti Public si
affianca a Const.

Variabili dimensionate mediante costanti


L’impiego delle costanti non è limitato alle espressioni matematiche, ma è esteso anche alle
istruzioni, per cui il lavoro del programmatore viene facilitato perché si possono definire alcuni
valori attraverso costanti, ed egli può agire su tale valore per ottenere una modifica del
comportamento di tutto il programma. Per esempio, nel listato seguente viene mostrata una
semplice tecnica di utilizzo delle costanti per definire una dimensione che verrà impiegata per
dichiarare una variabile, di tipo stringa a lunghezza costante, ed effettuare controlli atti a evitare
che l’utente digiti un testo troppo lungo, che sarebbe quindi troncato perdendo informazioni:
Sub InputDiLunghezzaControllata()
Const MaxLunghezzaCognome = 20
Dim Cognome As String * MaxLunghezzaCognome
Dim CognomeTemporaneo As String
Dim Finito As Boolean
Finito = False
While Not Finito
CognomeTemporaneo = InputBox(“Digitailcognome”)
If Len(CognomeTemporaneo) <=MaxLunghezzaCognome Then
Cognome = CognomeTemporaneo
Finito = True
Else
MsgBox “Cognometroppolungo(massimo ammesso: “_
& MaxLunghezzaCognome_
& “). Ridigitare.”
End If
Wend
End Sub

Se si verificasse la necessità di memorizzare cognomi lunghi più di quanto definito nella


costante MaxLunghezzaCognome, l’unica operazione da eseguire consisterebbe nel variarne il valore:
automaticamente tutta la routine comincerebbe a utilizzarlo senza che il programmatore debba
ulteriormente intervenire; questo evita anche alcuni insidiosi errori causati dalla mancata modifica
manuale di tutte le istruzioni qualora non si siano utilizzate le costanti.

Le costanti di Visual Basic


Il Visual Basic mette a disposizione numerose costanti per indicare determinati valori in forma
più mnemonica e chiara. Per esempio, i pulsanti sono identificati da un valore numerico, ma le
loro costanti sono molto più intuitive e semplici da ricordare: vbOkOnly, vbOkCancel, vbAbortRetryIgnore.
Oppure i colori sono codificati attraverso un numero, ma esiste l’equivalente costante come:
vbBlack, vbBlu, vbRed e vbYellow.

Per vedere quali siano le costanti disponibili si può ricorrere al visualizzatore di oggetti tramite
Visualizza/Visualizzatore di oggetti e, digitando la parola constants nella casella Testo da cercare,
si ottiene un elenco di tutte le costanti disponibili.
NOTA Il prefisso xl oppure vb identifica l’ambito d’impiego della costante: xl indica costanti di oggetti di Excel
mentre vb è relativo a costanti del linguaggio. Ne consegue che qualunque programma che utilizzi le costanti con
prefisso xl è orientato a gestire Excel.
Capitolo 5

Gli operatori

Ogni linguaggio di programmazione utilizza alcuni caratteri per indicare i vari operatori che è in
grado di gestire.

Operatori matematici
Gli operatori matematici sono quelli che indicano le operazioni matematiche e sono:
+: addizione;
–: sottrazione;
*: moltiplicazione;
/: divisione;
\: divisione con restituzione della sola parte intera;
^: elevazione a potenza.

NOTA Non sono disponibili le parentesi quadre e graffe per definire i livelli multipli di priorità nei calcoli, ma si
ricorre all’uso ricorsivo di parentesi tonde, per esempio 1 * (2 / (3 + 4)).

Somma e sottrazione
La somma avviene rispettando le usuali regole matematiche di precedenza degli operatori
prioritari quali la moltiplicazione e la divisione. Un esempio di utilizzo dell’operatore di somma è
il seguente:
a = b + c + 1

È utile riportare un’osservazione sulle somme tra addendi di tipo diverso: se il primo addendo è
di tipo Single e il secondo di tipo Long, il risultato sarà di tipo Double. Se il risultato dovrà essere
memorizzato in una variabile di tipo Variant, essa assumerà internamente il tipo Double , altrimenti il
risultato sarà convertito per accordarsi al tipo della variabile e, se essa non potrà contenerlo,
verrà generato un errore di overflow. (L’operatore + è utilizzato anche per concatenare le
stringhe.)

Moltiplicazione e divisione
La moltiplicazione non presenta particolarità, mentre la divisione si presta a una
considerazione, in quanto il Visual Basic fornisce tre strumenti:
l’operatore di divisione /;
l’operatore di divisione con restituzione della parte intera che tralascia la parte decimale \;
l’operatore Mod che restituisce la sola parte decimale della divisione.
Per evidenziare la differenza, nella Tabella 5.1 sono riportati alcuni esempi dell’utilizzo di tali
operatori.
Tabella 5.1 I vari tipi di divisione a confronto
Dividendo Operatore Divisore Quoziente
11 / 4 2,75
11 \ 4 2
11 Mod 4 3

NOTA L’operatore \ corrisponde alla funzione Int().

Operatore di assegnazione =
L’operatore di assegnazione permette di assegnare un valore a una variabile o a una proprietà di
un oggetto.
Il seguente frammento di codice contiene due esempi di assegnazione: il primo assegna il testo
“Questo è il testo che compare sul pulsante” a una stringa, il secondo assegna il valore di tale stringa
alla proprietà .Caption di un pulsante di nome CommandButton1, presente nell’UserForm a cui appartiene
questo frammento:
Dim Str As String
Str = “Questo è il testo che compare sul pulsante”
CommandButton1.Caption = Str

NOTA L’operatore di assegnazione coincide graficamente con quello di confronto di uguaglianza. Ciò non causa
generalmente nessuna confusione nel programmatore che si abitua con una certa rapidità a riconoscerli e
distinguerli nel loro significato. L’unico aspetto che lascia momentaneamente confuso chi non ha mai avuto
esperienze di sviluppo software è proprio il carattere uguale come operatore di assegnazione, in quanto si tende a
considerare l’uguale (=) un’asserzione di eguaglianza tra il valore posto alla sua destra e quello alla sua sinistra: si
tratta di una normale perplessità originata da quanto appreso sui banchi di scuola.

Operatori di confronto
Gli operatori di confronto vengono utilizzati per verificare condizioni e sono riportati nella
Tabella 5.2.
Tabella 5.2 Operatori di confronto
Operatore Simbolo Esempio
Minore < a<b
Minore o uguale <= a <= b
Uguale = a=b
Diverso <> a <> b
Maggiore > a>b
Maggiore o uguale >= a >= b

L’operatore Is
L’operatore Is viene utilizzato per verificare se due variabili di tipo Object indicano lo stesso
oggetto. Il seguente listato contiene una routine che utilizza due variabili di nome o1 e o2 : alla
prima viene assegnato un riferimento all’oggetto di nome ThisWorkbook e la successiva istruzione
MsgBox consente di osservare il risultato del test Is applicato a queste variabili.

Successivamente, anche la variabile o2 viene impostata con il riferimento dello stesso oggetto di
o1 , quindi dal test o1 Like o2 si otterrà il risultato True:

Sub EsempioOperatoreIs()
Dim o1 As Object
Dim o2 As Object
Set o1 = ThisWorkbook
MsgBox o1 Is o2 ‘ l’op. “Is” restituisce False
Set o2 = ThisWorkbook
MsgBox o1 Is o2 ‘ l’op. “Is” restituisce True
End Sub

Operatori logici
Se gli operatori di confronto permettono di mettere in relazione due valori tra loro; gli operatori
logici, descritti di seguito, vengono utilizzati per costruire test complessi basati su più relazioni.
And. Restituisce il valore True se il risultato della valutazione delle condizioni, poste alla sua
destra e alla sua sinistra, è per entrambe True, altrimenti restituisce il valore False.
Or. Restituisce il valore True, se il risultato della valutazione di almeno una delle condizioni

poste a sinistra e a destra è True, altrimenti restituisce il valore False.


Not. Inverte il valore booleano che lo segue.

Si guardi il seguente esempio di condizione in un’istruzione If:


If a < b And c > d Then

La condizione risulterà vera se il valore di a è minore di b (a<b) e (And) il valore di c è maggiore


di quello della variabile d (c>d). Se una o entrambe le relazioni risultano non vere, allora tutta la
condizione sarà considerata non vera. La stessa condizione che utilizza l’operatore Or è la
seguente:
If a < b Or c > d Then

A differenza della precedente condizione, essa sarà considerata vera se il valore di a è minore
di b oppure se il valore di c è maggiore di d: non importa che entrambe siano vere, però se
entrambe sono false allora il risultato che si otterrà è False. L’operatore Not permette di invertire il
risultato booleano che si ottiene da una condizione. Per esempio, l’istruzione:
If Not RigaCorrente = 65536 Then

è composta da un test che verifica se il valore della variabile RigaCorrente è uguale al numero
65536; il risultato viene invertito dall’operatore Not. Per esempio, se la variabile contiene il valore
1 allora la condizione risulterà vera. L’impiego dell’operatore Not viene generalmente evitato dai
programmatori alle prime armi in quanto può essere causa di problemi nello scrivere i test, ma in
talune situazioni si rivela utile per rendere il codice più leggibile; la seguente istruzione valuta il
valore della variabile booleana RaggiuntaFineDelFoglio e risulta decisamente comprensibile a una
prima occhiata:
If Not RaggiuntaFineDelFoglio Then

Esprimere gli intervalli


Per creare condizioni che verifichino se il valore di una variabile è compreso in un determinato
intervallo si ricorre a questi operatori. Per esempio, per verificare se la variabile Mese contiene un
valore compreso tra 1 e 12, è possibile scrivere le seguenti istruzioni equivalenti:
If Mese >= 1 And Mese <= 12 Then
If Mese > 0 And Mese < 13 Then
If Not Mese < 1 and Not Mese > 12 Then

And e Or in sequenza
Attraverso gli operatori And e Or si possono verificare condizioni molto complesse:
If Mese >= 1 And Mese <= 12 And Giorno >= 1 And Giorno <= _<
31 Then

Poiché è stato utilizzato il solo operatore And non vi sono problemi, mentre l’impiego congiunto
di operatori Not, And e Or richiederebbe una maggiore attenzione in quanto essi vengono valutati
gestendo un ordine di priorità, come avviene con gli operatori matematici.
Per evitare problemi di priorità è possibile ricorrere alle parentesi, le quali possono contribuire
a rendere più chiara la condizione che, comunque, può essere spezzata su più righe:
If (Mese >= 1 And Mese <= 12) And (Giorno >= 1 And Giorno <= 31) Then

oppure
If (Mese >= 1 And Mese <= 12) And _
(Giorno >= 1 And Giorno <= 31) Then

NOTA Le istruzioni che vengono spezzate su più righe impongono di inserire alla fine di ognuna di esse uno spazio
e il carattere underscore, fatta eccezione per l’ultima.
Confronto con operatori logici
La Tabella 5.3 riporta i valori di verità che si ottengono dagli operatori in base alle varie
combinazioni possibili.
Tabella 5.3 Risultati ottenibili dalla combinazione di valori booleani
Sinistra Operatore Destra Risultato
True And True True
False And False False
True And False False
False And True False
True Or True True
False Or False False
True Or False True

False Or True True


Not True False
Not False True

Concatenazione di stringhe
È estremamente usuale per i programmatori prendere il valore di due o più stringhe per crearne
una nuova, composta dal loro valore. Allo scopo è disponibile l’operatore &. Un esempio di come
concatenare alcune stringhe, per assegnare il risultato a una variabile di tipo String, può essere
fornito dalla seguente istruzione:
Str = “Questa è una “ & “stringa concatenata”
Str = Str1 & Str2
Str = “Il Signor “ & Cognome & “ ha questo nome di _
battesimo:” & Nome

Come si può osservare, la sintassi è semplice:


una stringa o una costante di tipo stringa;
l’operatore &;
una stringa o una costante di tipo stringa.
Essa prevede la possibilità di proseguire, ripetendo gli ultimi due elementi, per creare
concatenazioni di numerose stringhe:
Str = Str1 & Str2 & Str3 & Str4 & Str5 & Str6 & Str7

La seguente routine rappresenta un esempio di concatenazione, utilizzando valori di tipo stringa


ottenuti da vari oggetti di Excel più testi costanti e variabili (Figura 5.1):
Sub OperatoreDiConcatenazione()
Dim Str As String
Str = “La cartella corrente si chiama “ & _
ActiveWorkbook.Name
Str = Str & “ mentre il foglio si chiama “ & _
ActiveWorkbook.ActiveSheet.Name
MsgBox Str
End Sub
Figura 5.1 Il testo è stato costruito con una concatenazione di stringhe.

L’operatore di concatenazione +
Si segnala che l’operatore + può venire utilizzato per concatenare le stringhe in sostituzione
dell’operatore &. Essi non sono perfettamente equivalenti anche se la sintassi è identica; infatti,
l’operatore & richiede esplicitamente di gestire i valori come stringhe e concatenarli, mentre
l’operatore + assume il significato di somma o di concatenazione in relazione al tipo di oggetti su
cui opera, ma non sempre il compilatore è in grado di stabilirne con esattezza il significato
desiderato dal programmatore, per esempio se gli oggetti sono di tipo Variant.

Priorità nell’ordine di valutazione


Gli operatori vengono elaborati rispettando il loro livello di priorità o le loro regole di
precedenza. È utile conoscere tale ordine per comprendere eventuali apparenti anomalie nei test o
nei calcoli matematici che, probabilmente, sono risolvibili con un appropriato ricorso alle
parentesi.
NOTA Anche quando si ha una ragionevole padronanza degli operatori e delle loro precedenze le parentesi
possono rivelarsi utili, perciò se ne consiglia comunque l’utilizzo.
Capitolo 6

Funzioni, routine e subroutine

L’utilizzo di Excel porta a una naturale familiarità con le funzioni in quanto esse rappresentano
uno dei punti di forza dei fogli elettronici. Nella programmazione di Excel sono presenti numerose
funzioni, alcune proprie del Visual Basic, altre specifiche del foglio di lavoro. In Visual Basic, la
funzione è un potentissimo strumento per ottenere un’informazione o una conversione ed è
possibile crearne di nuove utilizzando questo stesso linguaggio.
NOTA Nel corso del capitolo, così come nel gergo dei programmatori, l’aggettivo chiamante fa riferimento a una
routine oppure a una funzione che, durante la propria esecuzione, viene temporaneamente sospesa per avviare
un’altra routine o funzione. Quest’ultima viene detta routine o funzione richiamata.

Differenza tra funzione, routine e subroutine


Le routine sono programmi che eseguono una determinata elaborazione con diversi scopi, quali
visualizzare un messaggio, eseguire un calcolo da inserire in una variabile pubblica, acquisire un
dato dall’utente o da un’altra fonte.
Le funzioni sono programmi che eseguono una determinata elaborazione con il solo scopo di
restituire un valore, elaborato in base a informazioni ricevute come parametri oppure utilizzando
variabili pubbliche.
Le subroutine sono un “incrocio” tra routine e funzioni: le elaborazioni che i programmatori
fanno svolgere alle subroutine possono essere equivalenti di una funzione o di una routine, con il
vantaggio che queste ultime accettano i parametri anche se non restituiscono valori al chiamante.
Per la precisione, le subroutine sono utili per separare una routine in più parti autonome che
svolgono uno specifico compito; questo consente:
di migliorare sensibilmente la leggibilità della routine poiché il programmatore può
analizzarle senza soffermarsi su tutti i dettagli;
di ridurre i tempi di debug, grazie alla possibilità di analizzare singolarmente il codice di
ogni subroutine senza dover considerare tutto l’insieme;
di creare gruppi di istruzioni che possono essere utilizzati in più punti del programma senza
doverli riscrivere, guadagnando in affidabilità e velocità di realizzazione.
Riguardo l’aspetto delle istruzioni che costituiscono una funzione o una routine non vi sono da
segnalare caratteristiche o limitazioni a favore dell’una o dell’altra. La Tabella 6.1 vuole costituire
un rapido riepilogo delle differenze.
Tabella 6.1 Schema delle differenze tra routine, subroutine e funzioni
Routine Subroutine Funzione
Accetta parametri No Sì Sì
Restituisce valori al chiamante No No Sì
Appare nella finestra Macro di Excel Sì No No
Appare nella finestra Funzioni di Excel No No Sì
Gestisce il dialogo con l’utente Sì Sì Sì (sconsigliato)
Può essere il punto d’inizio del programma Sì No No

Routine che restituiscono valori


Sebbene le routine non nascano per restituire valori al chiamante, esistono alcune tecniche che
aggirano tale ostacolo, ovvero:
si può utilizzare una subroutine, ovvero una routine che accetta parametri (che verranno
dichiarati utilizzando la parola chiave ByRef) e i valori che essa deve passare al chiamante
verranno inseriti in tali parametri;
si possono utilizzare variabili pubbliche, il cui valore verrà impostato dalla routine e sarà
letto dal chiamante.

NOTA Prima di utilizzare la parola chiave ByRef è fondamentale comprenderne il significato, che sarà illustrato in
questo stesso capitolo.

Richiamare routine, subroutine e funzioni


Non esistono sostanziali differenze nello scrivere le istruzioni che richiamano una routine, una
subroutine o una funzione.

Richiamare routine e subroutine prive di parametri


Per richiamare una routine o una subroutine che non prevede parametri da un’altra routine,
subroutine o funzione si può alternativamente:
utilizzare l’istruzione Call seguita dal nome della routine, sub-routine o funzione da eseguire;
indicare il solo nome della routine o subroutine da eseguire.
Le seguenti istruzioni sospendono l’elaborazione della routine che le contiene per eseguire la
routine ChiudiTuttiIFogliAperti:
If FineDellElaborazione = True Then
Call ChiudiTuttiIFogliAperti
End If

If FineDellElaborazione = True Then


ChiudiTuttiIFogliAperti
End If

Richiamare una subroutine richiedente parametri


Se deve essere richiamata una subroutine che richiede parametri allora è necessario ricorrere
all’istruzione Call e inserire, dopo il suo nome, i valori separati da una virgola e racchiusi tra
parentesi:
Call ChiudiTuttiIFogliApertiDellaCartella(“c:\Cartel1.xls”)

Richiamare una funzione


Sintatticamente, richiamare una funzione è identico al richiamare una routine o una subroutine,
ma occorre considerare due aspetti:
la funzione restituisce un valore;
un’istruzione può richiamare più funzioni in sequenza come:
Assieme = Trim(Nome) & “ “ & Trim(Cognome)

È ancora possibile utilizzare l’istruzione Call, gestendo una funzione esattamente come una
subroutine, ma in tal modo si perde il risultato che la funzione restituisce. Nelle seguenti due righe
di codice viene richiamata la funzione Unisci(), ma il suo risultato non viene utilizzato:
Call Unisci(Cognome, Nome)
Unisci(Cognome, Nome)

Generalmente il risultato dell’elaborazione viene memorizzato in una variabile o utilizzato in


una condizione come nei seguenti esempi:
If ConteggiaIscritti() < 30 Then
Totale = SommaImporti()
TotaleFasce = SommaImportiDiFascia(“A”)+ _
SommaImportiDiFascia(“B”)
TotaleDiOggi = CalcolaImportiDelGiorno( Day(Date) )

Il problema del ByRef


Nel chiamare una funzione o una subroutine, che utilizza la parola chiave ByRef nella
dichiarazione di uno o più parametri, è necessario essere a conoscenza di un comportamento tipico
del Visual Basic, ovvero, se la funzione viene richiamata:
attraverso l’istruzione Call, allora ByRef sarà operativo;
solo con il suo nome, allora ByRef non opererà e la funzione riceverà una copia del valore.
Per esempio, la funzione:
Function EliminaSpaziSuperflui(ByRef str As String)
Do While Left(str, 1) = “ “
str = Mid(str, 2)
Loop

Do While Right(str, 1) = “ “
str = Mid(str, 1, Len(str) - 1)
Loop
End Function

può essere richiamata dalla seguente routine mediante Call (Figura 6.1) ottenendo un
cambiamento del valore della variabile Testo, in cui la funzione EliminaSpaziSuperflui() avrà eliminato
gli spazi iniziali e finali:
Sub EliminazioneSpazi()
Dim Testo As String

Testo = “ ABC “
MsgBox “1: {“ & Testo & “}”
Call EliminaSpaziSuperflui(Testo)
MsgBox “2: {“ & Testo & “}”
End Sub

Figura 6.1 L’istruzione Call di funzioni con ByRef funziona correttamente.

Oppure la stessa routine può essere modificata nella riga che chiama la funzione
EliminaSpaziSuperflui() senza ottenere il cambiamento del valore di Testo (Figura 6.2):

Sub EliminazioneSpazi()
Dim Testo As String

Testo = “ ABC “
MsgBox “1: {“ & Testo & “}”
EliminaSpaziSuperflui(Testo)
MsgBox “2: {“ & Testo & “}”
End Sub
Figura 6.2 Richiamare funzioni con ByRef non utilizzando l’istruzione Call comporta un difetto.

Creare una nuova funzione


Le nuove funzioni possono essere inserite nella finestra Codice di un modulo o di un form
(Figura 6.3). La sintassi più semplice prevede:
la parola chiave Function;
il nome;
la parentesi tonda aperta;
gli eventuali parametri separati da una virgola;
la parentesi tonda chiusa;
opzionalmente, la parola chiave As seguita dal tipo di valore da restituire.
Figura 6.3 La finestra Codice dopo aver creato una nuova funzione.

Sulle righe successive troveranno posto:


il corpo;
la parola chiave End Function.
Segue una semplice funzione esemplificativa:
Option Explicit

Function RacchiudiFraParentesiQuadre(TxtAsString) As String


RacchiudiFraParentesiQuadre = “[“ & Txt & “]”
End Function

Parti componenti: nome, parametri, tipo da restituire


Osservando il precedente codice e confrontandolo con le regole appena illustrate si può dedurre
che:
Function è la parola chiave usata per dichiarare una funzione;
RacchiudiFraParentesiQuadre è il suo nome;

Txt As String ha un parametro di nome Txt di tipo String;

As String, posto alla fine della riga, indica che la funzione restituirà un valore di tipo stringa.

Nel corpo della funzione è presente solo un’istruzione che assegna un valore concatenato a una
variabile che:
non è mai stata allocata attraverso l’istruzione Dim, né è stato dichiarato il suo tipo;
ha il nome uguale a quello della funzione che la contiene;
non è, anche se non determinabile con sicurezza leggendo solo il codice riportato, una
variabile pubblica definita in altri moduli.
In altre parole non si tratta di una normale variabile perché:
viene automaticamente allocata al momento in cui la funzione incomincia l’elaborazione;
il suo tipo viene definito mediante l’indicazione collocata dopo la parentesi tonda chiusa
dell’istruzione Function e, se tale informazione viene omessa dal programmatore, il Visual
Basic utilizzerà implicitamente il tipo Variant;
la sua vita e la visibilità sono limitate alla funzione stessa;
il valore in essa contenuto verrà restituito al chiamante al termine dell’elaborazione della
funzione.
Le ultime considerazioni sono:
il corpo della funzione è costituito da normali istruzioni in linguaggio Visual Basic e quindi
anche richiami di altre funzioni o routine;
la parola chiave End Function indica la fine del corpo.

Sul nome non valgono le regole di Excel


Il nome che viene assegnato a una funzione rispetta le regole sintattiche dei nomi delle variabili
o di quelli delle routine; in questo caso, le regole che sovrintendono i nomi delle funzioni proprie
di Excel non trovano applicazione.
Per esempio, il nome della funzione di Excel ANNULLA.SPAZI() non è sintatticamente corretto
per il Visual Basic in quanto contiene il carattere punto.
Attenzione, inoltre, ai caratteri maiuscoli e minuscoli nei nomi di funzione: per il Visual Basic,
RaccogliOpzionale() e RACCOGLIOPZIONALE() sono equivalenti (Figura 6.4).
NOTA La funzione ANNULLA.SPAZI() di Excel trova il suo equivalente nelle funzioni Trim(), LTRim() e RTrim() di
Visual Basic.
Figura 6.4 Errore che si verifica se nel codice figurano funzioni o subroutine con lo stesso nome.

Parametri o argomenti
I parametri sono valori che la funzione riceve per la propria elaborazione e sono indicati tra
parentesi tonde nella riga di dichiarazione della funzione. La sintassi è identica a quella
dell’istruzione Dim, ma senza tale parola chiave, e ogni parametro viene separato dal successivo
con una virgola. Per esempio, la seguente funzione Montante(), che calcola il valore di un importo
comprensivo di interessi dopo un determinato periodo, utilizza tre parametri:
Capitale. Di tipo Currency;
Anni. Di tipo Integer;
Tasso. Di tipo Single.
Restituisce un valore di tipo Currency:
Function Montante(Capitale As Currency, Anni As Integer, _
Tasso As Single) As Currency
Montante = Capitale * (1 + Tasso / 100) ^ Anni
End Function

Il parametro è una copia del valore passato alla funzione


L’aspetto più significativo concernente i parametri consiste nel fatto che il loro valore è una
copia del valore dell’oggetto utilizzato dal chiamante. In altre parole, una funzione che modifichi i
valori contenuti nei parametri non modifica la loro origine. Un esempio potrà essere di aiuto per
capire meglio questo concetto: la funzione Trim() richiede un parametro di tipo stringa e restituisce
un valore costituito dal valore ricevuto come parametro, privato degli spazi iniziali e finali
superflui:
Sub ValoriDelChiamanteImmodificatiDalParametro()
Dim Str As String
Str = “ ABC “
MsgBox “1: {“ & Str & “}”
MsgBox “2: {“ & Trim(Str) & “}”
MsgBox “3: {“ & Str & “}”
End Sub

Nella seconda istruzione MsgBox() è presente la funzione Trim(), che visualizza il valore di Str
privato degli spazi iniziali e finali superflui, ma il valore di tale variabile è rimasto immutato. Ne
è la riprova la successiva MsgBox() in cui apparirà il valore di Str con tutti i suoi spazi.

ByRef
I parametri sono copie dei valori originari utilizzati nella chiamata della funzione o della
subroutine e ciò permette di scrivere istruzioni che possano modificare liberamente i parametri
senza preoccuparsi delle conseguenze: si tratta di copie a perdere. In taluni casi, però, può
risultare utile disporre del dato originale e non della sua copia. Per tali scopi è disponibile la
parola chiave ByRef, che richiede al compilatore di rendere disponibile e accessibile la fonte
originale dell’informazione.
Tecnicamente si dice che la variabile viene passata alla funzione o sub-routine per riferimento e
non per valore; infatti ByRef è l’abbreviazione del termine inglese By Reference (per riferimento).
La seguente funzione opera la conversione di tutte le lettere contenute in una stringa nel loro
corrispondente maiuscolo ed è simile alla funzione nativa UCase(), ma si differenzia per il fatto
che agisce direttamente sul parametro che riceve, modificandolo, in quanto esso viene indicato
nella dichiarazione di funzione come ByRef:
Function TuttoMaiuscolo(ByRef Txt As String)
Dim x As Integer

For x = 1 To Len(Txt)
If Mid(Txt, x, 1) >= “a” And Mid(Txt, x, 1) <= “z” Then
Mid(Txt, x, 1) = Chr$(Asc(Mid(Txt, x, 1)) –
Asc(“a”) + Asc(“A”))
End If
Next x
End Function

Un esempio di utilizzo è costituito dalla seguente routine, che assegna a una variabile un valore
e lo visualizza attraverso l’istruzione MsgBox str; successivamente viene eseguita la funzione
TuttoMaiuscolo(), passandole come parametro la precedente variabile e, immediatamente dopo,
viene nuovamente visualizzato il valore della variabile, che risulterà modificato (Figura 6.5):
Sub RichiamaTuttoMaiuscolo()
Dim str As String
str = “AbCdefg”
MsgBox str
Call TuttoMaiuscolo(str)
MsgBox str
End Sub

NOTA Quando vengono richiamate funzioni o subroutine i cui parametri sono identificati dalla parola chiave ByRef,
diventa fondamentale il ricorso alla parola chiave Call. Per approfondimenti, vedere più indietro in questo capitolo il
paragrafo “Il problema del ByRef”, relativo alle chiamate di funzioni e subroutine.
Figura 6.5 La funzione TuttoMaiuscolo() ha modificato la variabile della routine chiamante.

NOTA Quando si scrivono le prime funzioni può capitare che il ricorso alla parola chiave ByRef sia corretto. Prima
di utilizzarla è però bene considerare se la funzione può essere usata come parametro di altre funzioni oppure se è
possibile che il suo parametro debba essere modificato: in tali circostanze ByRef è sconsigliabile ed è invece
meglio impiegare il normale sistema di restituzione del valore attraverso la variabile con lo stesso nome della
funzione. Per chiarire il concetto, se la funzione Trim() fosse stata scritta indicando il parametro con ByRef, non
sarebbe possibile il suo impiego come invece avviene in numerosi programmi.

Matrici o array
Anche se nella pratica quotidiana è difficile incontrare funzioni che richiedano parametri di
matrice, ciò può avvenire semplicemente definendo il parametro come array.
Ovviamente, per rendere la funzione utilizzabile in una pluralità di situazioni, essa deve poter
operare con matrici di qualunque grandezza, purché coerenti con il numero di dimensioni.
Per questo motivo la dichiarazione di un parametro di matrice non riporta alcun indice:
Function SommaParametriInMatrice(Mtx() As Integer) As Long

In questo esempio è stata dichiarata una funzione che restituisce un valore di tipo Long e opera
su una matrice di tipo Integer di nome Mtx. In questo modo, essa può operare su array
monodimensionali aventi qualunque numero di elementi.
Il seguente listato riporta un esempio di una funzione operante sulle matrici, la quale viene
richiamata dalla routine Sommatoria, al cui interno sono create due matrici di nome ValA e ValB di
diverse dimensioni: la funzione SommaParametriInMatrice() calcolerà la somma dei vari elementi,
che verrà memorizzata rispettivamente nelle variabili TotaleA e TotaleB; al termine, tali risultati
saranno visualizzati mediante una finestra (Figura 6.6):
Sub Sommatoria()
Dim ValA(3) As Integer
Dim ValB(5) As Integer
Dim TotaleA As Long
Dim TotaleB As Long

ValA(1) = 2
ValA(2) = 3
ValA(3) = 4

ValB(1) = 10
ValB(2) = 20
ValB(3) = 30
ValB(4) = 40
ValB(5) = 50

TotaleA = SommaParametriInMatrice(ValA)
TotaleB = SommaParametriInMatrice(ValB)

MsgBox “TOTALI: A=” & TotaleA & “; B=” & TotaleB


End Sub

Function SommaParametriInMatrice(Mtx() As Integer) As Long


Dim T As Long
Dim x As Integer

For x = LBound(Mtx) To UBound(Mtx)


T = T + Mtx(x)
Next x
SommaParametriInMatrice = T
End Function

Figura 6.6 I risultati dei calcoli effettuati dalla funzione che gestisce le matrici.

Applicare le funzioni native di Excel al foglio di lavoro mediante VBA


Il VBA consente di scrivere routine che interagiscono con il foglio di lavoro e di applicare le
funzioni di Excel il cui risultato venga utilizzato dal programma stesso, evitando così di usare le
celle per inserirvi le formule. A questo scopo, VBA mette a disposizione l’oggetto Application, che
fornisce un altro oggetto di nome WorksheetFunction, il quale permette di indicare la funzione di Excel
desiderata come metodo. L’unico inconveniente consiste nel fatto che i nomi dei metodi non
corrispondono a quelli delle funzioni Excel in lingua italiana, bensì alla versione internazionale,
ovvero in inglese. Per esempio, per calcolare la somma delle celle contenute nell’intervallo di
celle A1:A5 del Foglio1 si utilizza la formula =Somma(A1:A5), mentre in VBA si deve scrivere
l’istruzione:
Application.WorksheetFunction.Sum(IntervalloCelle)

Un esempio di applicazione pratica è il seguente:


Sub UtilizzaFunzioneDelFoglioDiLavoro()
Dim IntervalloCelle
Dim Totale As Variant

Set IntervalloCelle = _
ActiveWorkbook.Worksheets(“Foglio1”).Range(“A1:A5”)
Totale = _
Application.WorksheetFunction.Sum(IntervalloCelle)
MsgBox Totale
End Sub
Le funzioni del foglio di lavoro
La guida di Excel include un elenco di tutte le funzioni disponibili per il foglio di lavoro
ordinate alfabeticamente. Per accedervi si deve:
aprire la guida in linea del Visual Basic mediante il tasto F1;
selezionare la scheda Indice;
digitare la parola Funzione nella casella 1.Digitare le parole chiave;
selezionare la voce Funzione nell’elenco 2.Oppure selezionarle dall’elenco;
fare clic sulla voce Funzioni relative al foglio di lavoro elencate in base alla categoria
visibile nell a casella 3.Selezionare un argomento.

Restituire uno o più valori


Per restituire un valore al chiamante si utilizza una particolare variabile, che viene
automaticamente definita da VBA al momento in cui la funzione è richiamata. Essa ha lo stesso
nome della funzione e il suo tipo è indicato dopo i parametri, utilizzando la parola chiave As. Nel
caso il tipo venga omesso, sarà impiegato Variant di default. Se è necessario restituire più valori
al chiamante si ricorre a una delle opzioni indicate di seguito.
Parametri dichiarati ByRef, in modo che la funzione inserisca in essi il valore che deve
restituire:
Sub AcquisisceAutore()
Dim Cognome As String
Dim Nome As String

Call RestituisceAutore(Nome, Cognome)


MsgBox “Libro scritto da “ & Nome & “ “ & Cognome
End Sub

Function RestituisceAutore(ByRef Nome As String, ByRef _


Cognome As String)
Cognome = “Guccini”
Nome = “Paolo”
End Function

Un tipo di dato composto, creato con l’istruzione Type, con cui si indicherà il tipo restituito
dalla funzione:
‘ Esempio di Type per restituire più valori al chiamante
Type Persona
Cognome As String
Nome As String
End Type

Sub AcquisisceAutore()
Dim Autore As Persona

Autore = RestituisceAutore
MsgBox “Libroscrittoda “ & Autore.Nome & “ “ & _
Autore.Cognome
End Sub

Function RestituisceAutore() As Persona


RestituisceAutore.Cognome = “Guccini”
RestituisceAutore.Nome = “Paolo”
End Function

Variabili pubbliche:
Public Cognome As String
Public Nome As String

Sub AcquisisceAutore()
RestituisceAutore
MsgBox “Libro scritto da “ & Nome & “ “ & Cognome
End Sub

Function RestituisceAutore()
Cognome = “Guccini”
Nome = “Paolo”
End Function

Più funzioni, ciascuna delle quali deputata a restituire un valore alla volta:
Sub AcquisisceAutore()
Dim Cognome As String
Dim Nome As String

Cognome = RestituisceAutoreCognome()
Nome = RestituisceAutoreNome()
MsgBox “Libro scritto da “ & Nome & “ “ & Cognome
End Sub

Function RestituisceAutoreCognome() As String


RestituisceAutoreCognome = “Guccini”
End Function

Function RestituisceAutoreNome() As String


RestituisceAutoreNome = “Paolo”
End Function

Creare funzioni utilizzabili nel foglio di lavoro


Ogni volta che Excel provvede a calcolare nuovamente il foglio, tutte le formule vengono
ricalcolate, quindi anche le eventuali funzioni create dal programmatore. Se esse contenessero
istruzioni per interagire con l’utente, a ogni calcolo ulteriore aprirebbero la relativa finestra.
Oltre al grave fastidio che ciò causerebbe, si aggiunge un altro problema: l’utente dovrebbe ogni
volta digitare l’opportuno valore richiesto dalle eventuali funzioni InputBox().

Excel: le finestre Macro e Inserisci funzione


Tutto il lavoro di sviluppo di routine e funzioni in linguaggio Visual Basic per Excel viene
probabilmente svolto per arricchire tale software e, quindi, è naturale attendersi che possa poi
essere utilizzato al suo interno. A questo punto le funzioni e le routine seguono due strade diverse.

Le routine e la finestra Macro


Scopo e funzionalità della finestra Macro sono già stati illustrati nei precedenti capitoli, ma ora
va evidenziato un importante dettaglio: le routine appaiono all’interno di tale finestra e sono pronte
per essere eseguite con un semplice clic (Figura 6.7).

Figura 6.7 La finestra Macro.

La finestra Inserisci funzione


Si può considerare un fatto ovvio vedere nella finestra Macro tutte le routine, ma è sorprendente
che tutte le funzioni create con l’istruzione Function in Visual Basic Editor siano diventate funzioni
del foglio di lavoro di Excel e, al pari di queste ultime, fruiscano di una serie di piccoli vantaggi
per l’utente; per esempio, è possibile inserirle avvalendosi dei normali strumenti di Excel, quali la
finestra Inserisci funzione.
Capitolo 7

Le funzioni native

In questo capitolo vengono elencate le funzioni native del Visual Basic, ovvero le funzioni che il
linguaggio mette a disposizione del programmatore per svolgere compiti semplici e ripetitivi
oppure che non potrebbero essere effettuati senza di esse. Prima di continuare è opportuno
soffermarsi su alcuni termini che verranno utilizzati nel corso del capitolo.
Tabella Ascii. È una tabella contenente 256 simboli, tra i quali trovano spazio le lettere, i
numeri, i caratteri di interpunzione e altro.
Funzione nativa. Viene messa a disposizione direttamente dal soft-ware e si contrappone alle
funzioni create dal programmatore.
Espressione. Formula che può comprendere anche funzioni, costanti e variabili.
Espressione numerica. Il suo risultato è di tipo numerico.
Espressione testuale. Il suo risultato è di tipo String.
Algoritmo. Sequenza logica di operazioni che devono essere eseguite per ottenere un
determinato risultato.
Personalizzazione. Attività del programmatore atta a ottenere dal software un risultato diverso
da quello standard, al fine di soddisfare meglio determinate esigenze.

Le funzioni del Visual Basic


Il Visual Basic dispone di una ricchissima raccolta di funzioni che permette di gestire la
maggior parte delle esigenze di un programmatore. I prossimi paragrafi elencano le principali,
raggruppandole per argomenti.

Matematiche
La Tabella 7.1 contiene una serie di funzioni matematiche native di VBA.
Tabella 7.1 Le funzione matematiche di VBA
Funzione Valore restituito
Abs(n) Valore assoluto
Atn(n) Arcotangente
Cos(n) Coseno
Exp(n) Elevazione alla n-esima potenza del logaritmo naturale ‘e’

Fix(n)
Parte intera del numero positivo senza arrotondamento, oppure arrotondamento per difetto dei numeri
negativi, ed equivale all’espressione Int (Abs numero) * Sgn (numero)

Int(n)
Parte intera del numero positivo senza arrotondamento oppure parte intera arrotondata per eccesso dei
numeri negativi
Log(n) Logaritmo naturale di base n

Rnd(n)
Numero frazionario casuale maggiore di 0 e minore di 1 che viene generato da un particolare algoritmo
matematico il cui punto di inizio può essere modificato utilizzando l’istruzione Randomize()
Round(n,d) Arrotondamento di n alla d-esima cifra decimale
Sgn(n) –1 oppure +1 se n è negativo o positivo
Sin(n) Funzione trigonometrica del seno
Sqr(n) Radice quadrata di n
Tan(n) Tangente di n

Conversione
La Tabella 7.2 contiene una serie di funzioni native di VBA per effettuare conversioni di tipi.
Tabella 7.2 Le funzioni di conversione di VBA
Funzione Valore restituito
Asc(Str) Codice Ascii del primo carattere della stringa Str ed è la funzione reciproca di Chr()
Chr(n) Carattere corrispondente all’n-esimo codice Ascii ed è il reciproco di Asc()
Hex(n) Stringa con il codice esadecimale di n
Oct(n) Stringa con il codice ottale di n
Str(n) Stringa con il valore del numero n e reciproca di Val(s) e si consiglia di valutare anche l’uso di CStr()
Val(s) Conversione del valore della stringa s nel suo equivalente numerico ed è reciproco di Str(n)
CBool(Esp) Restituisce il valore di tipo Boolean del risultato dell’espressione Esp
CCur(Esp) Restituisce il valore di tipo Currency del risultato dell’espressione Esp
CDate(Esp) Restituisce il valore di tipo Date del risultato dell’espressione Esp
CDbl(Esp) Restituisce il valore di tipo Double del risultato dell’espressione Esp
CDec(Esp) Restituisce il valore di tipo Decimal del risultato dell’espressione Esp
CInt(Esp) Restituisce il valore di tipo Integer del risultato dell’espressione Esp
CLng(Esp) Restituisce il valore di tipo Long del risultato dell’espressione Esp
CSng(Esp) Restituisce il valore di tipo Single del risultato dell’espressione Esp
CStr(Esp) Restituisce il valore di tipo String del risultato dell’espressione Esp
CVar(Esp) Restituisce il valore di tipo Variant del risultato dell’espressione Esp

In relazione al fatto che Visual Basic provvede in modo automatico a gestire le operazioni di
assegnazione dei valori, rispettando opportunamente i tipi, verrebbe da chiedersi il motivo di tante
funzioni di conversione.
Quasi sempre, Visual Basic effettua la corretta conversione semplicemente basandosi sul tipo
della variabile di destinazione, ma ciò non è possibile tutte le volte, quindi può accadere di dover
gestire manualmente la corretta conversione.
In più, c’è da considerare che vi sono situazioni in cui il programmatore può desiderare di
indicare esplicitamente il tipo che dovrà essere utilizzato, per esempio si potrebbe volere che
Visual Basic tratti tutti i calcoli di una determinata espressione matematica in formato Double. Per
esempio, la seguente formula rispetta le normali regole che il linguaggio adotta:
r = (a / b) * ((1 / c) * (d / (((e + 1.5) / 2))))

Volendo obbligare il linguaggio a utilizzare nei calcoli un determinato tipo di precisione


matematica, si può riscrivere l’espressione come:
r = CDbl(CDbl(a) / CDbl(b)) * CDbl(CDbl(1/c) * _
CDbl(CDbl(d) / CDbl((CDbl(e + 1.5) / 2))))

In questo modo si è certi che la precisione utilizzata sia quella corrispondente al tipo Double e
non vi saranno errori negli arrotondamenti, anche se ciò rappresenta una discreta perdita di tempo.
Double è il tipo preferito da VBA nei calcoli, quindi il risultato finale delle due espressioni è

identico.

Date, orari e calendario


La Tabella 7.3 contiene una serie di funzioni native di VBA per gestire date, orari e calendario.
Tabella 7.3 Le funzioni di VBA per la gestione di date e orari
Tipo
Funzione Valore restituito
restituito
Date() Data acquisita dall’orologio di sistema Date

Time() L’orario acquisito dall’orologio di sistema Date

Now() La data e l’orario acquisiti dall’orologio di sistema Date

Year(d) Anno relativo alla data d Integer


Month(d) Mese relativo alla data d Integer

Day(d) Giorno relativo alla data d Integer

Weekday(d)
Giorno della settimana relativo alla data d, espresso con un numero sequenziale Integer
che definisce 1 come domenica, 2 per il lunedì e così via
Hour(t) Ora dell’orario t Integer

Minute(t) Minuti dell’orario t Integer

Second(t) Secondi dell’orario t Integer

DateSerial(a,m, g)
Valore rappresentante una data seriale creata attraverso l’indicazione di anno,
mese e giorno nei rispettivi tre parametri
DoubleTimeSerial(h,M, Valore rappresentante un orario seriale creato attraverso l’indicazione di ora, Double
S) minuti e secondi nei rispettivi tre parametri
DateValue(Esp) Il valore dell’espressione esp Date

TimeValue(Esp) Il valore dell’espressione esp Date

Timer() Numero di secondi trascorsi dalla mezzanotte Single


Stringhe
La Tabella 7.4 contiene una serie di funzioni native di VBA per gestire le stringhe.
Tabella 7.4 Funzioni VBA per la manipolazione delle stringhe
Funzione Valore restituito Tipo restituito
LCase(S) Valore di S contenente tutte le lettere in minuscolo String

Left(S,n) Sottostringa della stringa S composta dagli ultimi n caratteri String

Len(S) Lunghezza della stringa S Long

LTrim(S) Valore di S privato degli spazi iniziali superflui String

Mid(S, p, n) Sottostringa della stringa S dal suo p-esimo carattere e lunga n caratteri String

Right(S, n) Sottostringa della stringa S composta dai primi n caratteri String

RTrim(S) Valore di S privato degli spazi finali superflui String

Space(n) Stringa composta da n spazi String

String(n, c) Stringa composta dalla ripetizione di n volte del carattere c String

StrReverse(S) Stringa composta dai caratteri contenuti nella stringa S, ma riportati in ordine inverso String
Trim(S) Stringa contenente il valore di S privato degli spazi iniziali e finali superflui String

UCase(S) Valore di S contenente tutte le lettere in maiuscolo String

Applicazione delle funzioni native di conversione


Per comprendere appieno l’uso e l’applicazione delle numerose funzioni disponibili in VBA,
vengono riportati esempi relativi a quelle di utilizzo più frequente o non presenti in Excel.

Abs(n)
Restituisce il valore assoluto del numero o dell’espressione numerica. Il seguente frammento
richiama una funzione chiamata Calcola-Media() che restituisce un valore che viene testato per
segnalare se esso è compreso tra –2 e +2:
If CalcolaMedia() > –2 And CalcolaMedia() < 2 Then
MsgBox “La media è troppo vicina allo zero”
End If

Ricorrendo alla funzione Abs(), lo stesso test diventerebbe:


If Abs(CalcolaMedia()) < 2 Then
MsgBox “La media è troppo vicina allo zero”
End If

Int(n)
Relativamente al valore o espressione numerica che riceve come parametro, restituisce la parte
intera del numero positivo senza arrotondamento oppure la parte intera arrotondata per eccesso dei
numeri negativi:
If Int(x) = x Then
MsgBox “numero privo di parte decimale”
Else
MsgBox “il numero ha un valore decimale”
End If

Round(n, d)
Per consentire di gestire l’arrotondamento con semplicità, è stata introdotta la funzione Round()
che arrotonda il valore del parametro n a un numero di cifre decimali impostate attraverso il
parametro d. La seguente routine permette di visualizzare una sequenza di finestre:
Sub EsempioRound()
Dim n As Double
Dim x As Integer
n = 123.987654321098

For x = 0 To11
MsgBox Prompt:=Round(n, x)_
, Title:=”Valore “ & n & “ arrotondato alla “ & x _
& “ cifra decimale”
Next x
End Sub

Sgn(n)
Restituisce il segno matematico dell’espressione numerica che riceve come parametro attribuito
il valore 1. Quindi, se il valore del parametro è:
negativo ovvero minore di 0: Sgn() restituisce il valore –1;
uguale a zero: Sgn() restituisce 0;
positivo ovvero maggiore di 0: Sgn() restituisce il valore +1.

Chr(n)
Restituisce una stringa lunga un carattere, il cui valore è dato dalla conversione del codice Ascii
che la funzione riceve come parametro nel corrispondente carattere. Per esempio, si veda la
funzione Asc().

Str(n)
La funzione Str() è stata una delle più utilizzate prima dell’avvento del tipo Variant e dei
linguaggi che gestivano automaticamente le conversioni del valore in base alle esigenze del tipo.
In particolare, Str() restituisce una stringa che contiene il valore di n convertito in tale tipo, ma
considera sempre il carattere punto come il separatore decimale. In contesti internazionali è
consigliabile ricorrere abitualmente alla funzione CStr() che, basandosi sulle impostazioni della
voce orologio, lingua e opzioni internazionali del Pannello di controllo (Figura 7.1), ricorre
all’opportuno separatore scegliendo tra la virgola o il punto.

Figura 7.1 Il Pannello di controllo e la scheda Formati delle Opzioni internazionali e della lingua in Windows 8.

Val(s)
La funzione Val() provvede ad analizzare la stringa che riceve come parametro, per restituirne il
valore numerico di tipo Double ove possibile, altrimenti restituisce 0. In particolare, la stringa viene
analizzata da sinistra verso destra fino a quando vi sono caratteri validi, poi la funzione restituisce
il valore numerico di quanto trovato. Per esempio:
Val(“12345.6”): restituisce il valore 12345.6;
Val(“12345.6A”): restituisce il valore 12345.6 ignorando il carattere “A” e tutti quelli che
eventualmente seguono;
Val(“123A45.6”): restituisce 123 ignorando tutti i caratteri dalla A in poi;

Val(“A12345.6”): restituisce il valore 0 in quanto l’elaborazione si arresta al primo carattere, che

non è utilizzabile per eseguire conversioni e tutti i caratteri vengono ignorati.

Funzioni di conversione
Le funzioni di conversione che permettono di evitare che VBA esegua conversioni automatiche
verso tipi indesiderati sono molto utili. Il parametro Esp indica che le funzioni richiedono un
parametro tra le parentesi.
CBool(Esp): restituisce la conversione in tipo Boolean del valore dell’espressione matematica che

riceve come parametro. In particolare, il valore sarà sempre True tranne se il valore di Esp è uguale
a zero: in tal caso CBool() restituirà il valore False.
CCur(Esp): restituisce la conversione in tipo Currency del valore che riceve come parametro. La

seguente istruzione assegna alla variabile Importo il valore contenuto nella variabile Somma di tipo
Double:

Importo = CCur(Somma)

: restituisce la conversione in tipo Date del valore numerico che riceve come parametro
CDate(Esp)

(Figure 7.2 e 7.3):


MsgBox CDate(1), , “CDate(1)”
MsgBox CDate(1/3), , “CDate(1/3)”

: restituisce la conversione in tipo Double del valore numerico che riceve come
CDbl(Esp)

parametro.

Figura 7.2 Il valore convertito da CDate(1).


Figura 7.3 Il valore convertito da CDate(1/3).

CDec(Esp): restituisce la conversione in tipo Decimal del valore numerico che riceve come
parametro. È interessante notare che nell’attuale versione di Visual Basic non è possibile creare
variabili di tipo Decimal e solo quelle di tipo Variant possono assumere tale configurazione.
CInt(Esp): restituisce la conversione in tipo Integer del valore numerico che riceve come

parametro. Questa funzione è da preferire alla sua versione più antica Int(), anche se ciò implica lo
scrivere programmi che potranno essere correttamente gestiti solo da compilatori Microsoft Visual
Basic, rendendo quindi molto difficile utilizzare un listato con un altro compilatore. Però, in questo
caso, è anche importante osservare che il Visual Basic per Excel serve per scrivere programmi che
interagiscano con Excel e, conseguentemente, questo problema non è molto significativo.
CLng(Esp): restituisce la conversione in tipo Long del valore numerico che riceve come parametro.

CSng(Esp): restituisce la conversione in tipo Single del valore numerico che riceve come

parametro.
CStr(Esp): restituisce la conversione in tipo String del valore numerico che riceve come

parametro. Questa funzione viene suggerita in sostituzione di Str() e Str$().


CVar(Esp): restituisce la conversione in tipo Variant del valore numerico che riceve come

parametro.

Applicazione delle funzioni native per date, orari


e calendario
I paragrafi seguenti forniscono un’esemplificazione sull’utilizzo delle funzioni native di VBA,
riportate nella Tabella 7.3, che permettono di gestire date, orari e informazioni di varia natura sul
calendario.

Date
La parola chiave Date viene utilizzata in due contesti diversi con due significati differenti:
per un tipo di dato che è deputato a contenere date, orari o entrambi;
per una funzione e, in questo caso, non richiede le parentesi dopo il nome.
Tra le funzioni per la gestione di date e orari, Date permette di interrogare il calendario del
computer per conoscere la data del giorno corrente, che viene restituita in formato Date. La seguente
routine interroga l’orologio interno e visualizza il giorno della settimana:
Sub VisualizzaGiornoDellaSettimanaDiOggi()
Dim d As Date
d = Date
MsgBox Prompt:=Format(d, “dddd”), _
Title:=”Giorno della settima per la data del “ & d
End Sub

Time
Interroga l’orologio del computer e restituisce un valore di tipo Date con l’orario corrente:
Sub VisualizzaDifferenzaOrari()
Dim d1, d2 As Date
d1 = Time
Dim x As Long
For x = 1 To 100000000#
Sqr (Sqr(Sqr(Rnd() * 100000)))
Next x
d2 = Time
Dim TempoImpiegato As String
TempoImpiegato = Format(d2 - d1, “hh:mm:ss”)
MsgBox “il ciclo e’ stato eseguito nel tempo di “ & _
TempoImpiegato
End Sub

NOTA Si utilizza la funzione Now() per ottenere contemporaneamente sia la data sia l’ora.

Now
La funzione Now() è l’equivalente delle funzioni Date() e Time() eseguite contemporaneamente e,
per chi deve lavorare sia con le date sia con gli orari, rappresenta una soluzione ottimale. Quando,
per esempio, si acquisiscono in sequenza, ma separatamente, la data e l’orario dall’orologio del
computer mediante le funzioni Date() e Time() può accadere che, nella frazione di secondo che
intercorre tra l’elaborazione delle due istruzioni, scatti la mezzanotte; in questa circostanza si
avrebbe la data del giorno prima e l’orario del giorno corrente:
Sub EsempioNow()
Dim Adesso As Date
Adesso = Now
MsgBox Adesso
End Sub

Year(d), Month(d), Day(d)


Queste tre funzioni restituiscono rispettivamente l’anno, il mese e il giorno della data che
ricevono come parametro. Segue l’esempio relativo a Year():
Sub EsempioAnnoBisestile()
Dim Oggi As Date
Oggi = Date
If (Year(Oggi) Mod 100 = 4 And Not Year(Oggi) Mod 100 = _
0) Or (Year(Oggi) Mod 100 = 0 And Year(Oggi) Mod 400 = _
0) Then
MsgBox “Quest’anno è bisestile!”
Else
MsgBox “Quest’anno ha 365 giorni.”
End If
End Sub

Weekday(d)
La funzione Weekday() permette di ottenere il numero di tipo Integer che indica il giorno della
settimana relativo alla data che riceve come parametro. I giorni vengono rappresentati secondo il
valore della tabella riportata di seguito, dove sono indicate le relative costanti.
Giorno Costante VBA
Domenica vbSunday

Lunedì vbMonday

Martedì vbTuesday

Mercoledì vbWednesday

Giovedì vbThursday

Venerdì vbFriday

Sabato vbSaturday

Decisamente, è da preferire l’utilizzo di queste costanti invece di ricorrere al numero Integer,


perché permettono di creare programmi più chiari e leggibili.
Per inciso, si segnala che la funzione Weekday() accetta un secondo parametro opzionale, nel quale
si può indicare quale giorno va considerato iniziale per la settimana. Per esempio, in alcuni Paesi
l’inizio della settimana coincide con la domenica, e in altri con il lunedì.
La seguente routine utilizza la funzione Weekday() per visualizzare un messaggio di saluto il lunedì
e un altro il venerdì:
Sub LunediVenerdi()
Dim GiornoSettimana As Integer

GiornoSettimana = Weekday(Date)

Select Case GiornoSettimana


Case vbMonday
MsgBox “Hai trascorso un buon weekend?”
Case vbFriday
MsgBox “Oggi è venerdì. Buon weekend!”
End Select
End Sub

Hour(t), Minute(t), Second(t)


Queste tre funzioni restituiscono rispettivamente l’ora, i minuti e i secondi di un orario che
ricevono come parametro; segue l’esempio dell’impiego della funzione Hour():
Sub esempioHour()
If Hour(Time) = 17 Then
MsgBox “E’ ora del the delle 5”
End If
End Sub

DateSerial(a, m, g)
Le date vengono memorizzate in una variabile di tipo Date che è equivalente al tipo Double, per cui
si può impostare una specifica data in una variabile di tipo Date con relativa semplicità, come
spiegato nei capitoli precedenti relativamente al modo in cui vengono memorizzati questi valori.
Impostare direttamente il valore di una variabile Date è invece sconsigliabile perché:
è facile scrivere la formula errata;
non è garantita in alcun modo la compatibilità con le versioni future di VBA o di Excel;
il tempo di elaborazione che si risparmia è minimo anche nel caso l’operazione venga
eseguita centinaia di migliaia di volte.
Per impostare il valore di una variabile di tipo Date conoscendo giorno, mese e anno espressi in
formato Integer esiste la funzione DateSerial(), atta a tale scopo, che richiede, nell’ordine, tre
parametri:
un numero che rappresenti l’anno;
un numero che rappresenti il mese;
un numero che rappresenti il giorno.
La routine EsempioDateSerial costituisce un semplice esempio d’impiego di questa funzione per
costruire una data il cui giorno, mese e anno sono estratti dalla variabile Oggi; la routine si chiude
con un test che verifica se le variabili Oggi e Riconvertito sono equivalenti, come è lecito attendersi:
Sub EsempioDateSerial()
Dim g, m, a As Integer
Dim Oggi As Date
Dim Riconvertito As Date
Oggi = Date
g = Day(Oggi)
m = Month(Oggi)
a = Year(Oggi)
Riconvertito = DateSerial(a, m, g)
If Riconvertito <> Oggi Then
MsgBox “Con la data “ & Oggi & “ la funzione _
DateSerial ha un bug”
End If
End Sub

TimeSerial(h, m, s)
In maniera simile alla funzione DateSerial(), la funzione TimeSerial() opera restituendo un valore
che si può utilizzare per una variabile di tipo Date; essa richiede tre parametri per indicare:
l’ora (il valore deve essere compreso tra 0 e 23);
i minuti (il valore deve essere compreso tra 0 e 59);
i secondi (il valore deve essere compreso tra 0 e 59).

DateValue(Esp)
Questa funzione riceve come parametro una stringa contenente una data e restituisce un valore di
tipo Variant che può essere utilizzato per assegnare tale data a una variabile di tipo Date (Figura
7.4):
Sub EsempioDateValue()
Dim d As Date
d = Date
If d <> DateValue(“31 dicembre 2002”) Then
Fineanno = DateValue(“31 dicembre 2002”)
MsgBox “a capodanno mancano”_
& Fineanno - d & “ giorni”
Else
MsgBox “Auguri per un felice anno nuovo!”
End If
End Sub

Figura 7.4 La finestra aperta da EsempioDateValue.

Il seguente esempio fa un uso coordinato della funzione Format() per ottenere una stringa,
opportunamente formattata, che possa essere utilizzata dalla funzione DateValue(); in particolare, la
variabile d contiene la data corrente che viene convertita in stringa e memorizzata in str;
quest’ultima diventa il parametro per la funzione DateValue() che provvede a restituire l’equivalente
valore, in formato Date, che viene assegnato alla variabile Riconvertito. Siccome si tratta sempre
della stessa data che ha subito alcune conversioni, ovviamente la data finale sarà ancora uguale a
quella iniziale:
Sub EsempioDateValueFormat()
Dim d As Date
Dim str As String
Dim Riconvertito As Date
d = Date
str = Format(d, “dd mmmm yyyy”)
Riconvertito = DateValue(str)

MsgBox “LafunzioneFormat()” _
& vbCr & “con i seguenti parametri: “ _
& Date & “,””dd mmmm yyyy””” _
& vbCr & “produce: “ & str _
& vbCr & “che utilizzata come parametro in” _
& vbCr & “DateValue(“”” & str & “””)” _
& vbCr & “permette di ottenere la data iniziale del” _
& Riconvertito
End Sub

TimeValue(Esp)
Similmente a quanto accade per la funzione DateValue(), questa funzione restituisce un valore in
formato Date estraendolo dalla stringa che riceve come parametro:
Sub EsempioTimeValue()
Dim diff As Date
diff = TimeValue(“23:59:59”) - Time
MsgBox “Alla mezzanotte mancano” & _
vbCr & Hour(diff) & “ ore, “ & Minute(diff) & _
“ minuti e “ & Second(diff) & “ secondi”
End Sub

Applicazione delle funzioni native per le stringhe


Nella programmazione, la modifica delle stringhe è un’esigenza estremamente frequente.
Seguono esempi di loro impieghi.

LCase(S)
LCase() restituisce una copia della stringa che riceve come parametro dopo aver convertito tutte
le lettere nell’equivalente minuscolo: la lettera L iniziale è l’abbreviazione del termine inglese
Lower: minore. UCase è la funzione speculare che restituisce la stringa convertita in maiuscolo.
Queste funzioni trovano applicazione pratica per verificare i valori introdotti dall’utente, evitando
di costruire test doppi; per esempio, il test che controlla che il carattere digitato dall’utente sia una
vocale deve verificare dieci possibilità, ovvero cinque vocali minuscole e cinque maiuscole:
Sub EsempioSenzaLower()
Dim s As String

s = InputBox(“Inserisci una vocale”)


If Len(s) > 1 Then
MsgBox “solo un carattere!”
Exit Sub
End If

If Not (s = “a” Or s= “e” Or s= “i” Or s= “o” Or s= “u” _


Or s = “A” Or s= “E” Or s= “I” Or s= “O” Or s= “U”)
Then
MsgBox “Non era una vocale!”
End If
End Sub

Left(S, n), Right(S , n), Mid(S,p,l)


Queste tre funzioni permettono di estrarre parti di una stringa. In particolare:
Left(S,n) restituisce una stringa composta dai primi n caratteri dalla stringa S;
Right(S,n) restituisce una stringa composta dagli ultimi n caratteri della stringa S;

Mid(S,p,l) restituisce una stringa lunga l caratteri copiati da S iniziando dalla posizione p.

La funzione Left() permette di ottenere una copia della stringa che riceve come parametro,
limitandone la lunghezza ai primi n caratteri.
La seguente istruzione copia il primo carattere della variabile Sorg in Dest:
Dest = Left(Sorg,1)

La seguente istruzione copia il valore della variabile Sorg in Dest, escluso l’ultimo carattere,
calcolandone la lunghezza mediante la funzione Len():
Dest = Left(Sorg,Len(Sorg)-1)

Len(S)
La funzione Len() restituisce un valore di tipo Long indicante il numero di caratteri contenuti nella
stringa che riceve come parametro, in altre parole la sua lunghezza.
Il seguente frammento di codice verifica se la stringa immessa dall’utente è più lunga di un
carattere e, in tal caso, invia una segnalazione di errore:
S = InputBox(“Inserisci una vocale”)
If Len(S) > 1 Then
MsgBox “solo un carattere!”
End If

Trim(), LTrim(S), RTrim()


Queste tre funzioni restituiscono stringhe dopo aver eliminato gli eventuali caratteri “spazio”:
Trim(s) elimina gli spazi posti all’inizio e al termine della stringa.
LTrim(s) elimina gli spazi posti all’inizio della stringa (L è l’abbreviazione di Left ovvero

sinistra).
RTrim(s) elimina gli spazi posti alla fine della stringa (R è l’abbreviazione di Right ovvero

destra).

Funzioni native per l’interazione con l’utente


I programmi in VBA potrebbero non avere alcuna necessità di interagire con l’utente, in quanto
potrebbero agire attraverso i fogli di lavoro per recuperare le informazioni di cui necessitano, o su
cui operare, e utilizzare celle per inserire risultati o messaggi. La semplicità con cui il Visual
Basic consente di aprire una finestra, per richiedere all’utente di inserire un valore oppure per
visualizzargli qualcosa, è però tale che non avrebbe senso ignorarla. Gli strumenti principali sono
due: MsgBox, MsgBox() e InputBox().

MsgBox
, senza parentesi tonde per racchiudere i parametri, viene abitualmente considerata
MsgBox

un’istruzione anche se, in realtà, è una chiamata a funzione. È possibile omettere sia le parentesi,
per comodità del programmatore, sia l’istruzione Call, infatti le seguenti righe di codice sono
equivalenti per quanto riguarda il risultato:
Sub EsempioCallMsgBox()
Call MsgBox(“Questo e’ il test”)
MsgBox (“Questo e’ il test”)
MsgBox “Questo e’ il test”
End Sub

L’istruzione Call è abitualmente tralasciata, mentre l’uso delle parentesi è indispensabile per
conoscere quale pulsante è stato selezionato dall’utente per chiudere la finestra. I parametri che
tale funzione accetta e per i quali viene anche indicato il relativo nome sono riportati di seguito.
Prompt. Stringa contenente il testo che deve essere visualizzato all’interno della finestra.
Buttons. Codici dei pulsanti che dovranno essere visualizzati nella finestra e permetteranno di

chiuderla. Il valore di default corrisponde al pulsante OK.


Title. Stringa contenente il titolo della finestra; il valore di default è “Microsoft Excel”.

HelpFile. Stringa contenente il nome del file di help nel quale sono contenute le informazioni

associate a tale finestra; di default viene aperto l’help di Excel attraverso l’assistente.
Context. Nel caso sia stato indicato un file di help, questo parametro consente di specificare

esattamente quale sua porzione sia efferente alla finestra, permettendo in tal modo di
visualizzare il testo di aiuto associato a essa.
Per comprendere che cosa si può ottenere agendo sui parametri Buttons, di seguito vengono
elencate alcune possibilità:
MsgBox _
prompt:=”Esempi delle possibili combinazioni di pulsanti” _
, Buttons:=vbYesNo_
, Title:=”Nome della costante: vbYesNo “

Per poter conoscere quale pulsante è stato utilizzato dall’utente per chiudere la finestra è
necessario utilizzare la forma MsgBox(), ovvero racchiudere i parametri tra parentesi.

MsgBox()
La funzione MsgBox() è in tutto equivalente a MsgBox, ma vi aggiunge la possibilità di conoscere
quale pulsante sia stato selezionato dall’utente attraverso il valore che essa restituisce; nella
seguente tabella sono riportati i valori restituiti da ogni pulsante.
Pulsante Nome della costante Valore equivalente
OK vbOK 1
Annulla vbCancel 2
Termina vbAbort 3
Riprova vbRetry 4
Ignora vbIgnore 5
Sì vbYes 6
No vbNo 7

Il seguente listato mostra come utilizzare il valore restituito dalla funzione MsgBox():
Sub EsempioMsgBoxConRestituzione()
Dim Btn As Integer
Btn = MsgBox(“Fai un clic su un pulsante”, _
vbExclamation + vbYesNo)
Select Case Btn
Case vbYes
MsgBox “E’ stato fatto clic su Yes”
Case vbNo
MsgBox “E’ stato fatto clic su No”
End Select
End Sub

InputBox()
La funzione InputBox() permette di aprire una finestra similmente a quanto avviene con la funzione
MsgBox(), ma anzichè restituire il codice del pulsante sul quale è stato fatto clic, restituisce la stringa

che l’utente ha digitato all’interno della relativa casella. I parametri che richiede sono diversi.
Prompt. Stringa contenente il testo che deve essere visualizzato all’interno della finestra.
Title. Stringa contenente il titolo della finestra; il valore di default è “Microsoft Excel”.

Default. Valore che la casella proporrà all’utente di default.

XPos. Posizione orizzontale della finestra calcolata come distanza dal lato sinistro dello

schermo al bordo sinistro della finestra.


YPos. Posizione verticale della finestra calcolata come distanza dal lato superiore dello

schermo al bordo superiore della finestra.


HelpFile. Stringa contenente il nome del file di help nel quale sono contenute le informazioni

associate a tale finestra; di default viene aperto l’help di Excel attraverso l’assistente.
Context. Nel caso sia stato indicato un file di help, questo parametro consente di specificare

esattamente quale sua porzione sia afferente alla finestra permettendo in tal modo di
visualizzare il testo di aiuto associato a essa.
La funzione InputBox() può essere utilizzata per richiedere all’utente di digitare un valore
numerico e ripetere la domanda fino a quando non viene introdotto un valore corretto.
NOTA Il valore dei parametri XPos e YPos sono espressi con una particolare unità di misura detta twip. Se essi sono
omessi, la posizione di default della finestra viene automaticamente calcolata per apparire centrata rispetto allo
schermo.
Capitolo 8

Esecuzione condizionale e ciclica delle


istruzioni

Nei precedenti capitoli si è fatto uso del linguaggio Visual Basic per creare alcune semplici
routine esemplificative senza specificare esattamente il senso di ogni istruzione, ma cercando di
fornire una chiara via interpretativa che consentisse di comprenderne il significato anche a chi non
ha dimestichezza con la programmazione. è giunto il momento di affrontare direttamente il tema del
linguaggio e dei suoi costrutti.
NOTA Nel corso di questo capitolo si farà spesso ricorso al termine manutenzione: la manutenzione è l’attività di
modifica di un programma per adattarlo a nuove circostanze o esigenze dell’utente.

Il flusso logico
Il flusso logico è la sequenza con cui il computer elabora il programma.Esso non è lineare in
quanto esistono istruzioni:
atte a ripetere ciclicamente un insieme di altre istruzioni, come nel caso dell’analisi del
contenuto di più celle del foglio di lavoro;
atte a scegliere tra due o più gruppi di istruzioni sulla base del test di una condizione.
Questi strumenti sono disponibili in ogni linguaggio di programmazione e sono irrinunciabili.
NOTA In questo caso, quando si fa riferimento a un gruppo di istruzioni, si intendono anche le routine, subroutine e
funzioni che possono farne parte.

Il punto di inizio del programma


Nei vecchi dialetti del Basic, l’esecuzione del programma iniziava dalla prima istruzione e si
sviluppava fino a quando non veniva trovata un’apposita istruzione o era stata elaborata l’ultima
esistente. In Visual Basic per Excel, il punto di inizio può essere determinato da varie situazioni
quali:
la richiesta dell’utente di eseguire una macro attraverso l’apposita finestra di Excel;
un clic dell’utente su un pulsante o un comando di un menu che sia stato aggiunto in Excel dal
programmatore;
un evento quale l’apertura o la chiusura della cartella alla quale sia stata associata una
routine;
fare clic su un componente di un UserForm già attivato.
Per tutti questi punti d’inizio è sempre individuabile il nome di una routine: l’esecuzione ha
inizio dalla sua prima istruzione.
NOTA Il programmatore può far eseguire una routine o una funzione che non richiedano parametri attraverso il
menu Esegui Sub/ UserForm: in tal caso la posizione del cursore individuerà la routine o la funzione da elaborare.
Se esso non è collocato all’interno di routine o funzioni, allora verrà aperta la finestra Macro di Visual Basic Editor
(Figura 8.1).

Figura 8.1 La finestra Macro di Visual Basic Editor.

La sequenza
La successione delle istruzioni che vengono eseguite, detta flusso del programma è, in linea di
principio, sequenziale, ovvero dalla prima istruzione che segue la riga Sub fino a quella che
contiene l’End Sub. Vanno tenute presenti le seguenti segnalazioni di normali casi che alterano tale
sequenza:
quando viene incontrata l’istruzione Call, o un’equivalente sistema di chiamata, la routine
corrente viene temporaneamente sospesa per eseguire quella richiamata e, al suo termine,
riprenderà l’elaborazione della routine chiamante;
quando viene richiamata una funzione, la routine corrente viene momentaneamente sospesa
per eseguire la funzione e, al termine di questa, l’elaborazione riprenderà, eseguendo
un’immaginaria sostituzione del valore restituito al nome della funzione e ai suoi parametri e
continuando a elaborare l’eventuale succedersi di operazioni nella formula.
In cima all’elenco della finestra Visualizza/Stack di chiamate appare visibile la routine attiva e,
al di sotto di essa, tutte le chiamanti nell’ordine inverso a quello in cui si sono succedute. In
pratica, la prima è la routine correntemente in esecuzione che, quando terminerà, verrà eliminata
dalla finestra; il controllo passerà a quella sottostante, che acquisirà il primo posto, mentre le altre
scaleranno di una posizione (Figura 8.2).

Figura 8.2 La finestra Stack di chiamate.

Il seguente listato può aiutare a comprendere meglio che cosa accade a una routine che viene
sospesa dalla chiamata a un’altra routine; infatti, ognuna di esse crea una variabile di nome Testo
nella quale inserisce una stringa che indica il nome della routine in cui è contenuta e il richiamo a
un’altra funzione in cui avvengono le stesse operazioni. A questo punto, può sorgere spontanea una
domanda: che cosa accade alla variabile Testo, dato che ogni routine la crea e vi inserisce un
valore?
Option Explicit

Sub Prima()
Dim Testo As String
Testo = “Prima”
Call Seconda
MsgBox Testo, , “Questa finestra è stata aperta dalla _
routine Prima”
End Sub

Sub Seconda()
Dim Testo As String
Testo = “Seconda”
Call Terza
MsgBox Testo, , “Questa finestra è stata aperta dalla _
routine Seconda”
End Sub

Sub Terza()
Dim Testo As String
Testo = “Terza”
Call Quarta
MsgBox Testo, , “Questa finestra è stata aperta dalla _
routine Terza”
End Sub

Sub Quarta()
Dim Testo As String
Testo = “Quarta”
Call Quinta
MsgBox Testo, , “Questa finestra è stata aperta dalla _
routine Quarta”
End Sub

Sub Quinta()
Dim Testo As String
Testo = “Quinta”
MsgBox Testo, , “Questa finestra è stata aperta dalla _
routine Quinta”
End Sub

NOTA Se si desidera collaudare questo listato, al momento di eseguirlo è necessario fare attenzione a come si
avvia l’esecuzione in quanto, se si utilizza il pulsante o il comando Esegui Sub/UserForm, si rischia che essa non
abbia inizio dalla routine Prima perché l’esecuzione inizia dalla routine che contiene il cursore. Per evitare questo
inconveniente, si deve preventivamente posizionare il cursore in una delle istruzioni della routine Prima oppure
utilizzare Strumenti/Macro di Visual Basic Editor.

Ogni routine alloca una variabile di nome Testo che, essendo dichiarata all’interno delle
istruzioni Sub/End Sub, è di tipo locale, ovvero visibile solo da tale routine; ne consegue che tutte le
routine creano tante variabili, ognuna assolutamente indipendente dalle altre. Infatti, la sequenza
delle finestre che vengono aperte dalle varie routine incomincia dall’ultima e, ognuna di esse,
mostra il valore corretto delle singole variabili Testo (Figura 8.3). Per approfondimenti in tema di
variabili si legga il Capitolo 4, in particolare il paragrafo “Vita e visibilità delle variabili”.
NOTA In realtà, il programma subisce continuamente interruzioni causate dai cosiddetti Interrupt, generati da altri
programmi, che richiedono al sistema operativo di essere elaborati. Inoltre, lo stesso sistema operativo gestisce in
frazioni di secondo i programmi in esecuzione affinché si alternino nell’utilizzo del processore, dando la sensazione
che tutti i programmi siano eseguiti, contemporaneamente. Può aiutare a comprendere il concetto immaginare i
programmi come persone assetate sedute in cerchio, in attesa che la persona con la borraccia (il sistema
operativo) permetta loro di bere un solo sorso (il tempo di elaborazione del processore): per placare la sete
bevendo altri sorsi (completare l’esecuzione di tutte le istruzioni), sarà necessario attendere che la borraccia
compia altri giri di tutti i presenti.
Figura 8.3 Le finestre prodotte dalle routine Quinta, Quarta, Terza, Seconda e Prima.

La fine dell’esecuzione
Il termine dell’esecuzione di una routine o funzione può portare a due differenti risultati, se l’una
o l’altra erano in esecuzione.
Da un’altra routine: quest’ultima riprenderà la sua esecuzione, ciò significa che non si è
raggiunta la fine del programma che continuerà l’esecuzione.
Da un oggetto di un UserForm: lo UserForm sarà nuovamente visualizzato in attesa di altre
interazioni con l’utente, a meno che tra le istruzioni compaia l’istruzione UnLoad Me che causa la
chiusura della finestra stessa.

Le condizioni
All’interno di un programma è possibile definire test mediante i quali decidere le istruzioni che
il programma deve eseguire. Nella Tabella 8.1 è riportato un paragone tra l’azione di preanalisi,
che può svolgere una persona addetta all’ufficio rilascio patenti, e la versione informatica di tale
operazione, considerando i dati del richiedente inseriti in una variabile di tipo definito dal
programmatore (attraverso l’istruzione Type).
Il Visual Basic dispone di diverse istruzioni con alcune varianti per la gestione dei test, che
sono:
If

Select Case

Tabella 8.1 Traduzione in codice VBA di una procedura umana


Azione umana Traduzione in VBA
If _
Se il richiedente ha raggiunto la maggiore età allora CalcolaEtaInAnni(Richiedente.
DataNascita)>= MAGGIOREETA Then

la pratica può essere passata al competente ufficio per tutti gli espletamenti e InviaPraticaUfficioRilascioPatenti(Richi
gli ulteriori accertamenti del caso
altrimenti Else

segnalare che egli deve pazientare ancora un po’ MsgBox “Sii paziente!”

Fine della valutazione End If

A tali istruzioni se ne aggiungono altre per consentire la ripetizione ciclica di un blocco:


For/Next;

For Each/Next;

While/Wend;

Do/Loop.

Ognuna delle precedenti istruzioni, con le sue varianti, verrà discussa nei prossimi paragrafi.

If
L’istruzione If è la più nota, viene utilizzata da coloro che sviluppano software ed è presente in
ogni linguaggio di programmazione.
È composta dalle seguenti parti:
il test, che deve poter essere ricondotto a un risultato esprimibile con un valore di tipo
booleano oppure numerico;
la parola chiave Then, sempre presente al termine della condizione;
le istruzioni da eseguire nel caso il test risulti positivo;
eventualmente le istruzioni da eseguire nel caso il test risulti negativo, precedute da una riga
contenente la parola chiave Else;
la parola chiave End if.
Più specificatamente, si considera che il risultato del test sia:
vero (il test ha restituito un valore numerico diverso da zero oppure un tipo booleano il cui
valore è True);
falso (il test ha restituito un valore numerico uguale a zero oppure un tipo booleano il cui
valore è False).
Nei prossimi paragrafi verranno analizzate le diverse forme che può assumere l’istruzione If.

If…Then/End If
La forma If/End If è la più semplice e permette di indicare un blocco di istruzioni che verrà
eseguito se il test contenuto nell’istruzione risultasse vero.
Nel seguente esempio, la condizione è costituita da un’identità matematica, ovvero
dall’asserzione che il valore 1 è uguale al valore 1; il risultato è quindi alquanto scontato:
Sub EsempioIfSemplice1()
If 1 = 1 Then
MsgBox “Il test ha dato ‘True’ come risultato”
End If
End Sub

Questa forma viene utilizzata nei casi in cui si debbano intraprendere una o più azioni se la
condizione è vera, mentre se essa risulta False il flusso deve proseguire ignorandola e passando
alla prima istruzione successiva alla End If corrispondente alla If appena analizzata.
Nel seguente esempio viene verificato se i valori di default, utilizzati dall’applicazione, sono
già stati letti da un ipotetico file; in tal caso l’applicazione provvede a caricarli per proseguire
l’elaborazione:
If Not ParametriDefaultGiaCaricati Then
Call AperturaFileParametriDefault
End If

In questo caso, la necessità del programmatore è assicurarsi che i parametri di default siano già
stati caricati per poter proseguire il normale flusso; la If rappresenta un’azione da eseguire prima
di continuare l’esecuzione del programma con le istruzioni a essa successive.
NOTA Si noti la presenza dell’operatore Not, il quale inverte il valore booleano dell’espressione che lo segue. Il test
verifica se il contrario della variabile ParametriDefaultGiaCaricati è True, ovvero se non sono già stati caricati i
dati.

If…Then/Else/End If
La forma If…Then/Else/End If è molto comune in quanto permette di scegliere tra due blocchi di
istruzioni, basandosi sul risultato di un’espressione inserita sulla riga If. Il concetto da sottolineare
è che solo uno dei due blocchi di istruzioni sarà eseguito in base all’esito del test: i programmatori
che si cimentano le prime volte con questa forma di If tendono a confondere l’uso della If…Then/End
If, ma si tratta di un problema che si risolve quasi subito.

Nel seguente esempio viene richiesto all’utente di introdurre un valore numerico; il test verifica
attraverso la funzione IsNumeric() se quanto digitato è effettivamente numerico e, in base al risultato
di tale controllo, visualizza un messaggio differente:
Sub EsempioIfElse1()
Dim str As String
str = InputBox(“Inserisci un numero”)

If IsNumeric(str) Then
MsgBox “Il test ha dato ‘True’ come risultato”
Else
MsgBox “Il test ha dato ‘False’ come risultato”
End If
End Sub
If annidate
Le If annidate non costituiscono un tipo diverso, ma semplicemente sono istruzioni che
contengono altre If come nel seguente esempio:
Sub EsempioIfannidate1()
Dim Velocita As Single
Velocita = 70

If Velocita > 50 Then


If Velocita > 90 Then
If Velocita > 130 Then
MsgBox “Amante della velocità a rischio _
autovelox”
Else
MsgBox “Stai viaggiando in autostrada?”
End If
Else
MsgBox “Velocità fra 50 e 90”
End If
Else
MsgBox “Sei in città o fermo?”
End If
End Sub

Normalmente, nei programmi, si ricorre alle If annidate anche se talvolta possono rendere meno
immediata la comprensione del programma stesso, come nell’esempio precedente. In realtà è raro
costruire If così complesse basate sul test della stessa variabile in quanto, per tali situazioni,
esistono strumenti più sofisticati, quali l’istruzione Select Case o If/ElseIf.
È invece più comune trovare If annidate le cui varie condizioni sono basate su parametri che
non si ripetono e risultano più leggibili.

If…Then/ElseIf/Endif
Nell’esempio del paragrafo delle If annidate è stata presentata una routine che poteva essere
scritta in modo diverso e più leggibile ricorrendo alla forma If...Then/ElseIf/Endif:
Sub EsempioIfElseIf()
Dim Velocita As Single

Velocita = 70
If Velocita < 50 Then
MsgBox “Sei in città o fermo?”
Else If Velocita < 90 Then
MsgBox “Velocità fra 50 e 90”
ElseIf Velocita < 130 Then
MsgBox “Stai viaggiando in autostrada?”
Else
MsgBox “Amante della velocità a rischio autovelox”
End If
End Sub

Come si può osservare, la parola chiave ElseIf si comporta analogamente alla Else a cui viene
aggiunta una condizione, in pratica si tratta dello stesso comportamento che si ottiene dalla Else
seguita da una If/ElseIf.
If con condizioni molto lunghe
Le variabili e le funzioni con il nome molto lungo hanno il grande vantaggio di essere
autoesplicative del contenuto o della funzionalità del relativo oggetto, ma anche lo svantaggio di
richiedere molto spazio.
Le condizioni possono diventare anche particolarmente lunghe, estendendosi al di là del margine
destro della finestra e diventando così illeggibili, perciò si perde la possibilità di comprenderne il
significato a colpo d’occhio. Per aggirare questo problema è stato introdotto il carattere
underscore (_) il quale indica che l’istruzione al termine della riga su cui si trova prosegue nella
successiva. Esso deve essere collocato in una posizione che sintatticamente potrebbe accettare uno
spazio ed essere digitato facendolo precedere da uno spazio.
Inoltre, con questo sistema, è possibile utilizzare più di una riga per una singola istruzione. Nel
seguente frammento, l’istruzione If presenta la condizione su più righe, si tratta di un esempio per
mostrare varie possibilità di interruzione:
If Valore1 > Valore2 _
And Valore3 = Valore4 And _
Valore5 _
< _
Valore6 _
Then
Valore0 = 1
End If

Il carattere underscore non è utilizzabile per spezzare il valore di una stringa, ma si può
ricorrere a esso creando due stringhe concatenate, ciascuna su una riga, tramite l’apposito
operatore (Figura 8.4):
Sub EsempioACapo2()
Dim str As String

str = “abcd” _
& “efgh”
MsgBox str
End Sub

Figura 8.4 La routine EsempioACapo2.

NOTA è importante non dimenticare che sono necessari uno spazio, il carattere underscore e il ritorno a capo per
suddividere correttamente un’istruzione su più righe.
Select Case
L’istruzione Select Case è utile nella maggioranza dei casi in cui si dovrebbe costruire una serie
di If nelle quali il test si basa sulla valutazione del risultato della stessa espressione.
Essa si compone di:
parole chiave Select Case seguite da un’espressione;
parola chiave Case, con il valore o l’insieme di valori che gestisce, seguita da una o più righe
che costituiscono le istruzioni eseguite nel caso il valore dell’espressione presente in Select
Case dia un risultato tra quelli indicati nell’istruzione Case;

opzionalmente, un blocco di istruzioni che verranno eseguite e, se nessuna istruzione Case


gestisce il valore dell’espressione della Select Case, esse appariranno dopo l’istruzione Case
Else che deve essere l’ultima Case;

l’istruzione End Select che indica la fine della Select Case.

NOTA Si osservi che non esiste l’istruzione End Case ma solo la End Select.

Un esempio è indubbiamente il miglior modo per chiarire questi concetti, prendendo come
riferimento una funzione che debba restituire il nome del mese corrispondente al numero che
riceve come parametro; tale funzione potrebbe venir scritta nel seguente modo:
Function EsempioSelectCase2(N As Integer) As String
If N = 1 Then EsempioSelectCase2 = “gen”
If N = 2 Then EsempioSelectCase2 = “feb”
If N = 3 Then EsempioSelectCase2 = “mar”
If N = 4 Then EsempioSelectCase2 = “apr”
If N = 5 Then EsempioSelectCase2 = “mag”
If N = 6 Then EsempioSelectCase2 = “giu”
If N = 7 Then EsempioSelectCase2 = “lug”
If N = 8 Then EsempioSelectCase2 = “ago”
If N = 9 Then EsempioSelectCase2 = “set”
If N = 10 Then EsempioSelectCase2 = “ott”
If N = 11 Then EsempioSelectCase2 = “nov”
If N = 12 Then EsempioSelectCase2 = “dic”
If N < 1 Or N > 12 Then EsempioSelectCase2 = “Numero _
sbagliato”
End Function

Oppure, utilizzando l’istruzione Select Case:


Function EsempioSelectCase2(N As Integer) As String
Select Case N
Case 1
EsempioSelectCase2 = “gen”
Case 2
EsempioSelectCase2 = “feb”
Case 3
EsempioSelectCase2 = “mar”
Case 4
EsempioSelectCase2 = “apr”
Case 5
EsempioSelectCase2 = “mag”
Case 6
EsempioSelectCase2 = “giu”
Case 7
EsempioSelectCase2 = “lug”
Case 8
EsempioSelectCase2 = “ago”
Case 9
EsempioSelectCase2 = “set”
Case 10
EsempioSelectCase2 = “ott”
Case 11
EsempioSelectCase2 = “nov”
Case 12
EsempioSelectCase2 = “dic”
Case Else
EsempioSelectCase2 = “Numero sbagliato”
End Select
End Function

NOTA Tra tutti i gruppi di istruzioni inclusi nella Select Case, solo uno sarà eseguito: il primo la cui Case indica un
valore o criterio uguale al valore del test presente nella Select Case.

Il primo inciso riguarda la compattezza della prima forma basata sulla If…Then che, con 12 righe,
gestisce altrettante condizioni, mentre l’istruzione Select Case ne richiede addirittura 26, più del
doppio. Ciò è fuorviante, in quanto la flessibilità di questa istruzione è molto ampia e va valutata
nell’ottica che ci può essere più di una singola istruzione da eseguire per ogni possibilità. Oltre a
rendere il listato più elegante e leggibile, in quanto esiste una sola espressione che il
programmatore deve leggere mentre sono presenti tante righe Case con i valori possibili da gestire,
questa istruzione dispone di caratteristiche che la rendono estremamente interessante:
si può indicare un singolo valore: la seguente istruzione è un esempio di Case che gestisce il
valore 1:
Case 1

si può indicare più di un valore: la seguente istruzione analizza se il valore dell’espressione è


uguale a 1, 3 oppure 9:
Case 1, 3, 9

è possibile ricorrere a un confronto semplice per indicare i valori che la Case deve gestire:
Case Is > 300

è possibile indicare un intervallo: la seguente istruzione verifica se il valore dell’espressione


è compreso tra 11 e 33:
Case 11 To 33

è possibile identificare le istruzioni da eseguire nel caso il risultato dell’espressione presente


nella Select Case non rientri tra quelli indicati per le altre Case:
Case Else

si possono anche combinare tali possibilità, come deducibile dai seguenti esempi di
istruzione Case:
Case 10 To 19, 50 To 59

Case 1, 3, 9, 10 To 19, 50 To 59, Is > 300

I cicli o loop
Tra gli strumenti classici a disposizione del programmatore, che tutti i linguaggi forniscono, vi è
la possibilità di costruire cicli, ovvero una o più operazioni da ripetere varie volte. Ecco alcuni
esempi di cicli:
scorrere tutte le celle contenute in una colonna di un foglio di lavoro per contare quante
presentano un determinato valore;
scorrere tutti i fogli di lavoro per verificare se ne esiste uno con un determinato nome;
scorrere tutti i caratteri di una stringa per sostituire quelli che contengono una lettera
minuscola con l’equivalente maiuscolo;
scorrere tutti gli elementi di una matrice per porre il loro valore uguale a zero;
scorrere tutti gli oggetti di tipo Casella di testo di una finestra per cancellarne l’eventuale
contenuto.
Il ciclo viene continuamente eseguito fino a quando non è stata raggiunta la condizione di fine
che può essere identificata da:
una condizione il cui risultato è il valore booleano False, oppure numerico uguale a 0, eccetto
il ciclo Do Until/Loop;
il numero di cicli predefiniti che è stato eseguito;
una specifica istruzione che ne determina la fine, indipendentemente dal valore della
condizione o dal numero di cicli già compiuti.
Un ciclo può contenere al proprio interno uno o più cicli, facendo attenzione che il ciclo interno
sia completamente contenuto in quello più esterno, come nel classico gioco delle bambole russe o
scatole cinesi. In pratica è vietato utilizzare le istruzioni nel seguente ordine:
dichiarare il punto di inizio di un ciclo;
dichiarare il punto di inizio di un altro ciclo;
dichiarare il punto di fine del primo ciclo;
dichiarare il punto di fine del secondo ciclo.
Ciò è errato, in quanto i due cicli si intersecano. La forma corretta è la seguente:
dichiarare il punto di inizio di un ciclo;
dichiarare il punto di inizio di un altro ciclo;
dichiarare il punto di fine del secondo ciclo;
dichiarare il punto di fine del primo ciclo.

For/Next
Il ciclo For/Next è il più semplice da apprendere e utilizzare e serve a eseguire il ciclo un numero
predeterminato di volte. L’istruzione For richiede:

la parola chiave For;


una variabile numerica utilizzata per memorizzare il numero del ciclo in esecuzione;
il carattere uguale;
il limite iniziale del ciclo;
la parola chiave To;
il limite finale del ciclo.
A essa seguono le istruzioni che costituiscono il ciclo vero e proprio, ovvero quelle che
verranno eseguite più volte fino a quando il ciclo non sarà dichiarato concluso. La loro fine viene
indicata dall’istruzione Next che può avere due forme:
senza ulteriori indicazioni, per cui il Visual Basic la considera complementare alla prima
istruzione For, che individua ripercorrendo la routine verso l’alto, e controlla che non abbia
già una propria corrispondente Next;
con la ripetizione della variabile di controllo, per cui Visual Basic controlla la prima
istruzione For, che individua ripercorrendo la routine verso l’alto, e verifica che non abbia già
una propria corrispondente Next che utilizzi la stessa variabile. Questa è la forma più
utilizzata, in quanto il compilatore è in grado di individuare errori e segnalarli al
programmatore.
Per esempio, la seguente routine visualizza un messaggio tre volte:
Sub EsempioForNext1()
Dim x As Integer
For x = 1 To 3
MsgBox “Ciclo in esecuzione”
Next x
End Sub

L’aspetto più interessante è però il fatto che la variabile di controllo del ciclo può essere
utilizzata al suo interno; la seguente routine mostra, come la precedente, un messaggio sul monitor,
ma aggiunge anche il numero ottenuto da tale variabile:
Sub EsempioForNext4()
Dim x As Long

For x = 1 To 1048576 ‘ 65536 se il foglio è in modalità


compatibilita
Sheets(1).Cells(x, 1) = Now
Next
End Sub

La variabile di controllo può essere utilizzata per inserire un determinato valore all’interno di
una matrice, per esempio lo 0:
Sub EsempioForNext3()
Dim x As Integer
Dim Valore(30) As Integer

For x = 1 To 30
Valore(x) = 0
Next x
End Sub

La variabile di controllo, inoltre, è spesso utilizzata come indice per accedere alle singole celle
di un foglio di lavoro. La seguente routine inserisce la data e l’ora corrente all’interno di tutte le
celle della seconda colonna del foglio di lavoro attivo, impiegando alcune decine di secondi
(Figura 8.5):

Figura 8.5 Il primo foglio di lavoro dopo l’esecuzione di EsempioForNext4().

Sub EsempioForNext4()
Dim x As Long

For x = 1 To 65536
Sheets(1).Cells(x, 2) = Now
Next x
End Sub

Il limite inferiore del ciclo non deve necessariamente essere impostato a 1: qualunque valore è
possibile, l’importante è rispettare la congruenza tra il valore massimo supportato dal tipo della
variabile di controllo e i limiti del ciclo stesso.
In altre parole, non è possibile eseguire un ciclo che inizi o superi il valore 40.000, se la
variabile è di tipo Integer e accetta solo valori inclusi tra –32.768 e +32.767. In caso contrario si
verifica un errore.
NOTA Se il ciclo deve lavorare su una matrice, è possibile utilizzare le funzioni LBound() e UBound() per indicare i
valori iniziale e finale del ciclo nei casi in cui la sua dimensione non sia nota a priori: per esempio nel caso delle
matrici dimensionate con le istruzioni Dim e Redim in modo variabile di esecuzione in esecuzione.

Un esempio di ciclo For/Next inserito in altri cicli For/Next è la seguente routine, che verifica le
celle nell’area composta dalle prime 4 colonne e 20 righe analizzandone il valore e ricercando
quelle il cui valore sia uguale a zero, con lo scopo di mostrare le coordinate all’utente:
Sub EsempioForNext5()
Dim Riga As Long
Dim Colonna As Long
Dim V As Variant

For Colonna = 1 To 4
For Riga = 1 To 20
V = Sheets(“Foglio2”).Cells(Riga, Colonna).Value
If Not IsEmpty(V) Then
If V = 0 Then
Sheets(“Foglio2”).Cells(Riga, Colonna).
Select
Sheets(“Foglio2”).Cells(Riga, Colonna).
Value = “ZERO”
MsgBox “Coordinate: “ & Riga & “,” &
Colonna & “, sostituito valore =” & V & “
con ZERO”
End If
End If
Next Riga
Next Colonna
End Sub

For…Step/Next
Il ciclo For…Step/Next non è altro che l’estensione del precedente, al quale viene aggiunta la
clausola Step per indicare un incremento o un decremento diverso da quello di default: +1. Step è
utile per eseguire:
cicli il cui limite iniziale è maggiore di quello terminale, impostando Step con un valore
negativo;
cicli in cui l’incremento della variabile sia definito da uno specifico valore come 2, 3, 5
oppure decimale: 1,2, e 3,77 (Figura 8.6).

Figura 8.6 Il foglio di lavoro attivo dopo l’esecuzione di EsempioForStepNext1.

Sub EsempioForStepNext1()
Dim x As Long

For x = 1 To 30 Step 2
Sheets(1).Cells(x, 1).Value = “esempio”
Next
End Sub

For Each/Next
Visual Basic dispone di un’istruzione per definire un ciclo operante su un insieme di oggetti,
evitando al programmatore di impostare il limite di partenza e quello di arrivo, in quanto
automaticamente gestiti. Si tratta di For Each/Next che richiede:
la parola chiave For Each;
il nome di una variabile di tipo Variant;
la parola chiave In;
il nome dell’insieme per il quale ogni singolo elemento sarà oggetto di un’elaborazione del
ciclo.
Il seguente esempio dichiara una matrice di tipo stringa composta da tre elementi ai quali
assegna un valore. Il ciclo viene eseguito sulla matrice allo scopo di concatenare il valore di ogni
singolo elemento nella variabile Str (Figura 8.7):
Sub EsempioForEach1()
Dim Mtx(3) As String
Dim Str As String
Dim x As Variant

Mtx(1) = “ABC”
Mtx(2) = “DEF”
Mtx(3) = “GHI”

For Each x In Mtx


Str = Str & x
Next x

MsgBox Str
End Sub

Figura 8.7 La finestra aperta da EsempioForEach1.

Per utilizzare il ciclo For Each/Next con le matrici è indispensabile tenere a mente come è
impostata l’Option Base.
Un ottimo esempio pratico è costituito dalla seguente routine che visualizza la media dei valori
contenuti nella matrice Valori (Figura 8.8 e Figura 8.9):
Sub EsempioForEach2()
Dim Valori(3) As Long
Dim Totale As Long
Dim Num As Integer
Dim x As Variant

Valori(1) = 10
Valori(2) = 20
Valori(3) = 30

For Each x In Valori


Num = Num + 1
Totale = Totale + x
Nextx

MsgBox “la media e’ :” & Totale / Num


End Sub

Essa può portare a due risultati totalmente differenti, ma esatti:


15, se non è stata impostata l’istruzione Option Base 1;
20, se è stata impostata l’istruzione Option Base 1.

Infatti, senza agire su tale impostazione del linguaggio, la matrice risulterà composta anche
dall’elemento Valori(0) che, pur avendo un valore uguale a zero, fa sì che la somma di tutti gli
elementi che corrisponde a 60 sia divisa per 4 anziché per 3, come apparentemente è lecito
attendersi.

Figura 8.8 La finestra aperta da EsempioForEach2, se Option Base è stata impostata con il valore zero.

Figura 8.9 La finestra aperta da EsempioForEach2, se Option Base è stata impostata con il valore uno.

NOTA Il ciclo For Each/Next non può essere utilizzato direttamente con i tipi di dati definiti dal programmatore,
perché il compilatore non saprebbe quale valore assegnare alla variabile di controllo tra quelli delle variabili
membro.

L’istruzione For Each/Next può essere utilizzata con successo sugli insiemi di oggetti che Excel
gestisce. Il seguente esempio mostra come creare una funzione che può essere richiamata
all’interno di una cella come una qualunque funzione di Excel quale SOMMA().
Oltre all’impiego dell’istruzione For Each/Next, essa è utile anche per vedere come si può gestire
un parametro del tipo A1:A20.
Function Sommatoria(r As Range) As Double
Dim SingolaCella As Object
For Each SingolaCella In r
Sommatoria = Sommatoria + SingolaCella.Value
Next SingolaCella
End Function

Do While/Loop
Il ciclo Do While/Loop viene utilizzato per indicare un blocco di istruzioni la cui esecuzione inizia
ed è ripetuta fino a quando la condizione indicata nell’istruzione Do While è vera.
Questo tipo di istruzioni viene utilizzato per eseguire un ciclo:
per un numero di volte non predefinibile che può anche essere zero;
quando la condizione di uscita è il risultato di un’azione che non può essere riassunta in
un’espressione, ma è il frutto dell’elaborazione stessa del ciclo; in questi casi si opta per
un’espressione composta da una sola variabile il cui valore segnala all’istruzione Do While se
il ciclo deve essere ripetuto o interrotto.
Nel seguente esempio, il ciclo viene ripetuto fino a quando l’utente non immette un valore
numerico nella finestra:
Sub EsempioWhileWend1()
Dim str As String

Do While Not IsNumeric(str)


Str = InputBox(“digita un numero”)
Loop
End Sub

L’equivalente esempio che utilizza una variabile per definire se il loop deve terminare è il
seguente:
Sub EsempioWhileWend2()
Dim str As String
Dim f As Boolean

f = True
Do While f
str = InputBox(“digita un numero”)
If IsNumeric(str) Then
F = False
End If
Loop
End Sub

NOTA All’inizio della propria esperienza di programmatore, la creazione delle condizioni del loop appaiono
complesse. Si può ricorrere a un piccolo trucco, ovvero utilizzare un ciclo con la condizione sempre vera, come ad
esempio Do While true e inserire all’interno del ciclo una o più istruzioni if che ne gestiscono l’interruzione (come
spiegato nel relativo capitoletto sull’uscita anticipata). Unica attenzione di ricordarsi di inserire questa if, altrimenti il
ciclo diventa infinito.
È da segnalare che esiste anche la forma While/Wend. Essa proviene dai linguaggi Basic degli anni
’80, ma è sempre meno utilizzata.
Con essa è possibile determinare se il blocco delle istruzioni deve essere eseguito o meno in
relazione al test che viene valutato prima di iniziare a elaborarle. Do/While/Loop e Do Until/Loop
introducono un’istruzione (Exit Do) che consente l’uscita dal ciclo in cui è contenuta, senza
ricorrere all’istruzione GoTo considerata in modo negativo per quanto ne riguarda l’utilizzo. I cicli
Do/Loop While e Do Loop/Until elaborano almeno una volta il blocco delle istruzioni che contengono.

La prosecuzione nella ripetizione del ciclo è invece sancita dal risultato del test. Nella Tabella
8.2 sono messi a confronto i comportamenti dei vari tipi di loop per evidenziare quali prevedono
che le istruzioni del ciclo siano sempre eseguite almeno una volta, indipendentemente dall’esito
del test.
Tabella 8.2 Il test della condizione di un ciclo a volte avviene dopo l’esecuzione delle istruzioni
Le istruzioni del ciclo vengono eseguite con esito
Tipo di ciclo
del primo test dei successivi test
True False True False
While/Wend Sì No Sì No
Do/Loop While Sì Sì Sì No
Do Loop/Until Sì Sì No Sì
Do While/Loop Sì No Sì No
Do Until/Loop No Sì No Sì
For/Next Sì No Sì No

NOTA L’indicazione relativa al ciclo For/Next è da interpretare come la situazione in cui il valore del limite di arrivo è
già stato superato, per esempio con l’istruzione For x = 3 to 1.

Do/Loop While
Il ciclo Do/Loop While consente di definire un insieme di istruzioni che verranno ripetute fino a
quando risulta vera la condizione che appare dopo la parola chiave While. Il seguente esempio
ripropone il ciclo presentato per While/Wend, al fine di comprendere le differenze d’impiego dei due
sistemi:
Sub EsempioDoLoopWhile1()
Dim str As String
Do

str = InputBox(“digita un numero”)


Loop While Not IsNumeric(str)
End Sub

Do/Loop Until
Il ciclo Do/Loop Until consente di definire un insieme di istruzioni che saranno ripetute fino a
quando risulti vera la condizione che appare dopo la parola chiave Until. Il seguente esempio
ripropone ancora quello precedente opportunamente modificato:
Sub EsempioDoLoopUntil1()
Dim str As String
Do
str = InputBox(“digita un numero”)
Loop Until IsNumeric(str)
End Sub

Come si può vedere, la routine è identica tranne che per l’istruzione Loop Until, nella quale la
condizione non contiene più l’operatore Not.

GoTo
Le situazioni in cui si rende necessario l’impiego dell’istruzione GoTo sono molto rare, comunque
è utile conoscerla poiché la sua sintassi è veramente semplice, mentre il compito a cui assolve
consiste nel permettere al programmatore di spostare l’esecuzione del programma dal punto in cui
essa viene inserita a una linea individuata da un’etichetta o label.
Nel seguente esempio, la riga con la prima funzione MsgBox non verrà mai eseguita, poiché
l’istruzione GoTo fa in modo che il programma prosegua l’elaborazione con la riga successiva alla
label:
Sub EsempioGoto1()
GoTo SaltaAQuestaPosizione
MsgBox “Questa riga non verra’ mai elaborata”
SaltaAQuestaPosizione:
MsgBox “EsempioGoto1”
End Sub

L’istruzione GoTo vuole il nome della label dalla quale proseguire l’elaborazione: essa va
posizionata alla colonna 1, deve iniziare con una lettera e terminare con il carattere due punti. I
caratteri ammessi sono gli stessi utilizzabili per definire il nome di una funzione.
Per farsi un’idea della struttura che poteva avere un programma scritto con le vecchie versioni
del Basic, si può osservare il listato EsempioGoto2, che è utile soprattutto come autoverifica, per
vedere se si riesce a seguire la logica dei salti. La sequenza delle finestre che aprono la routine è
mostrata nella Figura 8.10.
Sub EsempioGoto2()
MsgBox “Passo 1”
GoTo Pos2
Pos3:
MsgBox “Passo 3”
GoTo Pos4
Pos2:
MsgBox “Passo 2”
GoTo Pos3
Pos4:
MsgBox “Passo 4”
End Sub

L’unica limitazione che l’istruzione GoTo presenta risiede nel fatto che non è possibile saltare
all’esterno della routine o funzione in cui essa è contenuta. Il seguente esempio genererà un errore:
Sub EsempioGotoErratoA()
GoTo Punto
End Sub

Sub EsempioGotoErratoB()
Punto:
End Sub

Figura 8.10 Sequenza delle finestre che aprono la routine EsempioGoto2.

Uscire anticipatamente da Function, Sub o cicli


Come già spiegato, il termine dell’esecuzione di un ciclo è determinato dal risultato di un test
riesaminato ogni volta che il ciclo inizia o ha completato un giro; talvolta si rende però necessario
interromperlo anticipatamente. In questi casi, si usano istruzioni apposite oppure il GoTo.
Queste istruzioni sono:
Per le Sub: Exit Sub
Per le Function: Exit Function

Uscita forzata dai cicli While/Wend


Il ciclo While/Wend non dispone di istruzioni specifiche per la propria interruzione, quindi si deve
ricorrere all’istruzione GoTo come nel seguente esempio, in cui è definito un ciclo infinito poiché la
condizione restituisce sempre il valore 1, quindi True:
Sub EsempioWhileInterrotto1()
Dim t1 As Date

t1 = Now
While 1
If (Now - t1 > 1 / 24 / 60 / 60) Then
GoTo PuntoUscita
End If
Wend
PuntoUscita:
MsgBox “Ciclo terminato”
End Sub

In alternativa, si può utilizzare una variabile che viene impostata con il valore True, prima che il
ciclo abbia inizio, e al suo interno viene impostata a False, quando è giunto il momento di uscire da
essa:
Sub EsempioWhileInterrotto2()
Dim t1 As Date
Dim Continuare As Boolean

t1 = Now
Continuare = True
While Continuare
If (Now - t1 > 1 / 24 / 60 / 60 Then
Continuare = False
End If
Wend
PuntoUscita:
MsgBox “Ciclo terminato”
End Sub

Uscita forzata dai cicli For/Next


Per il ciclo For/Next esiste un’istruzione apposita che lo interrompe, facendo sì che la successiva
istruzione da eseguire sia quella collocata dopo Next. La seguente routine imposta un ciclo da 1 a
2.000.000.000 e quando il valore della variabile di controllo supera il valore 32.000 viene
interrotta dall’istruzione Exit For, dopo aver visualizzato un messaggio:
Sub EsempioExitFor()
Dim a As Long
For a = 1 To 2000000000
If a > 32000 Then
MsgBox “Si rischia che ci metta troppo!”
Exit For
End If
Next a
End Sub

Uscita forzata dai cicli Do/Loop


Il ciclo Do/Loop Until può essere interrotto mediante un’apposita istruzione: Exit . Di seguito è
Do

mostrato un esempio di utilizzo:


Sub EsempioExitDo()
Dim a As Long

Do
a = a + 1
If a > 32000 Then
MsgBox “Si rischia che ci metta troppo!”
Exit Do
End If
Loop While 1
End Sub
Capitolo 9

Insiemi di oggetti

Il concetto di oggetto ha più di quindici anni ed è quindi relativamente vecchio rispetto ai tempi
dell’informatica; infatti ha cominciato a essere discusso verso la metà degli anni ‘80.
L’idea sostanziale del tipo di programmazione e dei compilatori che si fondano su tale tecnica si
basa sull’interazione del programma verso componenti software dotati di proprie caratteristiche. Il
programma richiede a essi di svolgere una determinata azione che deve ricadere tra gli obiettivi
dell’oggetto.
Un altro dettaglio molto importante è dato dal fatto che un oggetto può essere composto da altri
oggetti, ereditandone le caratteristiche e le funzionalità più altre routine o funzioni che li
coordinano, ampliando così le possibilità dell’oggetto finale che si deve ottenere.

Proprietà, metodi, eventi ed ereditarietà: concetti


Si può iniziare pensando a un ipotetico oggetto di nome Finestra vuota il cui scopo sia il seguente
(Figura 9.1):
visualizzare un riquadro il cui colore di default sia il grigio, sovrastato da un rettangolo
orizzontale blu al cui interno può essere inserito un testo;
rendere disponibile in alto a sinistra un pulsante per la sua chiusura;
gestire il proprio ridimensionamento e spostamento sullo schermo in base alle operazioni
eseguite dall’utente sul suo bordo.
Tale oggetto può essere utilizzato come base per altri due oggetti:
;
Finestra di visualizzazione

Finestra di input.
Figura 9.1 Esempio di come sarebbe un oggetto base, che permette di ricavarne altri.

L’oggetto Finestra di visualizzazione sarà arricchito con gli oggetti che seguono (Figura 9.2):
un’area in cui inserire il testo;
un oggetto del tipo Casella di testo all’interno del quale l’utente può inserire alcuni valori;
una gamma di pulsanti che saranno visualizzati nella parte inferiore della finestra in base alle
impostazioni che di volta in volta riceverà;
un sistema per comunicare quale pulsante è stato utilizzato dall’utente per chiuderlo.

Figura 9.2 Esempio dell’aspetto dell’oggetto Finestra di visualizzazione.

Al contrario, l’oggetto Finestra di input sarà arricchito con gli elementi che seguono (Figura
9.3):
un’area in cui inserire il testo;
un oggetto del tipo Casella di testo in cui l’utente può inserire valori;
due pulsanti per consentire all’utente di confermare o annullare;
un sistema per comunicare il contenuto della casella di testo.

Figura 9.3 Esempio di come apparirebbe l’oggetto Finestra di input.

A loro volta, questi oggetti potrebbero essere presi come base per altri, per esempio si potrebbe
creare un oggetto di nome Finestra di visualizzazione con icona basato sull’oggetto Finestra di
visualizzazione, al quale venga aggiunta la possibilità di selezionare un’icona che appaia nella
parte sinistra della finestra. Quest’ultima può servire per rafforzare visivamente il tipo
d’informazione che essa fornisce, di volta in volta, all’utente. Questa possibilità, garantita dai
compilatori per la programmazione a oggetti, si chiama ereditarietà.
Il testo che visualizzano le finestre, sia nel titolo sia al loro interno, deve necessariamente poter
essere impostato a seconda delle necessità del programma. Esso viene memorizzato in una
variabile di nome Caption la quale, appartenendo a un oggetto ed essendo accessibile dall’esterno
dell’oggetto stesso, non viene chiamata variabile bensì proprietà. Le proprietà possono essere di
due tipi:
normale (il valore può essere acquisito o impostato);
di sola lettura (il valore può essere solo acquisito, ma non impostato).
Le eventuali funzioni che fanno parte dell’oggetto e possono essere richiamate dall’esterno di
esso vengono denominate metodi.
Alle proprietà e ai metodi di un oggetto si aggiungono gli eventi. Con questo termine si indica un
accadimento, o evento, che l’oggetto è in grado di gestire, eseguendo una specifica routine che il
programmatore ha creato per tali situazioni, assegnando a essa un nome composto dagli elementi
seguenti:
nome dell’oggetto;
carattere underscore;
nome dell’evento.
Gli esempi di nomi di routine che seguono sono relativi ad alcuni eventi per una finestra di
nome UserForm:
UserForm_Activate
UserForm_DblClick
UserForm_KeyPress
UserForm_MouseDown

Il Visual Basic utilizza il carattere punto per indicare l’appartenenza di una proprietà o di un
metodo a un oggetto. Per esempio, la seguente istruzione permette al programma di indicare il
valore della proprietà .Caption per l’oggetto CommandButton1:
CommandButton1.Caption = “Testo sul pulsante”

L’unico problema del programmatore consiste, quindi, nell’individuare il nome della proprietà
che gli può essere utile: gli è d’aiuto la finestra Proprietà che le elenca tutte (si ricorda che essa si
apre selezionando Visualizza/Finestra Proprietà).
NOTA Per evidenziare che si tratta di metodi o proprietà, saranno riportati con il nome preceduto dal punto. È
tuttavia importante sapere che quelli appartenenti all’oggetto Application possono apparire nel programma senza
l’indicazione di tale oggetto e senza il carattere punto.

Oggetti contenuti in altri oggetti


Se l’ereditarietà è un utile strumento per il programmatore che abbia già acquisito una discreta
scioltezza con il Visual Basic, la possibilità di inserire oggetti all’interno di altri oggetti è molto
più semplice e immediata. In particolare, Excel fa un largo utilizzo di questo sistema.
Per esempio, una cartella di Excel è composta da uno o più fogli di lavoro, quindi, ricorrendo al
punto di vista del programmatore e alla sua terminologia specialistica, si dovrebbe dire che
l’oggetto Cartella contiene al suo interno più oggetti Fogli di lavoro. Ne consegue che la cartella e i
fogli dovrebbero avere una serie di proprietà e metodi. Per esempio, entrambi i tipi di oggetto
dispongono della proprietà .Name, ma ciascuno di essi agisce solo a livello dell’oggetto indicato,
che trovate a sinistra del punto rispetto alla proprietà.
La routine VisualizzaNomeFogliDellaCartellaCorrente si avvale del ciclo For Each/Next per
provvedere a elencare in una stringa i nomi di tutti i fogli di lavoro contenuti nella cartella attiva, i
quali vengono acquisiti ricorrendo alla proprietà .Name di ciascun foglio, nonché alla stessa
proprietà applicata alla cartella attiva. Vale a dire:
all’oggetto ActiveWorkbook;
all’oggetto Worksheets, contenuto nell’oggetto Active-Workbook:
Sub VisualizzaNomeFogliDellaCartellaCorrente()
Dim Sht
Dim ElencoFoglio As String
Dim NomeFoglio As String

ElencoFoglio = “La cartella attiva si chiama “ _


& ActiveWorkbook.Name & _
“ed essa contiene i seguenti fogli:”
For Each Sht In ActiveWorkbook.Worksheets
NomeFoglio = Sht.Name
ElencoFoglio = ElencoFoglio & vbCr & NomeFoglio
Next Sht
MsgBox ElencoFoglio
End Sub

Gli oggetti di Excel


Ora che sono stati illustrati alcuni concetti quali metodi e proprietà, è possibile spostare
l’attenzione specificatamente sugli oggetti di Excel, per cominciare ad analizzarli e comprenderne
il significato e le possibilità d’utilizzo; infatti, VBA va considerato come uno strumento che
consente di descrivere le azioni che ogni oggetto deve eseguire per raggiungere un determinato
risultato.

Application
Application è un oggetto particolare, in quanto potrebbe essere paragonato all’Excel stesso e
contiene al suo interno altri oggetti fondamentali quali le cartelle, che a loro volta contengono i
fogli di lavoro. Esso fornisce al programmatore un numero considerevole di proprietà, metodi ed
eventi. Quelli più importanti sono elencati di seguito.
: insieme di tutte le cartelle aperte, compresa la cartella Personal.xls.
Workbooks

AddIns: insieme di tutti gli AddIn installati sul computer, indipendentemente dal fatto che
siano stati caricati o meno.

NOTA Gli AddIn sono cartelle con estensione .XLA che mettono a disposizione funzionalità aggiuntive e vengono
rese disponibili quando l’AddIn è caricato mediante il percorso Strumenti/Componenti aggiuntivi; per esempio,
Eurotool.xlaè un AddIn che contiene le funzioni per le conversioni delle valute.

Debug : mette a disposizione del programmatore il metodo .Print, che consente di stampare
qualcosa all’interno della finestra Immediata di Visual Basic Editor, e il metodo .Assert, per
definire una condizione che, se non risulta vera, permette di arrestare l’esecuzione del
programma.
Dialogs: insieme contenente tutte le finestre di dialogo di Excel. Esso viene richiamato

mediante il metodo .Item() che necessita di un numero per il tipo di finestra richiesta e può
essere sostituito dall’equivalente costante.
CommandBars: insieme di tutte le barre degli strumenti e dei menu di Excel.

Names: insieme di tutti i nomi che sono stati creati all’interno di una cartella con il comando

Inserisci/Nome/Definisci… di Excel, allo scopo di contrassegnare una cella o un intervallo.


Windows: simile al menu Finestra di Excel, consente di selezionare le varie finestre o di

disporle ricorrendo al metodo .Arrange.


WorksheetFunction: fornisce al Visual Basic un mezzo per utilizzare, all’interno di un’istruzione,

una delle funzioni disponibili sul foglio di lavoro, per esempio SOMMA().
RecentFiles: insieme di oggetti contenenti il nome delle cartelle aperte di recente che sono

accessibili attraverso la proprietà .Item.


FileSearch: insieme di oggetti contenenti il nome dei file che corrispondono a determinati

criteri di ricerca.
VBE: fornisce uno strumento per acquisire informazioni, attraverso diverse proprietà, relative a

Visual Basic Editor per Excel, in uso.

NOTA È possibile utilizzare le proprietà e i metodi di Application ricorrendo al riferimento implicito, che consente di
scrivere molto velocemente istruzioni più compatte: eliminando l’oggetto e il carattere punto, Visual Basic tenterà di
individuare l’oggetto che dispone di tale proprietà o metodo attraverso alcune regole di ricerca.

.Path, .Name e .FullName


Queste proprietà restituiscono informazioni relative al file in cui è contenuta la cartella, più
precisamente:
.Path restituisce il percorso del file della cartella di lavoro di Excel, senza il nome di
quest’ultimo;
.Name restituisce il nome del file che contiene la cartella di lavoro di Excel, senza il
percorso;
.FullName opera come combinazione delle due precedenti proprietà, restituendo una stringa
con il percorso del file della cartella di lavoro di Excel e il nome indicato di seguito.
Sub EsempioPossibilitaNomeFile()
MsgBox “Esempi di proprietà relative al nome della _
cartella” _
& vbCr & “.Name: “ & ActiveWorkbook.Name_
& vbCr & “.Path: “ & ActiveWorkbook.Path_
& vbCr & “.FullName: “ & ActiveWorkbook.FullName
End Sub

.SheetsInNewWorkbook
La proprietà .SheetsInNewWorkbook consente di conoscere il numero di fogli che conterrà ogni
nuova cartella, in base a quanto è stato impostato dall’utente nella casella Fogli nella nuova
cartella, contenuta nella scheda Generale della finestra Opzioni di Excel. Essa permette altresì di
impostare tale valore. Il seguente esempio verifica che ogni nuova cartella contenga almeno cinque
fogli di lavoro:
If Application.SheetsInNewWorkbook < 5 Then
Application.SheetsInNewWorkbook = 5
End If

FileSearch
L’oggetto .FileSearch consente di creare una matrice contenente tutti i file il cui nome
corrisponde a un criterio di ricerca, specificato attraverso le proprietà elencate di seguito.
.LookIn: accetta una stringa con il percorso in cui fare la ricerca.
.FileName: consente di indicare il criterio o il nome del file da ricercare. Si accettano le
combinazioni di caratteri quali ? e *, analogamente a quanto si utilizzava nel comando Dir del
Dos.
.FileType: costituisce un’alternativa a .FileName e permette di indicare il tipo di file che
deve essere ricercato attraverso alcune costanti che sono in grado di gestire tutte le relative
estensioni.
.SearchSubFolders: viene indicato, attraverso il valore booleano True o False, se la ricerca
dovrà avvenire solo nella cartella indicata in .LookIn o essere estesa alle eventuali cartelle
che essa contiene.
.Execute: avvia la ricerca in base a quanto specificato attraverso le precedenti proprietà.
Genera una matrice di nomi di file, completi del percorso, contenuta nella proprietà
.FoundFiles.Item, mentre la proprietà .FoundFiles.Count permette di conoscerne il numero.
L’esempio seguente effettua una ricerca nella cartella “c:\Archivi”, e nelle eventuali
sottocartelle, di tutti i file con estensione .XLS, per visualizzarne il nome in gruppi di quindici
mediante la MsgBox:
Sub RicercaTuttiIFileExcel()
Dim f As Long
Dim str As String
Dim Pagina As Long
Application.FileSearch.LookIn = “C:\Archivi\”
Application.FileSearch.Filename = “*.xls”
Application.FileSearch.FileType = _
msoFileTypeExcelWorkbooks
Application.FileSearch.SearchSubFolders = True

Application.FileSearch.Execute

For f = 1 To Application.FileSearch.FoundFiles.Count
str = str & Application.FileSearch.FoundFiles(f) & _
vbCr
If (f Mod 15 = 0) Then
Pagina = Pagina + 1
MsgBox str, , “Pagina numero “ & Pagina
str = Empty
End If
Next f
MsgBox str
End Sub

.GetOpenFilename
Il metodo .GetOpenFilename rappresenta un interessante sistema per i programmatori che
desiderano gestire il dialogo con l’utente, per la selezione dei file da aprire, avvalendosi della
finestra Apri di Windows, ma evitando che venga aperto automaticamente e rimandando tale
operazione a un momento successivo:
Sub FinestraDialogoApriConAperturaGestitaDalVBA()
Dim Nome As String

Nome = Application.GetOpenFilename
If Len(Nome) > 0 And Nome <> “Falso” Then
MsgBox “Il programma aprirà” & Nome
Application.Workbooks.Open (Nome)
End If
End Sub

In alternativa a esso, si può utilizzare il metodo Application. Dialogs(xlDialogOpen).Show.


NOTA Il terzo parametro di Application.GetOpenFilename si chiama Title e permette di assegnare il nome alla
finestra, in base alle esigenze del programma.

.Evaluate
Il metodo .Evaluate consente di ottenere il valore contenuto nella cella con il nome indicato
come parametro. La Figura 9.4 mostra un esempio. La seguente istruzione visualizza il valore della
cella alla quale è stato assegnato il nome CostoLitroBenzina attraverso il percorso Formule/Definisci
nome:
MsgBox Application.Evaluate(“CostoLitroBenzina”)
Figura 9.4 Esempio di applicazione del metodo Evaluate per visualizzare il valore di una cella.

Windows
L’insieme di oggetti Windows contiene vari oggetti di tipo Window e consente di utilizzare le
funzioni disponibili nel menu Windows di Excel, attraverso alcuni metodi e proprietà. Alcuni
esempi si trovano nell’elenco riportato di seguito:
Attivare la finestra contenente la cartella Cartel1:
Application.Windows(“Cartel1.xls”).Activate

Rendere visibile a tutto schermo la prima finestra riportata nell’elenco delle finestre aperte,
la quale coincide con la cartella correntemente attiva:
Windows.Item(1).WindowState = xlMaximized

Creare una nuova finestra che visualizza una cartella già aperta e ottenere il numero che la
identifica come non univoca per quella cartella:
ActiveWindow.NewWindow
win = ActiveWindow.WindowNumber

Workbooks
L’oggetto Workbooks è contenuto nell’oggetto Application e rappresenta l’insieme delle cartelle di
Excel correntemente aperte (Figura 9.5). Gli oggetti più interessanti che contiene sono i seguenti:
Worksheets , l’insieme dei fogli di lavoro appartenenti alla cartella;
BuiltinDocumentProperties, insieme dei valori inseriti o visibili nella finestra Proprietà di Excel;

Charts, l’insieme dei grafici contenuti nella cartella;

VBProject, l’insieme dei programmi che la cartella contiene.

Senza dubbio l’oggetto più utilizzato e importante è il primo.


Figura 9.5 Gli oggetti dell’insieme.

.Item()
Ogni foglio di lavoro contenuto nella cartella è accessibile attraverso la proprietà .Item() che
richiede un indice per selezionare quello desiderato. L’istruzione seguente visualizza il nome del
primo foglio di lavoro contenuto nella prima cartella:
MsgBox Workbooks.Item(1).Worksheets.Item(1).Name

Cartella corrente
La cartella corrente viene individuata attraverso la proprietà .Active Workbook di Application che
restituisce un oggetto di tipo Workbook:
Sub EsempioActiveWorkbook()
Dim n As Long

n = ActiveWorkbook.Sheets.Count
MsgBox “La cartella attiva e’ composta da “ & n & “ _
fogli”
End Sub

Debug
Il metodo Debug è utile durante le fasi di sviluppo e verifica dei programmi, in quanto permette di
inserire righe che, quando vengono eseguite, possono inviare un messaggio nella finestra
Immediata di Visual Basic Editor. Il programmatore può servirsene per vari scopi: verificare se
l’esecuzione del programma è transitata per un determinato punto oppure conoscere il valore di
una variabile in un determinato momento. In tali casi si utilizza il suo metodo .Print.
La routine EsempioDebugPrint esegue un ciclo su tutti i fogli di tutte le cartelle e, quando trova la
cella A1 che contiene qualcosa, provvede a segnalarlo al programmatore (Figura 9.6).
L’oggetto Debug dispone di un altro metodo che all’apparenza può sembrare strano o pericoloso,
mentre ha una propria utilità. Si tratta di .Assert, il cui compito consiste nelle operazioni seguenti:

arrestare temporaneamente l’esecuzione del programma nel caso in cui una condizione risulti
False;

aprire la finestra di Visual Basic Editor;


evidenziare in giallo la riga che ha causato l’interruzione.

Figura 9.6 Eseguendo EsempioDebugPrint, nella finestra Immediata di Visual Basic Editor appare il nome del foglio che
contiene un valore in A1 seguito dal valore stesso.

In questo modo il programmatore può applicare le operazioni che ritiene più opportune. La
routine EsempioDebugAssert analizza tutti i fogli di lavoro e interrompe l’esecuzione nel caso ne
trovi uno in cui la cella A1 contenga il valore “Questo e’ il valore della cella A1”:
Sub EsempioDebugAssert()
Dim wb As Variant
Dim ws As Variant

For Each wb In Workbooks


For Each ws In wb.Worksheets
Debug.Assert Not ws.Cells(1, 1).Value= _
“Questo e’ il valore della cella A1”
Next ws
Next wb
End Sub

Ora il programmatore potrebbe avvalersi della finestra Immediata per verificare il valore delle
proprietà degli oggetti ws e wb, o altri valori che ritiene importanti, per comprendere lo stato del
programma e i motivi che hanno condotto alla situazione corrente.
Dialogs
L’oggetto Dialogs contiene tutte le finestre di dialogo disponibili in Excel che possono essere
utilizzate dal programmatore, evitando di dover costruire propri UserForm che svolgono lo stesso
lavoro di quelli standard come, per esempio, la finestra Apri oppure Salva con nome.
Ogni finestra è contenuta in un apposito oggetto di tipo Dialog, al quale si accede mediante la
proprietà .Item() che richiede un indice che identifica la finestra richiesta. Le finestre sono oltre
duecento e molte non vengono utilizzate dalla maggior parte dei programmatori; di seguito viene
fornita una routine che permette di visualizzarle tutte in sequenza:
Sub EsempioDialogs()
Dim dlg As Variant
Dim r As Integer

Worksheets(1).Activate
For dlg = 1 To Application.Dialogs.Count
r = r + 1
Cells(r, 1) = Application.Dialogs.Item(dlg).Show
Next dlg
End Sub

NOTA L’indice può essere inserito ricorrendo alle costanti messe a disposizione da Visual Basic Editor per le
finestre di dialogo; in linea di principio il loro nome è composto dal prefisso xlDialog seguito dal nome inglese della
finestra: per esempio, la costante della finestra Apri si chiama xlDialogOpen.

CommandBars
L’insieme CommandBars è utilissimo per i programmatori che vogliono creare nuove barre
degli strumenti oppure inserire, in quelle esistenti, nuovi oggetti quali pulsanti, liste, caselle di
testo ecc.
Nell’esempio della routine EsempioCommandBars2 viene illustrato come visualizzare le barre
di comando Pattern, Chart, WordArt e Web:
Sub EsempioCommandBars2()
Application.CommandBars.Item(“Pattern”).Visible = True
Application.CommandBars.Item(“Chart”).Visible = True
Application.CommandBars.Item(“WordArt”).Visible = True
Application.CommandBars.Item(“Web”).Visible = True
End Sub

Windows
L’insieme Windows contiene tanti oggetti quante sono le finestre correnti aperte in Excel, più
vari metodi per selezionarle o sistemarle analogamente alle funzionalità messe a disposizione dal
menu Finestra. La routine EsempioWindows1 esegue un ciclo per un numero di volte pari al
numero di oggetti contenuti nell’insieme Windows, al fine di attivare ogni finestra e accodare il
suo titolo in una variabile di tipo String, il cui contenuto verrà visualizzato a esecuzione terminata:
Sub EsempioWindows1()
Dim w As Integer
Dim str As String
For w = 1 To Windows.Count
str = str & Windows.Item(w).Caption & vbCr
Windows.Item(w).Activate
Next w

MsgBox str, , “Lista delle finestre aperte”


End Sub

WorksheetFunction
L’insieme WorksheetFunction arricchisce le funzioni native di VBA rendendo disponibili quelle
di Excel. La seguente istruzione esemplifica come utilizzare la funzione .Power() di Excel
passandole come parametri i valori 8 e 2:
v = WorksheetFunction.Power(8, 2)

Scrivendo l’istruzione WorksheetFunction seguita da un punto, l’editor visualizza i nomi di tutte


le funzioni di Excel (Figura 9.7).

Worksheets
L’insieme Worksheets contiene tutti i fogli di una cartella di lavoro, più specificatamente la
cartella a cui esso appartiene; inoltre, a ogni foglio di lavoro corrisponde un oggetto di tipo
Worksheet.
Per accedere ai vari fogli si utilizza la proprietà .Item(). La subroutine che segue applica un
ciclo basato su tutte le cartelle aperte e contiene un altro ciclo basato su tutti i fogli della cartella
presa in esame dal ciclo esterno; lo scopo del ciclo è acquisire il nome di ogni foglio e riportarlo,
corredato dal nome della cartella a cui appartiene, nel primo foglio della cartella:
Sub EsempioLoopSuTuttiFogliDiTutteCartelle()
Dim nwb As Integer
Dim nws As Integer
Dim r As Integer
Dim wbNome As String
Dim wsNome As String

For nwb = 1 To Workbooks.Count


wbNome = Workbooks.Item(nwb).Name
For nws = 1 To Workbooks.Item(nwb).Worksheets.Count
wsNome = Workbooks.Item(nwb).Sheets(nws).Name
‘ memorizza le informazioni nel foglio
r = r + 1
Workbooks.Item(2).Sheets(1).Cells(r, 1) = wbNome
Workbooks.Item(2).Sheets(1).Cells(r, 2) = wsNome
Next nws
Next nwb
End Sub
Figura 9.7 Come viene visualizzato l’elenco delle funzioni disponibili per WorksheetFunction.

La subroutine è molto interessante perché illustra diversi aspetti importanti, quali i seguenti:
come accedere a tutte le cartelle che vengono individuate dalla proprietà .Item();
come acquisire il numero di cartelle aperte includendo quelle nascoste, quale Personal.xls;
come acquisire il numero di fogli di lavoro di cui dispone una determinata cartella.
L’istruzione seguente:
For nwb = 1 To Workbooks.Count

avvia un ciclo che verrà ripetuto tante volte quante sono le cartelle aperte, informazione resa
disponibile dalla proprietà .Count applicata all’oggetto Workbooks, mentre l’istruzione:
For nws = 1 To Workbooks.Item(nwb).Worksheets.Count

avvia un altro ciclo che sarà ripetuto tante volte quanti sono gli oggetti Worksheets contenuti
nella mesima cartella.
Applicando a tali oggetti la proprietà .Name, diventa possibile acquisire i nomi dei singoli
oggetti che potranno essere memorizzati all’interno del primo foglio, appartenente alla seconda
cartella aperta.
Più precisamente l’istruzione:
Workbooks.Item(2).Sheets(1).Cells(r, 1) = wbNome

memorizza, nella prima colonna e alla riga individuata dalla variabile r, il nome dell’oggetto
Workbook che è stato copiato nella variabile wbNome. Analogamente si comporta l’istruzione
seguente:
Workbooks.Item(2).Sheets(1).Cells(r, 2) = wsNome

che memorizza, nella seconda colonna, il nome del foglio analizzato.


La seguente routine costituisce un altro esempio di loop totalmente analogo al precedente nei
risultati e nella forma, ma che si differenzia sostanzialmente per il tipo di ciclo adottato e che
quindi si presta a essere un efficace strumento di apprendimento delle regole per costruire i cicli
For/Next e For Each/Next:
Sub EsempioLoopEachSuTuttiFogliDiTutteCartelle()
Dim wb As Variant
Dim ws As Variant
Dim r As Integer
Dim wbNome As String
Dim wsNome As String
For Each wb In Workbooks
wbNome = wb.Name
For Each ws In wb.Worksheets
wsNome = ws.Name
‘ memorizza le informazioni nel foglio
r = r + 1
Workbooks.Item(2).Sheets(1).Cells(r, 1) = wbNome
Workbooks.Item(2).Sheets(1).Cells(r, 2) = wsNome
Next ws
Next wb
End Sub

Come si può vedere, il codice risulta molto più compatto e, quando si avrà un poco di
confidenza con gli oggetti e gli insiemi di oggetti, anche molto più leggibile. Comunque seguono
alcune annotazioni per renderlo più chiaro.
Le variabili di controllo wb e ws del ciclo non sono più utilizzate come indici nelle proprietà
.Item() e il loro tipo è stato modificato in Variant in accordo con quanto richiesto dal ciclo For
Each/Next.
Il primo ciclo opera su tutti gli oggetti contenuti all’interno dell’oggetto Workbooks che è
implicitamente contenuto in Application.
Il secondo ciclo è particolarmente interessante e analizza tutti gli oggetti contenuti nell’insieme
Worksheets che appartiene al Workbook attualmente in analisi, identificato attraverso la variabile
di controllo del ciclo esterno.
L’impiego della proprietà .Name risulta molto più immediato.
Un altro sistema per accedere agli oggetti Workbooks e Worksheets, che può essere impiegato
praticamente su qualunque oggetto, si basa sull’impiego di variabili di tipo Object. La routine
seguente assegna alla variabile wb l’indirizzo del secondo elemento dell’insieme Workbooks e lo
utilizza per visualizzare il valore della sua proprietà .Name:
Sub EsempioVariabileObjectPerWorkbook()
Dim wb As Object

Set wb = Workbooks.Item(2)
MsgBox wb.Name
End Sub

Analogamente a quanto avviene nell’esempio precedente, la routine


EsempioVariabileObjectPerWorkSheets assegna alla variabile ws l’indirizzo del primo elemento
dell’insieme Worksheets appartenente al secondo elemento dell’insieme Workbooks, ovvero
l’indirizzo del primo foglio della seconda cartella aperta, visualizzandone il nome (Figura 9.8):
Sub EsempioVariabileObjectPerWorkSheets()
Dim ws As Object

Set ws = Workbooks.Item(2).Worksheets.Item(1)
MsgBox ws.Name
Figura 9.8 La macro visibile nella finestra elenca, all’interno del primo foglio della prima cartella, tutte le cartelle aperte e i
nomi dei fogli che esse contengono.

End Sub

NOTA Quando si utilizzano le variabili di tipo Object è indispensabile ricordarsi di ricorrere all’istruzione Set per
assegnare loro un valore, altrimenti Visual Basic Editor visualizzerà un messaggio di errore.

Font
L’oggetto Font ricorre praticamente in ogni oggetto che visualizzi il testo, come le celle del
foglio di lavoro e le finestre create dal programmatore, e dispone delle proprietà riportate nella
Tabella 9.1.
NOTA Quando si sta indicando che è necessario fare ricorso alla funzione RGB() per ottenere il codice colore,
significa che è necessario indicare il colore come risultato della combinazione di rosso, verde e blu, ciascuno
misurato su una scala da 0 a 255; i valori sono poi da convertire nel codice colore corrispondente, richiamando la
funzione RGB() e passandole i tre valori. Essa, in questo modo, restituisce un codice numerico di tipo Long
corrispondente alla combinazione di colori indicata.

Tabella 9.1 Le proprietà dell’oggetto Font


Proprietà Effetto Tipo dato Note
Imposta il colore di Si possono utilizzare le costanti: xlBackground,
Background sfondo sul quale Long xlBackgroundAutomatic, xlBackgroundOpaque,
apparirà il testo. xlBackgroundTransparent oppure la funzione RGB()
Imposta l’attributo
Bold Boolean Attivare: True; Disattivare: False.
grassetto.
Definisce il colore del
Color Long Impostare il colore mediante la funzione RGB()
carattere.
Imposta l’attributo
Italic Boolean Attivare: True; Disattivare: False.
corsivo.
Shadow Imposta l’attributo Boolean Attivare: True; Disattivare: False.
ombreggiato.
Dimensione del Variant
Size –
carattere. (numerico)

Le seguenti istruzioni modificano la cella A1 del foglio correntemente attivo impostando


rispettivamente:
il colore utilizzato per il testo in arancione;
l’attributo grassetto;
l’attributo corsivo a False se esso era attivo:
Cells(1, 1).Font.Color = RGB(255, 128, 0)
Cells(1, 1).Font.Bold = True
Cells(1, 1).Font.Italic = False

Un esempio di iterazione con l’oggetto Selection


La routine seguente potrà essere d’aiuto per realizzare macro che agiscono sulla cella attiva o su
una selezione di celle; l’istruzione If è superflua, ma risulta didatticamente importante per capire
dove inserire le condizioni. Essa può essere sostituita con altre condizioni che verranno ritenute
necessarie.
Sub OgniCellaNellaSelezioneInMaiuscolo()
Dim SingolaCella As Object

For Each SingolaCella In Selection


If Not IsEmpty(SingolaCella.Value) Then
SingolaCella.Value = UCase(SingolaCella)
End If
Next SingolaCella
End Sub
Capitolo 10

Creare le finestre

Oggi, creare un programma che utilizzi una finestra per dialogare con l’utente è diventato più
semplice rispetto allo sforzo richiesto alcuni anni fa. Queste finestre sono create con una tecnica
chiamata visuale, che si basa su un oggetto detto, appunto, finestra al quale sono aggiunti altri
oggetti quali caselle di testo, pulsanti e liste a discesa.

Terminologia
UserForm: è utilizzato per indicare le finestre create dal programmatore.
Focus: è un sostantivo che indica il componente della finestra attivo in un determinato
momento.

I preliminari
Il primo passo per costruire una finestra consiste nell’avere ben chiare le idee riguardo il suo
scopo e gli strumenti di cui si dovrà disporre per raggiungerlo. Il programma non è più l’elemento
fondamentale, che invece diventa la finestra: a essa dovranno essere associate routine che saranno
eseguite in risposta a determinati eventi, quali il clic del mouse o un inserimento di dati in una
casella da parte dell’utente.
Nel corso di questo capitolo saranno fornite le indicazioni necessarie per affrontare questo tipo
di lavoro, anche se non potranno essere esaustive; per esempio, non verranno riportate e illustrate
tutte le proprietà degli oggetti, poiché numerose e non indispensabili, evitando quindi di
confondere il lettore o di non consentire una rapida focalizzazione. Il Visualizzatore oggetti
contiene tuttavia tutte le informazioni per soddisfare le eventuali curiosità in proposito.
NOTA Durante la fase di test delle finestre può capitare di incontrare situazioni apparentemente senza senso
riconducibili a Visual Basic Editor quali:

Visual Basic Editor scompare dalla barra delle applicazioni di Windows;


premendo alcuni pulsanti il computer emette un beep;
le finestre non appaiono;
i menu e i pulsanti delle barre dei comandi non sono attivi;
un doppio clic su un controllo apre la finestra Codice, ma non crea la routine di gestione
dell’evento.

NOTA Queste e altre anomalie sono spesso dovute ai seguenti problemi di Excel:

una finestra è aperta;


un programma è in esecuzione;
è stata attivata la barra delle formule e quindi il cursore si trova al suo interno.

NOTA La prima cosa da fare, quando si riscontrano anomalie, consiste nel tornare in Excel per controllarne lo
stato.

Acquisire maggiori informazioni


Per riuscire a utilizzare appieno il Visualizzatore oggetti, al fine di ricercare approfondimenti in
tema di componenti degli UserForm, è necessario conoscere il nome assegnato agli oggetti da
Visual Basic, diverso dal termine che appare normalmente nell’Editor, ma che può essere
facilmente individuato con il sistema descritto di seguito.
Selezionare sullo UserForm il componente che si desidera esplorare con il Visualizzatore di
oggetti; se esso non è presente, occorre crearne uno nuovo, che potrà essere cancellato con il
tasto Canc non appena concluso il passo successivo.
Osservare nella finestra Proprietà l’elenco a discesa collocato immediatamente sotto il titolo
della finestra stessa: il nome assegnato al componente selezionato o appena creato appare in
grassetto, seguito dal nome del tipo di componente; occorre annotarlo e digitarlo nel
Visualizzatore oggetti.
Attraverso il menu Visualizza, avviare il Visualizzatore oggetti.
Nella casella testo da ricercare, inserire il nome del tipo di componente da ricercare e fare
clic sul pulsante Cerca In.
Per esempio, per ricercare informazioni sulle caselle di testo, si dovrà digitare il nome del tipo
utilizzato da Visual Basic, ovvero TextBox. Tra le voci che saranno trovate, quelle relative agli
UserForm appartengono alla libreria MSForms.
Inoltre, se è stato installato l’aiuto o help e si desidera approfondire ulteriormente le
informazioni in merito a un componente degli User- Form, è possibile ricorrere a tale strumento.

Creare una finestra


Per creare una nuova finestra o UserForm si deve aprire la cartella all’interno della quale dovrà
essere contenuta, aprire Visual Basic Editor e selezionare Inserisci/UserForm; apparirà
immediatamente un nuovo UserForm vuoto (Figura 10.1).
Figura 10.1 Visual Basic Editor con una nuova finestra appena creata.

Ricordare questo dettaglio significa non perdere tempo a cercare di visualizzare tale finestra e a
capire come comportarsi se scompare facendo doppio clic o eseguendo altre operazioni. A questo
riguardo, il menu Finestra è indubbiamente di aiuto, in quanto permette di vedere:
la voce relativa al nuovo UserForm;
la voce del codice relativa allo UserForm, se è già stata creata involontariamente (Figura
10.2).

Figura 10.2 Il menu Finestra dopo la creazione di una nuova finestra e del suo codice.

NOTA Si tenga presente che la finestra Proprietà visualizza informazioni relative all’oggetto correntemente
selezionato, il cui nome viene riportato per comodità immediatamente sotto l’intestazione.

Selezionare uno o più componenti


La selezione di un componente avviene facendo clic sopra di esso, ma è possibile selezionare
più oggetti:
tenendo premuto il tasto Ctrl e facendo clic su ogni singolo oggetto che si desidera
selezionare;
tracciando con il puntatore del mouse, quando ha la normale forma della freccia, un’area sulla
finestra che comprenda i vari oggetti;
utilizzando entrambe le tecniche.

NOTA Il primo oggetto a essere selezionato avrà le maniglie di colore bianco, a differenza degli altri che le avranno
nere.

Per deselezionare un oggetto che è stato erroneamente selezionato è sufficiente fare clic sopra di
esso, tenendo premuto il tasto Ctrl.

Impostare contemporaneamente una proprietà per più


componenti
Vi sono situazioni in cui diventa necessario modificare una proprietà in diversi componenti; si
può risparmiare tempo selezionando tutti gli oggetti dello stesso tipo che si desidera modificare e
agendo sulla finestra Proprietà: a essi saranno assegnati i nuovi valori impostati.
È anche possibile applicare questa tecnica su componenti diversi, ma in tal caso la finestra
Proprietà mostrerà un insieme di voci limitato alle sole proprietà comuni tra tutti i tipi selezionati.
Se i componenti non sono ancora stati inseriti sullo UserForm, è possibile impostare i valori
delle proprietà sul primo di essi e, anziché continuare a prelevare lo stesso componente dalla
Casella degli strumenti, copiarlo e incollarlo tante volte quanti sono gli oggetti desiderati con
quelle caratteristiche.
NOTA Sebbene la proprietà Name sia presente in ogni componente, non appare nella finestra Proprietà se sono stati
selezionati più componenti, in quanto ogni oggetto deve avere un nome univoco e quindi non avrebbe senso
impostare lo stesso per tutti (Figura 10.3).
Figura 10.3 Se vengono selezionati più oggetti, la finestra Proprietà visualizza solamente le proprietà comuni.

Eliminare un controllo dalla finestra


Per eliminare un componente che per qualche motivo non serve più, lo si deve selezionare e
cancellare selezionando Modifica/Elimina. Una tecnica più veloce prevede l’utilizzo del tasto
Canc, che ha lo steso effetto.
NOTA Il percorso Modifica/Annulla permette di annullare solo l’eliminazione dell’ultimo componente cancellato:
quelli precedenti non sono più recuperabili.

Tipi di finestre: modali e non modali


In base alle esigenze del programmatore, si possono creare due tipi di finestra che differiscono
nel comportamento d’interazione dell’utente con Excel.
Modali: è la tipica finestra di dialogo di Windows che non permette all’utente di svolgere
altri lavori con Excel fino a quando resta aperta; se egli tenta di fare clic fuori dalla finestra,
un beep gli segnalerà l’impossibilità di tornare a Excel. Tipici esempi di finestre modali sono
Apri e Salva.
Non modali: l’utente può uscire dalla finestra per tornare in Excel e svolgere altri lavori, per
ritornare successivamente a essa.

NOTA Una finestra modale non impedisce all’utente di passare a un altro software, ma solo a quello a cui essa
appartiene, in questo caso Excel.

Indubbiamente le finestre non modali sono quelle più apprezzate dall’utente, che può
sospendere l’interazione con essa, magari per spostarsi su un foglio in cerca di informazioni
richieste dalla finestra; per il programmatore, le finestre modali sono quelle che richiedono un
numero inferiore di attenzioni, in quanto tutto quello che avviene è limitato all’interazione
dell’utente con la finestra, per cui è relativamente facile prevedere tutte le condizioni che possono
verificarsi.
Per i programmi destinati a essere elaborati in Excel, la scelta tra i due tipi è abbastanza
scontata ed è orientata verso il tipo modale, anche in virtù del fatto che l’utente è abituato a esso,
anche se il tipo non modale potrebbe essere ugualmente apprezzato.
Nell’ipotetico caso esistesse la necessità di modificare l’allineamento verticale di celle non
contigue, l’utente dovrebbe:
selezionare la cella;
richiamare la finestra che gestisce l’allineamento verticale e selezionare quello di volta in
volta più opportuno;
chiudere la finestra.
Occorre quindi ripetere queste operazioni per tutte le celle da riformattare.
La finestra Formato celle è di tipo modale, ovvero l’utente la richiama, imposta i parametri
secondo le proprie necessità e la chiude indicando al programma che deve applicare le
impostazioni alla cella attiva o a quelle selezionate (Figura 10.4). Diversamente, se tale finestra
fosse di tipo non modale, essa rimarrebbe sempre aperta evitando all’utente di riaprirla
continuamente.

Figura 10.4 La finestra di Excel da utilizzare per applicare la formattazione relativa all’allineamento verticale. Essa viene
aperta con la modalità ShowModal.

Già da questo esempio si potrebbero trarre numerose riflessioni sulla scelta tra il tipo modale o
non modale: in alcuni casi la programmazione sembra essere un’arte e cosa sia meglio o più utile
porta a lunghe disquisizioni accademiche.
Il suggerimento che si può dare in questi casi è utilizzare le finestre modali, in quanto non
causano alcun tipo di complicazione, come la nessessità di aggiungere al programma controlli per
evitare errori (per esempio, per verificare se la cartella sulla quale la finestra deve agire non è
stata chiusa nel frattempo, oppure se l’utente ha avviato lo stesso programma più volte).
Il punto cruciale che impone il ricorso alla finestra di tipo modale può essere riassunto in una
domanda: le informazioni che vengono introdotte nella finestra sono necessarie o indispensabili
per la prosecuzione? Se la riposta è affermativa non vi sono dubbi di sorta.
Se si è deciso per creare una finestra non modale, allora si deve impostare la proprietà ShowModal
con il valore False: tale proprietà non è accessibile ai programmi, quindi non è possibile
impostarla dall’interno di una routine, ma può comunque essere successivamente variata attraverso
Visual Basic Editor.
NOTA Un programma che utilizza una finestra modale può comunque aprire altre finestre.

L’aggiunta dei componenti


Il passo successivo alla creazione della finestra consiste nell’inserirvi gli oggetti di cui si
potrebbe avere bisogno: Visual Basic Editor li chiama componenti. La Casella degli strumenti
(Figura 10.5) deve essere visibile, altrimenti occorre selezionare Visualizza/Casella degli
strumenti per aprirla. Per collocare un nuovo componente sulla finestra si procede come descritto
di seguito.
Selezionare il componente desiderato facendo clic sulla relativa icona che appare nella
Casella degli strumenti, eventualmente dopo avere visualizzato la scheda che la contiene, se
è diversa da Controlli.
Fare clic sulla finestra, approssimativamente nella posizione in cui dovrà apparire lo spigolo
superiore sinistro del componente che viene visualizzato con una dimensione reimpostata.
Prendere una maniglia del componente per modificare le sue dimensioni in base alle esigenze.
È necessario sapere a quale icona corrisponde il controllo che si vuole inserire, ma questo non
dovrebbe risultare difficile, anche in considerazione dei suggerimenti che appaiono sotto il
puntatore del mouse quando esso si attarda su un’icona.
Figura 10.5 La Casella degli strumenti.

Quello che è invece necessario conoscere sono le caratteristiche dei controlli, che vengono qui
elencati rispettando l’ordine in cui appaiono nella Casella degli strumenti:
Etichetta o Label
Casella di testo
Casella combinata
Casella di riepilogo
Casella di controllo
Pulsante di opzione
Pulsante interruttore
Cornice
Pulsante di comando
Schede
Pagine
Barra di scorrimento
Pulsante di selezione
Immagine
RefEdit
Il componente Etichetta, o label (Figura 10.6), consente di creare un oggetto sulla finestra il cui
scopo è visualizzare un testo che viene digitato:
nella proprietà .Caption:
Label1.Caption = “Testo dell’Etichetta”

direttamente all’interno del controllo dopo averlo selezionato con due clic del mouse,
facendo attenzione a non farli troppo ravvicinati per evitare che siano interpretati come un
doppio clic (in questo caso verrebbe aperta la finestra relativa al codice e si dovrebbe
utilizzare il menu Finestra per tornare alla finestra dello UserForm).

Figura 10.6 Come appare un controllo Etichetta in fase di progettazione della finestra.

Le caratteristiche del testo che viene visualizzato all’interno del componente Etichetta possono
essere specificate attraverso le sue proprietà, in particolare Font che consente di agire su tutti gli
attributi del carattere (Figura 10.7). Essi possono essere anche impostati attraverso il programma
utilizzando l’oggetto Font; per esempio, la seguente istruzione modifica l’oggetto di nome Label1
attivando l’attributo Grassetto per il testo che visualizza:
Label1.Font.Bold = True

Figura 10.7 La finestra Tipo di carattere che si apre facendo clic sul pulsante ... presente nella voce Font della finestra
Proprietà.

Altre proprietà dell’oggetto Etichetta che possono risultare utili sono riportate nella tabella
seguente (Figura 10.8).
Nome della
Scopo
proprietà

ControlTipText
Definisce una stringa che viene visualizzata sotto il puntatore del cursore quando l’utente
indugia sopra di esso.

AutoSize
La dimensione del controllo viene automaticamente modificata per adattarsi alla dimensione del
testo che contiene.
TextAlign Definisce l’allineamento del testo optando tra sinistra (default), centrato e destra.

WordWrap
Consente all’etichetta di mandare a capo il testo se la lunghezza complessiva supera quella del
controllo.
Figura 10.8 Le proprietà del componente Label (etichetta).

Casella di testo o TextBox


Il componente Casella di testo è largamente utilizzato nelle finestre ed è un oggetto al quale
l’utente è abituato (Figura 10.9); il suo impiego consiste nel:
consentire l’inserimento di un valore nella finestra utilizzando una o più righe;
visualizzare informazioni.
Per acquisire quanto l’utente ha digitato o inserire al suo interno un valore, si ricorre alla
proprietà Text. Il seguente frammento di codice acquisisce il testo presente nel componente Casella
di testo di nome TextBox1, lo converte in maiuscolo e ve lo reinserisce:
str = TextBox1.Text
str = UCase(str)
TextBox1.Text = str

Figura 10.9 Come appare il controllo Casella di testo in fase di progettazione della finestra.
Casella combinata o ComboBox
Il componente Casella combinata (Figura 10.10) consente all’utente di inserire un valore
attraverso due sistemi:
a digitazione;
la scelta di una voce presente nella lista che si apre facendo clic sul pulsante posto alla fine
della casella.

Figura 10.10 Come appare il controllo Casella combinata in fase di progettazione della finestra.

Il valore digitato può essere acquisito mediante la proprietà Value. Il seguente listato è una
routine, associata a un controllo di nome CommandButton1, che provvede a copiare il valore della
casella combinata di nome MezziDiTrasportoUtilizzabili in TextBox1:
Private Sub CommandButton1_Click()
TextBox1.Text = MezziDiTrasportoUtilizzabili.Value
End Sub

La stessa proprietà consente di impostare il valore che tale controllo deve visualizzare, magari
come opzione da proporre all’utente:
MezziDiTrasportoUtilizzabili.Value = “Automobile”

Per inserire i valori all’interno della lista si può ricorrere al metodo Add-Item; il seguente
esempio carica alcuni valori in un componente ComboBox di nome MezziDiTrasportoUtilizzabili:
MezziDiTrasportoUtilizzabili.AddItem (“Motocicletta”)
MezziDiTrasportoUtilizzabili.AddItem (“Bicicletta”)
MezziDiTrasportoUtilizzabili.AddItem (“Autobus”)
MezziDiTrasportoUtilizzabili.AddItem (“Taxi”)
MezziDiTrasportoUtilizzabili.AddItem (“Aereo di linea”)
MezziDiTrasportoUtilizzabili.AddItem (“Aereo noleggiato”)

Per la loro capacità di interagire direttamente con il foglio di lavoro, risultano interessanti le
proprietà illustrate di seguito.
Row Source: è possibile assegnarle un riferimento stile Excel dal quale prenderà i valori che
verranno visualizzati all’utente; per esempio, si può assegnare A1:A8 mediante Proprietà
oppure “A1:A8” se si utilizza una macro.
Control Source: contiene il riferimento alla cella nella quale verrà copiato il valore che
l’utente introdurrà nel controllo.

Casella di riepilogo o ListBox


La Casella di riepilogo (Figura 10.11) è un componente al cui interno il programma inserisce
valori attraverso la proprietà AddItem riguardante la Casella combinata; di tali valori l’utente può
selezionarne:
uno solamente, se la proprietà Multiselect è impostata a zero ovvero con la costante
fmMultiSelectSingle;

uno o più di uno, tra loro contigui, se la proprietà Multiselect è impostata a uno ovvero con la
costante fmMultiSelectMulti;
uno o più di uno, anche se non sono tra loro contigui, se la proprietà Multiselect è impostata a
uno ovvero con la costante fmMultiSelectExtended.

Figura 10.11 Come appare il controllo Casella di riepilogo in fase di progettazione della finestra.

Per controllare quali voci siano state selezionate dall’utente, si può ricorrere a un ciclo che
verifica ogni elemento per determinare se è selezionato o meno. La seguente routine è un esempio
di come deve essere costruito il loop: in questo caso, il suo scopo è visualizzare una finestra che
riepiloga tali voci:
Private Sub CommandButton1_Click()
Dim n As Integer
Dim Selezionato As Boolean
Dim s As String

s = “Selezionate le seguenti voci:” & vbCr

For n = 0 To MezziDiTrasportoUtilizzati.ListCount - 1
Selezionato = MezziDiTrasportoUtilizzati.Selected(n)
If Selezionato Then
s = s & MezziDiTrasportoUtilizzati.List(n)
s = s & vbCr
End If
Next n
MsgBox s
End Sub

NOTA Gli elementi del componente Casella di riepilogo sono numerati da zero indipendentemente dalle
impostazioni di Option Base; per questo motivo, il loop viene eseguito da zero fino al numero di elementi in esso
contenuti decrementato di un’unita: per esempio, se esistono tre elementi la proprietà Count restituisce il valore 3
(comunque essi sono numerati da zero a due).
Casella di controllo o CheckBox
Le caselle di controllo sono un altro componente presente molto spesso nelle finestre (Figura
10.12); il loro compito consiste nel fornire all’utente la possibilità di contrassegnare una scelta
facendo clic con il mouse per visualizzare il tipico segno di spunta. Il testo descrittivo viene
inserito attraverso la proprietà Caption, disponibile sia al programma sia, più comodamente, nella
finestra Proprietà di Visual Basic Editor. Per sapere se l’utente ha attivato o disattivato la casella,
si ricorre alla proprietà Value. Il seguente codice di esempio controlla se l’utente ha attivato una
casella di nome StampareBusta:
If StampareBusta.Value = True Then
Call EsegueStampaDellaBusta
End If

Figura 10.12 Come appare il controllo Casella di controllo in fase di progettazione della finestra.

Pulsante di opzione o OptionButton


I pulsanti di opzione sono concettualmente identici alle caselle di controllo, ma introducono il
concetto di esclusione reciproca: solo uno di essi può essere attivo in un dato momento (Figura
10.13).

Figura 10.13 Come appare il controllo Pulsante di opzione in fase di progettazione della finestra.

Per poter gestire più insiemi di pulsanti di opzione si deve ricorrere a una sorta di contenitore
che consenta allo UserForm di sapere quali devono interagire tra loro e quali no (Figura 10.14): la
Cornice o Frame.
È utile ritornare al concetto di oggetto che ne può contenere altri: la finestra è un oggetto che può
contenere più pulsanti di opzione dei quali solo uno può essere selezionato. Se essa contiene un
oggetto Cornice il quale, a sua volta contiene altri oggetti Pulsante di opzione, essi costituiranno
un gruppo separato all’interno del quale vi sarà un solo Pulsante di opzione selezionato. In questo
modo si contano già due pulsanti di opzione attivi: uno contenuto nell’oggetto UserForm e un altro
nell’oggetto Cornice dentro UserForm. Applicando questo concetto si potranno avere più cornici
per creare gruppi indipendenti di

Figura 10.14 Come appare uno UserForm con una serie di gruppi di pulsanti di opzione raggruppati in quattro insiemi.
Quelli numerati da 1 a 4 appartengono all’insieme degli UserForm.

pulsanti di opzione, arrivando a inserire in una cornice altre cornici, ognuna delle quali
potrebbe avere gruppi di pulsanti di opzione tra loro indipendenti.
Il controllo per determinare se un Pulsante di opzione è stato selezionato o meno può essere
effettuato analizzando la proprietà Value, che restituisce il valore booleano True o False a seconda
dei casi.

Cornice o Frame
Il componente Cornice viene impiegato per creare un insieme di componenti che abbiano tra
loro una relazione, per cui può risultare utile raggrupparli (Figura 10.15).
Per fini estetici e di immediatezza: per esempio, in una finestra in cui devono essere inseriti
dati relativi a una coppia spostata, questi possono essere raggruppati in due Cornici distinte;
Per motivi tecnici: i pulsanti di opzione contenuti in una cornice opereranno come un gruppo,
per cui attivare uno di essi significa disattivare tutti quelli appartenenti allo stesso gruppo; in
tal modo è possibile avere più gruppi di pulsanti di opzione che non interferiscano
reciprocamente.
Figura 10.15 Come appare un controllo Cornice in fase di progettazione della finestra.

Ogni cornice può avere una scritta che appare nella parte superiore; può esservi indicato il
contenuto della cornice (Figura 10.16) in modo da guidare l’utente a una migliore lettura della
finestra. Questo testo viene inserito mediante la proprietà Caption.

Figura 10.16 Esempio di utilizzo delle Cornici per migliorare la leggibilità della finestra.

Pulsante di comando o CommandButton


I componenti Pulsante di comando (Figura 10.17) sono estremamente diffusi nelle finestre e il
loro compito consiste nell’eseguire una determinata routine o chiudere la finestra, magari
comunicando all’utente le sue intenzioni; per esempio, se ha fatto clic sul pulsante OK significa che
conferma i dati e vuole che il programma svolga il suo compito, se ha fatto clic su Annulla vuol
dire il contrario. A ciascuno di essi deve essere associata una routine che verrà eseguita quando
l’utente farà clic su tale controllo.
Il sistema più rapido ed efficace per raggiungere questo scopo consiste nel farvi doppio clic
sopra: sarà aperta la finestra Codice nella quale apparirà il corpo di una nuova routine con il nome
composto dal nome del controllo e dell’evento che essa gestirà (Click più il carattere underscore).
Figura 10.17 Come appare un controllo Pulsante di comando in fase di progettazione della finestra.

Scheda o TabStrip
Il componente Scheda serve per avere più controlli raggruppati su diverse schede ed è analogo
al controllo Pagina che, però, è più immediato, per cui si suggerisce di utilizzare quest’ultimo.

Pagina o Page
Se una finestra visualizza troppe informazioni, generalmente diventa poco leggibile e tende a
confondere l’utente.
In queste situazioni, il controllo Pagina si rivela utile in quanto consente di creare un’area
concettualmente suddivisa in più livelli, ciascuno dei quali è un insieme di oggetti che saranno
visualizzati a turno (Figura 10.18).
L’ordine di visualizzazione si basa sulla scheda che l’utente decide di vedere agendo sulla
linguetta posta nella parte superiore del controllo Pagina.

Figura 10.18 Come appare il controllo Pagina in fase di progettazione della finestra.

Anche nei casi in cui non vi sia un reale sovraffollamento di informazioni ma, più
semplicemente, siano presenti informazioni utilizzate più raramente, è possibile conferire alla
finestra una migliore leggibilità utilizzando due o più schede in cui inserire i dati meno utili che
siano comunque immediatamente disponibili per l’utente, qualora desiderasse consultarli o
modificarli.
Di seguito è descritto come utilizzare questo controllo.
Per prima cosa si crea il controllo Pagina sulla finestra.
Si assegna il testo descrittivo alla scheda agendo sulla sua proprietà Caption.
Si inseriscono i controlli appartenenti alla prima scheda.
Si assegna il nome alla scheda, sostituendo quello di default con un altro più descrittivo e
utilizzando il menu contestuale.
Una volta completata una scheda, si passa a quella successiva facendo clic sulla sua linguetta;
possono essere create schede con il menu contestuale, se non ve ne sono altre disponibili.
Le Figure 10.19 e 10.20 mostrano alcuni esempi.
NOTA Il menu contestuale del controllo Pagina verrà descritto nel prossimo paragrafo.

Figura 10.19 Esempio di controllo Pagina con attiva la scheda Page1.

Figura 10.20 Esempio di controllo Pagina con attiva la scheda Page2.

Immagine o Image
Il componente Immagine riserva un’area nella quale potrà essere caricata un’immagine che sarà
visualizzata nella finestra. L’immagine viene indicata:
all’interno di Visual Basic Editor attraverso la proprietà Picture;
dal programma, mediante la proprietà Picture alla quale viene assegnato il risultato della
funzione LoadPicture() che riceve come parametro, il nome dell’immagine da caricare (Figura
10.21).

Figura 10.21 Come appare un controllo Immagine dopo aver specificato l’immagine attraverso la proprietà Picture.

Di default, se la dimensione dell’immagine eccede quella del componente, essa verrà


automaticamente tagliata ai bordi in base a quanto impostato nella proprietà PictureAlignment.
In alternativa, è possibile operare con la proprietà PictureSizeMode, che consente di ridimensionare
automaticamente l’immagine affinché sia completamente visibile, impostandone il valore a:
fmPictureSizeModeStretchper ingrandire l’immagine al fine di riempire l’area del componente, ma
senza rispettare le proporzioni;
fmPictureSizeModeZoom per ingrandire l’immagine al fine di riempire l’area del componente, ma

rispettando le proporzioni;
fmPictureSizeModeClip per rispettare le dimensioni originarie.

La Figura 10.22 mostra la finestra Proprietà relativa a un componente Immagine.


Figura 10.22 La finestra Proprietà relativa a un componente Immagine.

RefEdit
Il controllo RefEdit è uno strumento molto interessante per i programmatori in Visual Basic per
Excel, infatti permette all’utente di inserire un riferimento a una o più celle mediante il mouse, in
modo simile a quanto può fare con altre funzionalità di Excel come Ricerca obiettivo (Figura
10.23).

Figura 10.23 La finestra Ricerca obiettivo che si apre da Dati/Analisi di Simulazione/Ricerca obiettivo di Excel: la prima e
l’ultima casella sono componenti RefEdit.

Tutta la gestione è a carico di Visual Basic; quando l’utente preme il pulsante alla destra del
componente RefEdit la finestra viene nascosta e ne appare un’altra, che consente di accedere al
foglio di lavoro e selezionare una cella o un’insieme di celle (Figura 10.24): i riferimenti di tale
selezione vengono copiati nella nuova finestra. Al termine di questa operazione l’utente deve fare
un altro clic sul pulsante della casella, la finestra si richiuderà e quella originaria tornerà visibile,
mentre all’interno del controllo RefEdit su cui si era fatto clic compariranno i riferimenti
selezionati dall’utente.

Figura 10.24 Il risultato che si ottiene facendo clic sul pulsante collocato a destra di una casella RefEdit; la finestra
originaria si nasconde e viene sostituita.

Il programmatore non deve fare altro che acquisire, nel momento in cui gli servono, i riferimenti
selezionati o digitati, ricorrendo alla proprietà Text. La seguente routine visualizza i riferimenti
inseriti nel componente RefEdit quando viene fatto clic su un pulsante di nome CommandButton1:
Private Sub CommandButton1_Click()
Dim str As String

str = RefEdit1.Text
MsgBox “Il riferimento e’ : “ & str
End Sub

NOTA Se il componente RefEdit non è visibile sulla Casella degli strumenti, significa che esso non è configurato.

Per risolvere, fare clic con il tasto destro del mouse nella parte più interna della Casella degli
strumenti per aprire il menu contestuale in cui andrà selezionata la voce Controlli Aggiuntivi
(Figura 10.25). per aprire l’omonima finestra: nell’elenco Controlli disponibili, cercare la voce
RefEdit.Ctrl e selezionarla (Figura 10.26).

Alla chiusura della finestra, nella Casella degli strumenti sarà disponibile l’icona del controllo
RefEdit.

Figura 10.25 Controlli aggiuntivi della Casella degli strumenti.


Figura 10.26 Elenco dei controlli aggiuntivi.

Navigare tra i componenti


Gli utenti possono accedere a un controllo presente su uno UserForm, o spostarsi da uno
all’altro, principalmente attraverso tre sistemi:
facendo clic su di essi;
utilizzando il tasto Tab;
con lo spostamento del cursore, seguendo le istruzioni del programma.
Se lo spostamento da un controllo a un altro avviene mediante il tasto Tab, allora è necessario
avere cura di gestire l’ordine con cui i vari componenti sono da attivare. L’ordine ha più
importanza per l’utente, che non desidera vedere saltare il cursore da un controllo a un altro senza
una logica, che per il programma, il quale non può conoscere l’ordine con cui l’utente accederà ai
vari componenti dello UserForm.
Per impostare tale sequenza, si ricorre a un’apposita finestra che si apre selezionando
Visualizza/Ordine di tabulazione.
Tale finestra non elenca tutti i suoi componenti e per comprenderne la logica è necessario
ricordare il concetto di contenitore, o di oggetti che hanno altri oggetti. Lo UserForm è un oggetto
che ne può contenere altri, quali etichette, caselle di testo, pulsanti e cornici. Quest’ultimo tipo di
oggetto è, a sua volta, un contenitore di altri oggetti tra i quali è possibile trovare anche altre
cornici.
Ne consegue che la finestra Ordine di tabulazione mostra gli oggetti appartenenti:
al componente selezionato, se esso è di tipo contenitore, quali UserForm o cornice;
al contenitore al quale appartiene l’oggetto selezionato.
Un esempio può essere di aiuto a comprendere meglio il concetto. Se in una finestra sono
presenti tre oggetti (una cornice, una cornice con al suo interno un’altra cornice e un pulsante), la
finestra Ordine di tabulazione li mostrerà indipendentemente da quanti ne esistono all’interno delle
cornici, e sarà possibile indicare l’ordine con il quale saranno raggiunti in sequenza mediante il
pulsante Tab. Successivamente sarà necessario eseguire la stessa operazione sui singoli oggetti di
tipo Cornice per indicare la sequenza degli oggetti che contengono.

Associare le routine ai componenti


Dopo avere creato uno UserForm e avervi inserito i componenti, è giunto il momento di
associare le routine che svolgono il lavoro per il quale si è costruita la finestra.
Di solito sono associate a eventi riguardanti uno o più componenti, ma l’oggetto Pulsante di
comando e il suo evento Click sono quelli più utilizzati.
Per esempio, se una finestra deve richiedere all’utente di digitare un valore che dovrà essere
inserito nella cella attiva del foglio di lavoro, è possibile creare un pulsante di nome AggiornaCella
e, nella routine di gestione dell’evento Click, inserire le istruzioni:
Private Sub AggiornaCellaCmdBtn_Click()
ActiveCell.Value = NuovoValoreTextBox.Text
End Sub

Creare il gestore di eventi


Visual Basic Editor associa automaticamente le routine ai componenti della finestra basandosi
sul loro nome, quindi ogni routine il cui nome sia composto dal nome di un oggetto, di un evento e
dal carattere underscore, sarà automaticamente associata alla relazione oggetto/ evento con gli
stessi nomi.
Per conoscere i nomi di tutti gli eventi possibili per ogni oggetto, occorre:
attivare la finestra Codice;
selezionare l’oggetto nella lista Oggetto;
aprire la lista Routine.

NOTA La dichiarazione delle routine di uno UserForm è preceduta dalla parola chiave Private per rendere tali
routine inaccessibili agli altri moduli o UserForm. Se si desidera condividere una routine con altre finestre,
conviene realizzare una routine separata (non di tipo Private) che possa essere richiamata dalle varie routine degli
UserForm.
Capitolo 11

Gestione degli errori

Per il programmatore, l’utente rappresenta un’incognita, in quanto è impossibile prevedere che


cosa farà e, soprattutto, come lo farà. Questa semplice considerazione si rivela tanto più concreta,
quanto più il programma si diffonde e viene utilizzato da persone con conoscenze informatiche
molto diverse. Ormai fa parte del bagaglio culturale di chiunque utilizzi un computer gestire gli
errori dei programmi; talvolta, infatti, questi ultimi sembrano addirittura impazzire, fanno cose
inaspettate, si rifiutano di funzionare o, nel peggiore dei casi, si bloccano. Spesso, però, la colpa
di questi problemi non va ricercata nelle macchie solari e nelle conseguenti tempeste magnetiche:
quasi sempre esiste una logica di tipo informatico dietro a queste anomalie, anche se può essere
quanto mai difficile individuarla e risolverla.
Chi sviluppa i software è molto sensibile a questi inconvenienti, in quanto sa che l’utente
potrebbe lamentarsi dell’instabilità del programma, del tempo che ha perso, dei risultati mai
ottenuti.
Qualunque sia il motivo, gli errori nei programmi possono comunque verificarsi e la differenza
tra un programmatore e l’altro si vede anche nell’attenzione che impiega nell’applicazione tecnica
utile a prevenire o gestire gli errori.

Terminologia
Di seguito sono elencati alcuni termini informatici, tanto per chiarire qualche concetto.
Ambiente. Insieme di fattori disgiunti o concomitanti, con cui il programma deve rapportarsi:
versione del software, spazio libero su disco fisso, esecuzione contemporanea di altri
programmi e lingua.
Compilazione. Fase in cui Visual Basic Editor converte le istruzioni in un formato interno,
eseguibile come programma.
Sintassi. Insieme di regole formali che indicano come un’istruzione può essere costruita.

Errori di compilazione e di esecuzione


Un programma può essere affetto da errori che possono rivelarsi in distinti momenti e
richiedono un approccio radicalmente differente. È possibile trovare errori di tre tipi diversi:
errori sintattici;
errori di compilazione;
errori di esecuzione.

Errori sintattici
Quello sintattico è il primo tipo di errore con cui il programmatore moderno deve confrontarsi.
È causato da un’istruzione scritta con errori formali come, per esempio, i seguenti:
omettere il nome identificativo nell’istruzione Sub o Function;
una parola chiave digitata erroneamente;
una parola chiave digitata ma omessa;
mancanza di una parentesi, una virgola oppure uno o più parametri obbligatori nella chiamata
di funzioni o subroutine;
suddividere un’istruzione su più linee senza utilizzare correttamente i caratteri spazio e
underscore;
concatenare stringhe e variabili, utilizzando l’operatore & senza lasciare gli spazi tra i vari
componenti;
creare espressioni nelle quali non è presente una corrispondenza corretta tra le parentesi
aperte e chiuse;
accedere a un elemento di una matrice senza utilizzare l’indice;
cercare di assegnare un valore a una proprietà non modificabile di un oggetto.
Questo genere di errori viene individuato da Visual Basic Editor nel momento stesso in cui si
preme il tasto Invio, oppure si sposta il cursore all’esterno della o delle righe che contengono
l’istruzione: ciò rende possibile analizzarla immediatamente per cercare di comprendere l’errore e
correggerlo. Il tipo di segnalazione è duplice e si presenta come nell’elenco che segue.
I caratteri dell’istruzione appena introdotta o modificata, nella quale viene riscontrato un
errore, assumono il colore rosso.
Appare una finestra in cui un’indicazione comunica la presenza di un errore di compilazione e
la tipologia del problema.
Arrivati a questo punto, esiste la possibilità di premere il pulsante ? per cercare di avere
spiegazioni più esaurienti riguardanti l’errore. Premendo il pulsante OK il cursore torna
sull’istruzione errata.
NOTA Visual Basic Editor definisce come errori di compilazione le analisi sintattiche delle istruzioni. La
compilazione avviene nel momento in cui il programma è eseguito.
Individuare la causa dell’errore può essere semplice o difficile, in relazione alla stessa
istruzione. È consigliabile, in proposito, suddividere le istruzioni troppo complesse in modo che
gli eventuali errori possano essere circoscritti con maggiore semplicità. Per esempio, utilizzare
un’istruzione che assegna a una proprietà un valore derivante da una funzione che richiede tre
parametri, ognuno dei quali composto da una lunga espressione, significa complicarsi la vita. È
più facile controllare la stessa istruzione suddividendola in cinque parti come di seguito.
Tre destinate ad assegnare ad altrettante variabili i valori che restituiscono le tre espressioni.
Una per assegnare a un’altra variabile il risultato della funzione richiamata utilizzando le tre
precedenti variabili.
Una per assegnare alla proprietà il valore dell’ultima variabile.
In caso si debba procedere al debug del programma, questa tecnica permette di avere
rapidamente sotto controllo gli elementi che seguono:
il valore di ogni singolo parametro utilizzato nella funzione;
il valore restituito dalla funzione.
Diventerà così molto più semplice capire se il problema è presente in essi o se una delle
espressioni è stata scritta omettendo una coppia di parentesi o un’operazione (dalla Figura 11.1
alla Figura 11.6).
Un esempio concreto di quanto detto può essere costituito dall’istruzione seguente:
Sub EsempioDivisione1()
MsgBox InputBox(“Digitare il divisore”)/ _
InputBox(“Digitare il dividendo”)
End Sub

Essa risulta sintatticamente perfetta; quando viene eseguita apre in successione due finestre
InputBox per richiedere all’utente di introdurre altrettanti numeri per poi visualizzare, con la

funzione MsgBox, il risultato della loro divisione. Il suddividerla in più istruzioni porta alla routine
seguente:
Sub EsempioDivisione1()
Dim divisore, dividendo As Double

dividendo = InputBox(“Digitare il divisore”)


divisore = InputBox(“Digitare il dividendo”)

MsgBox dividendo & “/” & divisore & “=” & dividendo / _
divisore
End Sub

NOTA La funzione InputBox restituisce un valore di tipo String che Visual Basic provvede a convertire
automaticamente nel tipo della variabile a cui deve essere assegnato il valore digitato dall’utente.

NOTA Il compilatore, a differenza delle precedenti versioni, non ammette più che una variabile abbia lo stesso
nome di una funzione e lo segnala immediatamente. Ciò riduce la possibilità di scrivere errori: per esempio poteva
capitare di creare la variabile di nome Len che ha un’omonima funzione.
Figura 11.1 Errore causato dall’omissione del nome della routine nell’istruzione Sub.

Figura 11.2 Errore causato dall’assenza di spazi nella concatenazione di variabili.

Figura 11.3 Errore causato dalla mancanza di una parola chiave nell’istruzione If.

Figura 11.4 Errore causato dall’uso inesatto di una proprietà.


Figura 11.5 Errore causato dall’uso inesatto di una proprietà.

Figura 11.6 Errore causato dall’assenza del carattere spazio prima di underscore per suddividere un’istruzione su più
righe.

Errori di compilazione
Quando si introduce un’istruzione, essa può essere sintatticamente corretta, ma nel contesto
generale potrebbe risultare incoerente. Per esempio, si è visto che i cicli possono contenere al loro
interno altri cicli. In questo modo, la routine che segue non presenta errori per l’interprete ma, al
momento della compilazione, viene segnalato (Figura 11.7):
‘ ---Attenzione: ciclo errato!
Sub EsempioConCicloErrato()
Dim a, b As Integer
Dim c As Long

For a = 1 To 5
For b = a To a + 1
c = b ^ 2
Next a
Next b
End Sub
Figura 11.7 Esempio di errore di compilazione nel ciclo For / Next.

Questi errori sono decisamente più difficili da individuare e risolvere degli errori sintattici ed è
quindi necessaria un’analisi che non si limiti alla singola istruzione, ma abbracci in successione
gli elementi seguenti:
tutta la routine;
tutto il modulo;
tutto il progetto (VBAProject).
Quasi mai è necessario spingersi a verificare l’intero progetto, in quanto il problema è quasi
sempre posto all’interno della routine o funzione che viene indicata da Visual Basic Editor. Vi
sono anche casi, però, decisamente più rari, in cui il problema va risolto a livello di modulo, per
esempio quando ci sono routine con lo stesso nome.
Gli errori di compilazione, per i programmatori che non hanno ancora avuto il tempo di
acquisire una sufficiente esperienza con il linguaggio, rappresentano una difficoltà che può metterli
alla prova, ma generalmente vengono risolti in breve tempo. Esistono casi in cui, tuttavia, per vari
motivi la routine errata sembra non contenere nessun errore. In queste situazioni potrebbe essere
utile suddividerla, se possibile, in due o più subroutine, ognuna delle quali specializzata a
svolgere una parte del lavoro della routine originaria; per non dover andare a modificare i
programmi che eventualmente la richiamano, la tecnica da utilizzare consiste nel mantenerla come
contenitore delle chiamate alle altre subroutine.
La routine che segue è un esempio di due differenti e ipotetici cicli: il primo scorre tutto il
foglio Disponibilità per conteggiare le righe aventi uno specifico requisito, al fine di verificare se
tale numero è maggiore di dieci, per eseguire sullo stesso foglio un aggiornamento. I cicli
appaiono sostituiti da una chiamata a una funzione e una chiamata a una subroutine nelle quali
apparirà il codice dei due cicli:
SubA ggiornaDisponibilitaSeNecessario()
r = ContaRigheOveQuantitaUgualeAZero(“Disponibilita”)
if (r > 10 Then)
Call AggiornaMagazzino(“Disponibilita”)
End If
End Sub

In questo modo, è possibile eseguire il programma e verificare se l’errore di compilazione si è


spostato nella funzione o nella subroutine, il che restringe l’ambito di ricerca. Nel caso in cui le
parti di routine che vengono scorporate non abbiano uno scopo significativo, il tutto può essere
facilmente descritto nel nome che verrà assegnato alle nuove subroutine destinate a contenerle.
Per il nome da assegnare alle subroutine create per tali scopi, si può suggerire di utilizzare il
nome della routine principale seguita dal carattere underscore più un numero; in tal caso è
fortemente consigliabile aggiungere nella routine principale una serie di commenti che permettano
di comprendere il lavoro che le routine svolgono:
Sub AggiornaDisponibilitaSeNecessario()
‘ esegue il calcolo delle righe in cui il valore..
r = AggiornaDisponibilitaSeNecessario_1(“Disponibilita”)
if (r > 10 Then)
‘ aggiorna il foglio “Disponibilità” per..
Call
AggiornaDisponibilitaSeNecessario_
2(“Disponibilita”)
End If
End Sub

Meglio ancora, si può utilizzare il nome stesso della routine principale seguito da una
descrizione estremamente sintetica del lavoro che svolgono:
Sub AggiornaDisponibilitaSeNecessario()
r = _
AggiornaDisponibilitaSeNecessario_ContaRighe(“Disponibilita”)
if (r > 10 Then)
Call _
AggiornaDisponibilitaSeNecessario_Aggiorna(“Disponibilita”)
End If
End Sub

Per evitare l’eccessiva proliferazione di nomi di routine e funzioni che possono inutilmente
invadere la finestra Macro o Funzioni di Excel, oppure rendere difficile comprendere quali sono
direttamente richiamabili e quali invece esistono solo come supporto per altre, si consiglia
vivamente di ricorrere alla parola chiave Private, che precederà Sub o Function, rendendole così
visibili solo all’interno del modulo in cui sono contenute e, quindi, non nelle finestre.

Errori di esecuzione o di runtime


Gli errori sintattici vengono sempre individuati da Visual Basic Editor nel momento stesso in
cui si sta scrivendo l’istruzione, mentre gli errori formali vengono segnalati quando si richiede
l’esecuzione di un programma.
Gli errori di esecuzione rappresentano il vero problema dei programmatori perché appaiono
solo durante l’esecuzione del programma e, aspetto ancor più problematico, solo in determinate
circostanze o, addirittura, saltuariamente.
La causa principale degli errori di esecuzione è l’utente stesso; per esempio, egli può inserire
una lettera in una casella di testo in cui viene richiesta la digitazione di un valore numerico. Questo
costringe i programmatori a porsi una semplice, ma altrettanto sostanziale, domanda: quali sono le
competenze informatiche di chi utilizzerà questo programma? La risposta permette di definire il
livello di cura e attenzione per la prevenzione degli errori. Se il programma è destinato ai
cosiddetti utenti evoluti (power user), essi non saranno terrorizzati trovandosi faccia a faccia con
una finestra di Visual Basic che comunica l’errore in una macro.
Situazione completamente differente per gli utenti poco esperti, che potrebbero reagire in
diversi modi come cercare di forzare in qualche modo la situazione, chiamare qualcuno che possa
essere d’aiuto, spegnere il computer, telefonare all’assistenza della Microsoft chiedendo loro
spiegazioni di tale anomalia di Excel o anche solo adirarsi con il programmatore.
Come si può gestire l’errore? Esistono due approcci diversi, che dovrebbero essere applicati
congiuntamente, e sono i seguenti:
la programmazione difensiva;
la programmazione correttiva.
La prima si basa sull’introduzione di una serie di test, mentre la seconda utilizza istruzioni
apposite finalizzate alla gestione degli errori, evitando l’apparire della finestra di Visual Basic.

Precedere gli errori


Potrebbe apparire come ovvio e scontato, ma è uno dei capisaldi di un buon programma: il
sistema migliore per curare gli errori consiste nel prevenirli.
Prevenire un errore significa inserire istruzioni che eseguano verifiche e analisi sui dati o
sull’ambiente: in pratica si traduce con lo scrivere istruzioni inutili rispetto all’obiettivo del
programma, con un aumento della sua complessità.
Riprendendo la forma estesa della routine EsempioDivisione1, apparsa all’inizio del capitolo, si può
dire che essa non presenta gli errori seguenti:
sintattico (tutte le istruzioni sono scritte correttamente);
di compilazione (non vi sono errori tra le istruzioni o conflitti con altre routine);
di esecuzione (digitando i valori 100 e 20 si ottiene il risultato atteso senza inconvenienti).
Tale routine ottiene perfettamente ciò che si è ripromessa, ovvero visualizzare il risultato di una
divisione. Può accadere, però, che l’utente digiti nella seconda finestra InputBox il valore 0: un
numero fratto zero genera come risultato un valore infinito, che Visual Basic non gestisce, e una
segnalazione d’errore.
Per evitare che il programma arresti la propria esecuzione con una finestra di errore è
sufficiente applicare una piccola precauzione, ovvero verificare se il valore del divisore è diverso
da zero. Essa si traduce in un’istruzione If da inserire prima dell’esecuzione dei calcoli:
Sub EsempioDivisione2()
Dim divisore, dividendo As Double

dividendo = InputBox(“Digitare il divisore”)


divisore = InputBox(“Digitare il dividendo”)

If divisore <> 0 Then


MsgBox dividendo & “/” & divisore & “=” & dividendo /
_divisore

Else
MsgBox “impossibile eseguire divisioni per zero”
End If
End Sub

Esiste ancora la possibilità che si verifichi un problema se non viene introdotto un valore
numerico, allora l’assegnazione di quanto digitato dall’utente a una variabile di tipo numerico
genererà un messaggio di errore (Figura 11.8).

Figura 11.8 Viene generato un errore, se InputBox riceve un valore testuale da assegnare a una variabile di tipo numerico.

Per ovviare a questo inconveniente è necessario introdurre un sistema di controllo su quanto la


funzione InputBox restituisce, prima di assegnarlo alla variabile:
Sub EsempioDivisione3()
Dim divisore, dividendo As Double
Dim str As String

str = InputBox(“Digitare il dividendo”)


If Not IsNumeric(str) Then
GoTo ErroreTipoNonNumerico
Else
dividendo = str
End If

str = InputBox(“Digitare il divisore”)


If Not IsNumeric(str) Then
GoTo ErroreTipoNonNumerico
Else
divisore = str
End If

If divisore = 0 Then GoTo ErroreDivisoreUgualeAZero

MsgBox dividendo & “/” & divisore & “=” & dividendo / _
divisore

Fine:
Exit Sub
ErroreTipoNonNumerico:
MsgBox “Non è stato immesso un numero”
GoTo Fine:

ErroreDivisoreUgualeAZero:
MsgBox “Impossibile eseguire divisioni per zero”
GoTo Fine:
End Sub

contiene alcuni aspetti, già illustrati nei capitoli precedenti, che meritano di
EsempioDivisione3

essere commentati seguendo il flusso del programma.


Viene introdotta un’altra variabile di nome Tmp di tipo String, ovvero dello stesso tipo che
restituisce la funzione InputBox.
Il valore di InputBox viene assegnato alla variabile Tmp, per la congruenza di tipo. Qualunque
sia il valore digitato dall’utente non potrà causare errori nell’assegnazione.
La variabile Str, analizzata mediante la funzione IsNumeric(), restituisce il valore True se il
valore di Str può essere convertito in un numero senza errore, altrimenti False.
Il risultato del test IsNumeric(Str) è utilizzato direttamente in una If: se è True, provvede a
eseguire la conversione e assegna il risultato alla variabile numerica, altrimenti viene
eseguito un Go-To all’etichetta ErroreTipoNonNumerico.
Prima di effettuare la divisione viene analizzato il valore del divisore, che non deve essere
uguale a zero, affinché l’elaborazione proceda correttamente; in caso contrario, una If
provvede a deviare il flusso verso l’etichetta ErroreDivisoreUgualeAZero.
La funzione MsgBox visualizza il risultato della divisione e vengono eseguite le successive
istruzioni, ovvero un’etichetta e l’Exit Sub.

NOTA Quando il flusso del programma incontra un’etichetta non accade nulla, perché essa è solamente il punto di
riferimento a cui andare per le istruzioni GoTo.

Degne di particolare nota sono le ultime istruzioni, che vengono eseguite solo nei casi in cui il
programma abbia aggirato una situazione che avrebbe causato un errore:
ErroreTipoNonNumerico:
MsgBox “Non è stato immesso un numero”
GoTo Fine:

ErroreDivisoreUgualeAZero:
MsgBox “impossibile eseguire divisioni per zero”
GoTo Fine:

Esse provvedono a visualizzare una descrizione del problema mediante la funzione InputBox e,
anziché terminare l’esecuzione della routine mediante l’istruzione Exit Sub, la fanno continuare
dall’etichetta Fine. Tecnicamente si poteva procedere anche nel modo seguente:
sostituire la prima istruzione GoTo Fine con una Exit Sub;
eliminare la seconda istruzione GoTo Fine.
Si ottiene così, anche se è sconsigliabile scegliere questa soluzione, un risultato perfettamente
identico a quello ottenuto con EsempioDivisione3:
ErroreTipoNonNumerico:
MsgBox “Non è stato immesso un numero”
Exit Sub

ErroreDivisoreUgualeAZero:
MsgBox “impossibile eseguire divisioni per zero”
End Sub

Se alla fine delle istruzioni deputate a essere eseguite, quando vengono scoperte potenziali
situazioni di errore, viene inserito sempre un GoTo verso un punto terminale della routine, si
possono ottenere i vantaggi elencati di seguito.
Diventa sempre possibile eseguire operazioni alla fine della routine come, per esempio,
chiudere una cartella che era stata aperta per le operazioni da compiere.
Si riduce il rischio di dimenticare di introdurre un GoTo quando vengono inserite nuove
istruzioni prima della End Sub, per la gestione di altre situazioni di rischio; in caso contrario,
quando viene eseguito il penultimo gruppo di istruzioni, verrà eseguito anche l’ultimo.
Dalla routine EsempioDivisione3 vengono riprese le ultime istruzioni, opportunamente modificate
per mostrare la forma in cui l’errore può presentarsi. Esso è abbastanza visibile dato l’esiguo
numero di istruzioni presenti:
ErroreTipoNonNumerico:
MsgBox “Non è stato immesso un numero”
ErroreDivisoreUgualeAZero:
MsgBox “impossibile eseguire divisioni per zero”
GoTo Fine:
End Sub

il programma risulta strutturato in modo omogeneo e chiaro.


È importante comprendere il costo della prevenzione; guardando la routine EsempioDivisione3 e
confrontandola con EsempioDivisione1, il concetto è molto chiaro: la stessa routine, composta da una
singola istruzione, si è ingigantita fino a sfiorare le trenta istruzioni.
Questo significa che non è necessario inserire controlli per tutti i potenziali rischi, ma solo per
quelli che compromettono l’insieme del lavoro o hanno un’alta probabilità di manifestarsi. Per
esempio, ha senso gestire il rischio di trovare il disco fisso senza spazio disponibile per creare un
nuovo foglio di lavoro all’interno di una cartella? Forse, ma attualmente la probabilità che il
programma si imbatta in una situazione del genere è abbastanza remota.
Se il programma chiede all’utente di indicare il percorso nel quale memorizzare il risultato
dell’elaborazione, che per portare a termine il proprio lavoro impiega molti minuti, ha senso
gestire il rischio che nel frattempo la cartella di destinazione sia stata rimossa o sia stato spento il
computer di rete sul quale risiede? La serie di domande più o meno legate alle problematiche
quotidiane potrebbe occupare troppe pagine; quello che conta è bilanciare lo sforzo di
programmazione, che serve a ottenere programmi poco vulnerabili, con i danni che possono essere
prodotti da un errore non gestito.
Funzioni Is…()
Per riuscire a identificare alcune caratteristiche del valore di una variabile, al fine di evitare
che si generino errori di esecuzione, Visual Basic fornisce una serie di funzioni che restituiscono
un valore booleano. Esse sono riepilogate nella tabella seguente.
Funzione Controlla se
IsArray(Nome) il nome della variabile è una matrice.
IsDate(Nome) il nome della variabile è di tipo Date.
IsEmpty(Nome) è stato assegnato un valore alla variabile.
IsError(Err) Err contiene un numero identificativo di errore.
IsMissing(Nome) nella chiamata della subroutine o funzione corrente è stato omesso un parametro opzionale.
IsNull(Nome) la variabile contiene il valore Null.

IsNumeric(Nome)
il valore della variabile è di tipo numerico o può essere anche convertito in tipo numerico senza
errori.
IsObject(Nome) la variabile è di tipo Object.

Alcune di queste funzioni ricorrono al concetto di vuoto, o assenza di valore, che viene indicato
mediante le costanti descritte di seguito:
Empty, alla variabile non è ancora stato assegnato nessun valore;
Null, la variabile non contiene un valore ma lo ha avuto.

I test IsEmpty() e IsNull() sono significativi solo in presenza di variabili di tipo Variant.
NOTA L’utilizzo del valore Null può essere fonte di sorprese apparentemente incomprensibili, perché ogni test su
di esso restituisce False in quanto la sua presenza rende l’intero test nullo, quindi non vero.

Il debugging
Il debugging è la fase in cui il programma può essere compilato ed eseguito per verificarne il
comportamento, eliminando difetti o errori.
Generalmente, il tempo che richiede è di difficile stima, dato che giocano diversi fattori come
quelli descritti di seguito:
l’efficienza e la flessibilità degli strumenti utilizzati;
l’esperienza del programmatore con il linguaggio;
l’esperienza del programmatore e le tematiche con cui opererà il software;
la dimensione del programma in termini di moduli e numero di linee;
la facilità e velocità nel disporre i dati che devono essere utilizzati per il test.
Visual Basic Editor contiene diversi strumenti per il debugging, i quali gravitano principalmente
intorno al principio del punto di interruzione.
Prima di tutto, però, è utile conoscere due informazioni fondamentali.
Se il pulsante Microsoft Visual Basic scompare dalla barra delle applicazioni di Windows è
possibile che un programma VBA abbia aperto una finestra di dialogo, visibile in Excel, che
non è stata chiusa.
Se Visual Basic Editor non permette di interagire con il programma, emettendo un beep ogni
qualvolta si fa clic sulla finestra, oppure quando viene premuto un tasto, bisogna controllare
se Excel è nella modalità Pronto, il che è determinabile osservando la barra che appare sul
bordo inferiore della finestra.
Questi piccoli suggerimenti possono semplificare la vita per chi inizia a cimentarsi con Visual
Basic Editor e il debugger.

Il punto di interruzione
Il punto di interruzione (break point) è un’istruzione che viene contrassegnata affinché il
programma sospenda la propria esecuzione quando la incontra. Permette di compiere varie
operazioni tra le quali:
verificare il contenuto delle variabili;
analizzare quali routine o funzioni si sono succedute nelle chiamate fino a giungere a quella
corrente;
analizzare il contenuto delle proprietà di oggetti.
Inoltre, permette di eseguire attività quali:
modificare il valore di una variabile;
modificare il contenuto delle proprietà di oggetti;
impostare un’istruzione dalla quale riprendere l’esecuzione.

Impostare e rimuovere il punto di interruzione


L’impostazione di un punto di interruzione comunica a Visual Basic Editor che, prima di
eseguire una determinata istruzione, deve effettuare una sospensione per consentire al
programmatore di agire.
L’impostazione avviene nei modi seguenti:
posizionando il cursore sulla riga contenente l’istruzione da contrassegnare;
contrassegnandola seguendo il percorso Debug/Imposta/rimuovi punto di interruzione.
Un pallino rosso scuro apparirà nella colonna grigia presente sul lato sinistro della finestra
Codice e l’intera istruzione risulterà colorata con uno sfondo rosso. Per rimuoverla si procede in
maniera identica (Figura 11.9).
Non tutte le istruzioni possono avere un punto di interruzione, per esempio l’istruzione Dim. Se si
rendesse indispensabile collocare un punto di interruzione su di essa, sarà necessario accontentarsi
di marcare quella precedente o successiva. Il risultato è identico.

Figura 11.9 Come appare un punto d’interruzione impostato su un’istruzione che occupa più righe.

NOTA Per accelerare la definizione dei punti di interruzione si può fare clic sulla barra laterale grigia in
corrispondenza dell’istruzione. Quando il programma raggiunge un’istruzione contrassegnata con un punto di
interruzione, l’esecuzione si arresta prima di eseguirla, in modo da permettere al programmatore di verificare ciò
che ritiene importante. L’istruzione che sarà eseguita appare contraddistinta, oltre che dal pallino rosso, anche da
una freccia gialla e il suo sfondo sarà giallo e rosso.

Interrompere l’esecuzione: Ctrl+Bloc Scorr


Alternativamente ai punti di interruzione, è possibile ricorrere, per le emergenze, alla
combinazione di tasti Ctrl+Bloc Scorr, soprattutto quando è attivo un ciclo che, per errore, è stato
scritto in modo da non avere mai termine; per esempio, la seguente routine contiene un loop
infinito:
Sub EsempioLoopInfinito()
Dim a

While True
a = 123456
Wend
End Sub

Riprendere l’esecuzione normale


Dopo aver svolto tutte le operazioni ritenute utili, il programmatore può decidere di proseguire
l’elaborazione e in tal caso utilizza il pulsante Continua presente sulla barra degli strumenti Debug
(Figura 11.10).
Figura 11.10 La barra degli strumenti Debug con il pulsante Continua.

L’elaborazione continuerà fino a che non si verificheranno i casi seguenti:


termine del programma;
un punto d’interruzione;
un errore;
un blocco causato dall’utente/programmatore mediante i tasti Ctrl+Bloc Scorr.

Riprendere l’esecuzione passo-passo


In alternativa alla ripresa della normale esecuzione, è possibile proseguire applicando una sola
istruzione per volta.
Praticamente questa modalità, detta “passo-passo” (o step by step), corrisponde all’inserimento
di un punto di interruzione su ogni istruzione. Per avanzare di una nuova riga si utilizza:
il percorso Debug/Esegui istruzione;
il tasto F8.
Questo sistema è utile per vedere i valori che le variabili acquisiscono o quali strade prende il
flusso del programma, per comprendere se accadono cose diverse da quelle desiderate.
Un aspetto importante da conoscere, per quanto riguarda questa modalità, consiste nella
possibilità di scegliere se essa debba essere estesa o meno anche alle funzioni e subroutine
richiamate dalla routine corrente.
Per eseguire l’istruzione corrente si utilizzano i tasti descritti nell’elenco che segue.
Il tasto F8 oppure il comando Debug/Esegui istruzione, per estendere la modalità passo-passo
anche alle chiamate.
Maiuscolo F8 oppure il percorso Debug/Esegui istruzione/routine, in modo che la modalità
passo-passo non venga applicata nell’esecuzione delle routine o nelle funzioni chiamate:
ovviamente, se esse contengono un punto di interruzione l’esecuzione verrà sospesa in questa
posizione.
A essi si aggiungono due sistemi per fare in modo che l’esecuzione proceda in modalità
normale, ottenendo due diversi risultati.
Giungere alla fine della routine corrente. Utilizzando il percorso Debug/Esci da
istruzione/routine, riprende l’esecuzione normale fino ad arrivare al termine della routine
corrente e ritornare a quella chiamante per riprendere la modalità passo-passo.
Giungere a un punto preciso. Ricorrendo al comando Esegui fino al cursore è possibile
impostare la linea sulla quale è presente il cursore come il punto in cui l’esecuzione dovrà
essere sospesa. Essa, però, sarà raggiunta mediante la normale elaborazione, salvo incontrare
punti di interruzione prima di giungervi.
Quando l’esecuzione passo-passo non è più necessaria, è possibile riprendere l’esecuzione
normale.

Analizzare o impostare il valore delle variabili o proprietà


Quando il programma viene sospeso, è possibile analizzare il valore delle variabili o delle
proprietà. Per fare questo esistono diversi sistemi.
Il primo consiste nell’utilizzare la finestra Variabili locali che si apre con il menu Visualizza e
permette di vedere:
tutte le variabili locali, ovvero tutte le variabili dichiarate nella routine corrente;
il loro valore;
il loro tipo.
Il secondo metodo consiste nel selezionare il percorso Visualizza/Finestra Immediata e aprire la
finestra Immediata, che permette di svolgere numerosi compiti quali, per esempio, i seguenti
(Figure 11.11 e 11.13):
visualizzare il valore di una variabile, di una proprietà o di un’espressione utilizzando il
comando Print;
richiamare funzioni o subroutine;
eseguire test;
modificare il valore di una variabile o proprietà assegnando un valore;
eseguire un ciclo contenente istruzioni ricorrendo a una sola riga, suddividendo le istruzioni
con il carattere due punti.
Le possibilità sono realmente sorprendenti e solo utilizzandole si può comprendere appieno
quanto siano comode e flessibili. Se si tenta un’operazione non lecita, Visual Basic Editor lo
segnalerà con un’apposita finestra. Un terzo sistema consiste nel posizionare il puntatore del
mouse su una variabile: il valore apparirà sotto di esso, all’interno di un riquadro giallo.
Figura 11.11 Esempi d’uso della finestra Immediata. Si noti il richiamo di una subroutine e il ciclo.

NOTA Se si cerca di visualizzare il valore di una variabile inesistente mediante il metodo Print, VBA non segnalerà
errore; per questo motivo è utile fare attenzione a come si è digitato il nome se il risultato è una riga vuota. In
alternativa, è utile ricorrere al completamento automatico del nome utilizzando i tasti Ctrl premuti
contemporaneamente alla barra spaziatrice.

Il quarto sistema utilizza la finestra Variabili locali nella quale si può inserire il nome di una
variabile o di un’espressione per visualizzarne il valore (Figura 11.12).

Figura 11.12 La finestra Variabili locali mostra le variabili dichiarate nella routine corrente. Si noti il pulsate posto a destra e
in altro raffigurante tre punti: esso permette di selezionare le routine chiamanti.

Figura 11.13 Esempi d’impiego della finestra Immediata.


Capitolo 12

Come interagire con celle, fogli e cartelle

In tutto il libro sono stati portati esempi nei quali si è cercato di fare uso degli oggetti più
importanti e specifici di Visual Basic per Excel, ovvero celle, fogli di lavoro e cartelle di lavoro:
essi dovrebbero risultare sufficientemente semplici per poter comprendere il loro funzionamento,
anche se non ne è stata data una spiegazione tecnica approfondita, ma per padroneggiarli bene è
necessaria una maggiore conoscenza.
Prima una precisazione: ogni proprietà o metodo riferito a uno di questi oggetti fa
automaticamente riferimento all’entità attiva. Per esempio:
agire su una cella indicandone solo le coordinate significa che essa appartiene al foglio di
lavoro corrente;
non definire a quale cartella appartiene il foglio cui si fa riferimento significa che esso si
trova nella cartella corrente.
Questi aspetti sono importanti per comprendere come operano i vari metodi in assenza di
indicazioni specifiche.

Terminologia
Di seguito si riportano i termini più usati nel corso della trattazione di questo argomento.
Coordinata: informazione relativa alla posizione di riga o di colonna di una cella. Per
individuare una cella è necessario l’uso congiunto di entrambe, ottenendo un Riferimento.
Riferimento: sistema attraverso il quale viene individuata la posizione di una cella nel foglio
di lavoro, oppure indicazione di un oggetto ottenuta attraverso una variabile di tipo Object (in
altri linguaggi prende il nome di puntatore).
Riferimento A1: sistema di riferimento, normalmente utilizzato da Excel, in cui ogni cella
viene indicata attraverso una lettera che ne identifica la colonna e un numero che ne identifica
la riga di posizionamento entro il foglio di lavoro.
Riferimento R1C1: sistema di riferimento alternativo in cui ogni cella viene indicata con una
coppia di numeri che ne identifica il numero di colonna e di riga rispettivamente, preceduti
dalle lettere R e C, iniziali di Riga e Colonna.
Intervallo: insieme di celle che occupa sul foglio un’area di forma rettangolare; viene
indicato riportando il riferimento di una coppia di celle poste sugli spigoli opposti, per
esempio A1:H5.

L’istruzione With
Un’istruzione molto utile quanto si parla di oggetti che possono richiedere l’applicazione
sequenziale di più proprietà e metodi è With/End With: tutte le istruzioni comprese all’interno del
suo blocco fanno implicitamente riferimento all’oggetto indicato in With. Per esempio:
With ActiveCell
.Borders.LineStyle = xlDouble
.Value = “Nuovo valore”
.Orientation = xlVertical
End With

Un’interessante proprietà di questa istruzione consente di annidare le istruzioni With/End With


all’interno di altre istruzioni dello stesso tipo; per esempio, è lecito questo frammento di codice:
Sub EsempioWithDoppia()
With ActiveCell
With .Font
.Bold = True
.Italic = True
.Name = “Arial”
End With

.Borders.LineStyle = xlDouble
.Value = “Nuovo valore”
.Orientation = xlVertical
End With
End Sub

NOTA La proprietà Orientation determina come il testo deve apparire all’interno della cella, similmente a quanto
viene definito dalla scheda Allineamento della finestra Celle, e accetta un valore di tipo Long; le principali costanti
per formattare la cella sono: xlDownward, xlHorizontal, xlUpward, xlVertical.

La cella
La cella è il componente base del foglio elettronico. Programma e utente devono poter agire su
essa liberamente, altrimenti vi sarebbero operazioni realizzabili solo manualmente. Per accedere
alla cella si utilizzano i seguenti due metodi:
Cells

Range

Essi si distinguono fondamentalmente per due aspetti:


Cells sfrutta un sistema di coordinate basato sul numero di riga e colonna e non permette di
indicare un intervallo di celle;
Range impiega il normale sistema composto dalla lettera della colonna e dal numero di riga,
cioé il sistema di riferimento A1, e consente di indicare anche intervalli di celle.
Per esempio, entrambe le seguenti istruzioni assegnano alla stessa cella il valore 123:
Range(“A1”).Value = 123
Cells(1,1). Value = 123

Proprietà e metodi comuni a Range e Cells


Sia Cells sia Range permettono di accedere a proprietà e metodi che hanno lo stesso nome e lo
stesso scopo e che verranno perciò trattati insieme.

Assegnare o acquisire un valore o una formula


Per inserire in una cella un valore, o per acquisirlo, si fa ricorso a diverse proprietà.
.Value assegna o acquisisce il valore contenuto in una cella:
Cells(1,1).Value = 1234
VarA = Cells(1,1).Value;

.Formula assegna alla cella una formula indicata attraverso l’abituale sistema di riferimento
Excel A1:
Cells(1, 1).Formula = “=A2+A3”;

.FormulaR1C1 assegna alla cella una formula indicata attraverso il sistema di riferimento
basato sul numero di riga e colonna, che verrà tramutato nel sistema A1 utilizzando i
riferimenti assoluti; la seguente istruzione inserisce nella cella A4 la formula =B1+C1:
Cells(4, 1). FormulaR1C1 = “=R1C2+R1C3”;

.Text restituisce una stringa con il valore contenuto nella cella rispettando la sua
formattazione, cioè la sua visualizzazione all’interno del foglio di lavoro; più precisamente,
Text differisce da Value perché non restituisce un valore di tipo Variant.

Attivare una cella


Per Excel la cella attiva è quella sulla quale è presente il cursore e che può ricevere l’input
dall’utente.
Per rendere attiva una cella, si ricorre al metodo Activate applicato all’oggetto Range. Per
esempio, la seguente istruzione provvede ad attivare la cella B2:
Range(“B2”).Activate

NOTA Può essere attiva una sola cella alla volta.

Il metodo Cells
Il metodo Cells permette di accedere a una cella utilizzando i suoi indici di riga e di colonna ed è
utile quando il programma deve agire su più celle mediante un ciclo: bastano due variabili di
controllo, una per ciascuna coordinata che individua la cella.
Il seguente esempio mostra come inserire il valore zero nelle celle poste nell’intervallo A1:H5:
Sub EsempioCells1A()
Dim r, c As Long

For r = 1 To 5
For c = 1 To 8
Cells(r, c).Value = 0
Next c
Next r
End Sub

Il metodo Range
Cells permette di accedere a una cella utilizzando due indici che indicano il suo numero di riga e
colonna.
Anche il metodo Range è molto utile quando il programma deve agire su più celle mediante un
ciclo, ma in questo caso è sufficiente una variabile di controllo per identificarle.
Il seguente esempio mostra come inserire il valore zero nelle celle poste nell’intervallo A1:H5,
analogamente a quanto svolto dalla routine EsempioCells1A:
Sub EsempioRange1A()
Dim cella
For Each cella In Range(“A1:H5”)
cella.Value = 1
Next cella
End Sub

In alternativa, sfruttando il concetto che la proprietà Range si può riferire a un insieme di celle,
si può concentrare tutto in un’unica istruzione, con enormi vantaggi di comprensibilità e poco
rischio di errori di scrittura rispetto alla forma proposta in EsempioRange1A:
Sub EsempioRange1B()
Range(“A1:H5”).Value = 0
End Sub

NOTA Range può essere utilizzato come tipo per una variabile, ricorrendo all’istruzione Dim.

Ottenere coordinate R1C1 da A1


Disponendo di un riferimento di tipo A1 è possibile utilizzare la proprietà Column per conoscere
l’equivalente numerico relativo alla coordinata della colonna: essa viene applicata a un oggetto di
tipo Range e restituisce un valore di tipo Long.
La seguente istruzione rappresenta un esempio d’impiego e restituisce il valore 6:
NumColn = Range(“F5”).Column

Discorso analogo per la proprietà Row, che restituisce la coordinata della riga:
NumRiga = Range(“F5”).Row

nel caso di questo esempio restituisce il valore 5.

Convertire manualmente un riferimento R1C1 in A1


Se si vuole utilizzare solo Range, anche nei casi in cui si opera con riferimenti di tipo R1C1 in
cui Cells è più appropriato, viene riportata di seguito una funzione che provvede a trasformare tale
riferimento nel formato A1; essa richiede come parametri il numero di riga e il numero di colonna,
che sono gli stessi che dovrebbero essere passati a Cells, e restituisce una stringa:
Function ConvRifR1C1RifA1(r As Integer, c As Integer) As _
String
Dim str As String

If c > 26 Then str = Chr$(Asc(“A”) + Int(c / 26) - 1)


str = str & Chr$(Asc(“A”) + c - (Int(c / 26) * 26) - 1)
ConvRifR1C1RifA1 = str & CStr(r)
End Function

Il risultato può essere utilizzato direttamente all’interno di Range: la seguente istruzione


inserisce l’orario corrente nella cella B5:
Range( ConvRifR1C1RifA1(5, 2) ).Value = Time

NOTA La funzione ConvRifR1C1RifA1 è complessa, ma interessante per studiare come si possa lavorare sulle
lettere utilizzando numeri per selezionare quelle desiderate dalla tabella Ascii.

Utilizzare i riferimenti R1C1 con Range


Benché Range non accetti i riferimenti di tipo R1C1, esiste una tecnica per aggirare tale
inconveniente; il seguente ciclo è l’equivalente della routine EsempioCells1:
Sub EsempioRange2()
Dim r, c As Long
For r = 1 To 5
For c = 1 To 8
Range(Cells(r, c), Cells(r, c)).Value = 1234
Next c
Next r
End Sub

Come si può osservare, al metodo Range vengono forniti due parametri, il cui valore viene
restituito da altrettante chiamate ai metodi Cells aventi gli stessi riferimenti.
Per esempio, se le variabili r e c contenessero rispettivamente i valori 2 e 3, Range otterrebbe il
seguente riferimento: “C2:C2”.
In queste situazioni è comunque consigliabile l’utilizzo del metodo Cells, che rende il loop
molto più chiaro.

Intervalli multipli o non contigui


Il metodo Range permette di ottenere in maniera semplice risultati particolarmente complessi,
impiegando sapientemente il concetto degli intervalli.
Per esempio, la maniera più semplice per cambiare il valore nelle celle poste nelle colonne da
A a G e nelle righe 1, 3, 5, 7 consiste nell’applicare quattro volte il metodo Range:
Range(“A1:G1”).Value = 12345678
Range(“A3:G3”).Value = 12345678
Range(“A5:G5”).Value = 12345678
Range(“A7:G7”).Value = 12345678
Sfruttando al massimo le proprietà di Range è possibile concentrare tutte queste istruzioni in una
sola, ricorrendo ai riferimenti su intervalli multipli.
In questo caso, anche se gli intervalli non sono contigui, è possibile scrivere la seguente
istruzione, che ottiene il medesimo risultato delle precedenti quattro:
Range(“A1:G1;A3:G3;A5:G5;A7:G7”).Value = 12345678

Per spaziare gli intervalli è sufficiente l’inserimento del carattere punto e virgola.
Ricorrendo poi agli spazi per separare gli intervalli tra loro, il risultato visivo diventa
decisamente migliore:
Range(“A1:G1 ; A3:G3 ; A5:G5 ; A7:G7”).Value = 12345678

NOTA È indispensabile porre la massima attenzione nell’inserire gli spazi all’interno delle stringhe in quanto
possono alterarne il significato; per esempio, non è ammessa la loro presenza tra le coordinate di un riferimento.

Simulare lo spostamento ottenibile con i tasti freccia


Lo spostamento sul foglio elettronico può avvenire utilizzando i tasti freccia: se vengono
premuti insieme al tasto Ctrl l’entità dello spostamento della cella attiva varierà in relazione alla
posizione della successiva cella vuota o non vuota presente nella direzione indicata dal tasto.
Visual Basic mette a disposizione una proprietà analoga che, invece di rendere attiva un’altra
cella, si limita a restituirne l’indirizzo: essa è End e accetta un valore numerico che può essere
sostituito dalle costanti di Excel elencate di seguito.
xlToLeft

xlToRight

xlUp

xlDown

La seguente istruzione ottiene lo stesso spostamento della cella attiva che si potrebbe ottenere
sul foglio mediante la pressione dei tasti Ctrl+destra:
ActiveCell.End(xlToRight).Select

Accedere al singolo carattere


Attraverso la proprietà Characters è possibile accedere ai singoli caratteri di una cella.
Il suo scopo principale consiste nel poter assegnare a essi formattazioni individuali, la sua
sintassi è analoga alla funzione Mid(), ovvero richiede due parametri:
il primo indica la posizione;
il secondo indica il numero di caratteri da considerare.
Per esempio, la seguente istruzione permette di assegnare la dimensione di 14 punti per i due
caratteri collocati dalla decima posizione della cella attiva in poi:
Activecell.Characters(10, 2).Font.Size = 14

La routine mostrata di seguito rappresenta un esempio decisamente più articolato dell’utilizzo


della proprietà Characters, infatti essa analizza tutte le celle della selezione e, per ognuna di esse,
provvede a cambiare le lettere con l’equivalente minuscolo, fatta eccezione per le iniziali:
Sub SoloInizialiMaiuscole()
Dim c
Dim str As String

‘ elabora tutte le celle


For Each c In Selection
Dim RendiMaiuscolo As Boolean
Dim p As Long

RendiMaiuscolo = True
‘ per tutta la lunghezza del valore della cella c...
For p = 1 To Len(c.Value)
‘se il p-esimo carattere e’ spazio...
If c.Characters(p,1).Text = “ “ Then
‘ non modificarlo, ma la prossima lettera va in
maiuscolo
‘perche’ e’ l’iniziale
RendiMaiuscolo = True
Else
‘ se deve rendere maiuscola questa lettera
If RendiMaiuscolo Then
‘ copia carattere maiuscolo
c.Characters(p, 1).Text = _
UCase(c.Characters(p,1).Text)
‘ la prossima non va più in maiuscolo
RendiMaiuscolo = False
Else
‘ copia carattere minuscolo
c.Characters(p, 1).Text = _
LCase(c.Characters(p, 1).Text)
End If
End If
Next p
Next c
End Sub

NOTA Nella routine SoloInizialiMaiuscole si può sostituire l’uso della proprietà Characters, ricorrendo a una
variabile di tipo String, e la proprietà Value, per acquisire il valore della cella e modificarlo a fine elaborazione.

La colonna e la riga
Le colonne e le righe di un foglio di lavoro possono venire utilizzate come oggetti all’interno di
Visual Basic, anche se le loro situazioni d’impiego sono poche.
La routine EsempioColumns esegue un ciclo per tutte le colonne del foglio di lavoro attivo e
modifica la larghezza di tutte le colonne, dimezzandola con la proprietà ColumnWidth:
Sub EsempioColumns()
Dim Cln

For Each Cln In ActiveSheet.Columns


Cln.ColumnWidth = Cln.ColumnWidth / 2
Next Cln
End Sub

La routine EsempioRows si comporta in maniera analoga alla precedente, agendo sulle righe
mediante la proprietà RowHeight:
Sub EsempioRows()
Dim Rw

For Each Rw In ActiveSheet.Rows


Rw.RowHeight = Rw.RowHeight / 2
Next Rw
End Sub

Per operare su un’intera colonna, o un’intera riga, indicando unicamente una cella appartenente
a essa, si possono utilizzare le seguenti proprietà.
EntireColumn, che applicata a una cella restituisce un oggetto di tipo Range nel cui intervallo
è compresa un’intera colonna. La seguente istruzione, per esempio, seleziona l’intera colonna
in cui si trova la cella attiva:
ActiveCell.EntireColumn.Select;

EntireRow, che applicata a una cella restituisce un oggetto di tipo Range nel cui intervallo è
compresa un’intera riga. La seguente istruzione, per esempio, seleziona l’intera riga nella
quale si trova la cella attiva:
ActiveCell.EntireRow.Select.

Il foglio di lavoro e la cartella


Il foglio di lavoro viene indicato in Visual Basic utilizzando l’oggetto WorkSheet, che
appartiene all’insieme Sheets, a sua volta contenuto in una cartella di lavoro il cui corrispondente
oggetto prende il nome di Workbook.
Per comprendere come utilizzare i diversi insiemi e oggetti si osservino le seguenti istruzioni
equivalenti, che visualizzano il nome del primo foglio presente nella cartella Esempio12.xls,
tenendo presente che:
le prime due istruzioni vogliono mostrare come indicare una cartella;
le successive due vogliono mostrare come indicare un foglio di lavoro.
MsgBox Workbooks.Item(2).Sheets.Item(1).Name
MsgBox
Workbooks.Item(“Esempio12.xls”).Sheets.Item(1).Name
MsgBox Workbooks(“Esempio12.xls”).Sheets(1).Name
MsgBox Workbooks(“Esempio12.xls”).Sheets(“Foglio01”).Name

NOTA La prima istruzione utilizza l’indice 2, in quanto il primo foglio è sempre Personal.xls, a meno che non sia
stato chiuso, e viene supposto che non ve ne siano altri aperti.

Per cercare di comprendere il perché di tante sintassi apparentemente differenti è utile


analizzarle singolarmente.
MsgBox Workbooks.Item(2).Sheets.Item(1).Name fa accesso nell’insieme Workbooks,
mediante la proprietà Item, al secondo oggetto, cioè il secondo foglio di lavoro aperto.
L’insieme Sheets contiene tutti i fogli di lavoro e i grafici della cartella e in esso viene
indicato il primo oggetto utilizzando di nuovo la proprietà Item.
MsgBox Workbooks.Item("Esempio12.xls").Sheets.Item( 1).Name è analogo al precedente
esempio, ma la cartella non viene selezionata in base alla sua posizione nell’insieme
Workbook, bensì attraverso il proprio nome.
con MsgBoxWorkbooks(“Esempio12.xls”).Sheets(1).Name, selezionata la cartella, viene
selezionato dall’insieme Sheets, cioè dal contenuto della cartella, il primo elemento.
con MsgBox Workbooks(“Esempio12.xls”).Sheets(“Foglio 01”).Name, selezionata la
cartella, viene selezionato dall’insieme Sheets l’elemento di nome “Foglio01”.
In pratica la proprietà Item può accettare sia il nome dell’oggetto desiderato, come il foglio di
lavoro o la cartella, sia un indice numerico, che determina la posizione dell’oggetto all’interno
dell’insieme cui appartiene.
Quando la parola chiave Item viene omessa, Visual Basic la considera implicita, quindi
l’indicazione Workbooks(“Esempio12.xls”) è equivalente a Workbooks.Item(“Esempio12.xls”).
Una volta compresa questa struttura, diventa molto semplice lavorare con gli oggetti e si può
approfondire il concetto di variabile di tipo Object applicata a essi; la seguente routine svolge lo
stesso lavoro delle precedenti quattro istruzioni, ma si avvale di una variabile per acquisire il
nome del foglio di lavoro:
Sub EsempioObjectSuCartelleEFogli()
Dim obj As Object

Set obj = Workbooks.Item(2).Sheets.Item(1)


MsgBox obj.Name

Set obj = Workbooks.Item(“Esempio12.xls”).Sheets.Item(1)


MsgBox obj.Name
Set obj = Workbooks(“Esempio12.xls”).Sheets(1)
MsgBox obj.Name
Set obj = Workbooks(“Esempio12.xls”).Sheets(“Foglio01”)
MsgBox obj.Name
End Sub

Come si può osservare, nell’istruzione di assegnazione di un valore alla variabile obj non viene
utilizzata anche la proprietà Name, che invece era presente nell’esempio delle quattro istruzioni
MsgBox: questo è dovuto al fatto che le variabili di tipo Object sono riferimenti agli oggetti,
mentre la proprietà Name avrebbe restituito una stringa con il nome dell’oggetto.

Gestire l’insieme dei fogli


Visual Basic mette a disposizione del programmatore una serie di metodi per manipolare
l’insieme dei fogli di lavoro: di seguito sono descritti con la spiegazione delle funzionalità.

Inserire un nuovo foglio di lavoro


Per creare un nuovo foglio di lavoro si utilizza la proprietà Add.
La seguente istruzione crea un nuovo foglio nella cartella attiva, assegnandogli il nome di
default ActiveWorkbook.Worksheets.Add.
È possibile anche indicare la collocazione del nuovo foglio rispetto a quelli già esistenti,
utilizzando uno dei seguenti parametri del metodo Add:
Before, il nuovo foglio precede quello indicato;
After, il nuovo foglio segue quello indicato.
Il nome del foglio di riferimento deve obbligatoriamente essere un oggetto di tipo Sheet, per
questo motivo si ricorre alla funzione omonima come illustrato dalla seguente istruzione:
ActiveWorkbook.Worksheets.Add after:= Sheets(“Foglio01”)

oppure:
ActiveWorkbook.Worksheets.Add after:= Worksheets(“Foglio01”)

dove viene implicitamente utilizzata la proprietà Item; la forma estesa sarebbe:


ActiveWorkbook.Worksheets.Add after:=
Worksheets.Item(“Foglio01”)

Di default, il nuovo foglio viene creato in una posizione precedente a quello corrente.
Per collocare il nuovo foglio in fondo alla cartella si ricorre alla proprietà Count, per calcolare
l’indice dell’ultimo foglio e creare il riferimento da passare nel parametro after, come qui di
seguito:
ActiveWorkbook.Worksheets.Add after:= Sheets(Sheets.Count)

NOTA Add supporta il parametro di nome Count, che è numerico e può servire a indicare il numero di fogli da
creare.

Eliminare un foglio
È possibile eliminare un foglio da una cartella ricorrendo al metodo Delete, che viene applicato
a un oggetto Sheet come nei seguenti esempi (Figura 12.1):
ActiveWorkbook.Worksheets(“Foglio01”).Delete
ActiveWorkbook.Sheets(“Foglio01”).Delete
Workbooks(“Esempio12.xls”). Sheets(“Foglio01”).Delete

Figura 12.1 Il metodo Delete apre una finestra che richiede conferma.

Attivare una cartella e un foglio di lavoro


Nel caso in cui tutte le operazioni pilotate da Visual Basic facciano riferimento implicito a un
determinato foglio di lavoro, è possibile renderlo attivo senza doverlo indicare in tutte le
istruzioni e, in seguito, utilizzare l’oggetto ActiveWorkbook che può essere utile anche in altri frangenti.
Per attivare un foglio si applica il metodo Activate all’oggetto Sheet che lo contiene, come nella
seguente istruzione che provvede a rendere attiva la cartella Esempio11 e il suo foglio di nome
“Foglio4”:
Workbooks(“esempio12.xls”).Activate
Sheets(“Foglio01”).Activate

Creare una nuova cartella di Excel


Attraverso Visual Basic è possibile creare una nuova cartella di lavoro vuota, con una modalità
che dovrebbe essere ormai intuibile:
Workbooks.Add

Il metodo Add applicato alle cartelle non accetta i parametri After e Before, come accade con i
fogli di lavoro: ogni nuova cartella viene semplicemente creata e le viene attribuito il nome di
default, costituito dalla parola Cartel seguita da un numero.
Ovviamente, per non perdere le informazioni inserite nella nuova cartella, è necessario salvarla
con il metodo SaveAs che può accettare diversi parametri, i più comuni e interessanti dei quali
vengono riportati di seguito:
FileName, nome con il quale la cartella verrà salvata;
Password, consente di indicare una password per limitare l’accesso alla cartella;
CreateBackup, a ogni successivo salvataggio Excel farà una copia di backup della cartella,
aggiornata al precedente salvataggio.
Sub EsempioCreaNuovaCartella()
Dim wb As Workbook

Set wb = Workbooks.Add
MsgBox “Creata nuova cartella di nome “ & wb.Name

wb.SaveAs Filename:=”EsempioDiCartellaCreataDaVBA”
End Sub

La selezione di celle
La selezione di celle può essere composta da una o più celle, raggruppate in uno o più intervalli
anche non contigui.
Per Visual Basic la selezione è un oggetto di tipo Range, che contiene i riferimenti agli intervalli
selezionati nei fogli di lavoro.
È importante dare risalto ai seguenti concetti:
la cella attiva è quella in cui è presente il cursore, quindi è pronta a ricevere l’input
dell’utente (è unica in ogni sessione di Excel ed esi-ste sempre);
la selezione esiste solo quando più celle vengono selezionate e comprende sempre la cella
attiva.
La selezione può essere utilizzata per agire su ogni singola cella; per esempio, il seguente ciclo
provvede a trasformare il contenuto di ogni cella da formula a valore:
Sub TrasformaFormulaInValore()
Dim c

For Each c In Selection


c.Value = c.Value
Next c
End Sub

Indubbiamente, a prima vista, questo ciclo apparirà alquanto strano, poiché l’istruzione al suo
interno sembra decisamente superflua, invece ottiene il risultato desiderato.
La spiegazione è relativamente semplice: la variabile c rappresenterà una cella diversa per ogni
ciclo e a essa verrà assegnato il valore ottenuto applicando la proprietà Value alla variabile c
stessa, che abbiamo detto essere una formula.
In pratica la variabile c assumerà il valore del risultato della formula in essa contenuta.
Se si fosse utilizzata l’istruzione:
c.Value = c.Formula

le celle contenenti formule sarebbero rimaste immodificate, in quanto sarebbe stata assegnata
loro la formula stessa, non il suo risultato.
NOTA Se non esiste nessuna selezione, Selection restituirà il valore Nothing.
Indice
Introduzione
Finalità
Convenzioni utilizzate nel libro
Capitolo 1 - Macro: un modo per dire “programma”
VBA: come iniziare con facilità
Prima di iniziare: impostare il livello di sicurezza
Avviare il registratore
Registrare la prima macro
Capitolo 2 - L’ambiente di Visual Basic Editor
Visual Basic Editor
I menu di Visual Basic Editor
Capitolo 3 - Macro e subroutine
Le macro create con il registratore
Le routine
Capitolo 4 - Tipi, variabili, matrici e costanti
Tipi di variabile
Variabili
Matrici o array
Le costanti
Capitolo 5 - Gli operatori
Operatori matematici
Operatore di assegnazione =
Operatori di confronto
Operatori logici
Concatenazione di stringhe
Priorità nell’ordine di valutazione
Capitolo 6 - Funzioni, routine e subroutine
Differenza tra funzione, routine e subroutine
Richiamare routine, subroutine e funzioni
Creare una nuova funzione
Parametri o argomenti
Le funzioni del foglio di lavoro
Restituire uno o più valori
Creare funzioni utilizzabili nel foglio di lavoro
Excel: le finestre Macro e Inserisci funzione
Capitolo 7 - Le funzioni native
Le funzioni del Visual Basic
Applicazione delle funzioni native di conversione
Applicazione delle funzioni native per date, orari e calendario
Applicazione delle funzioni native per le stringhe
Funzioni native per l’interazione con l’utente
Capitolo 8 - Esecuzione condizionale e ciclica delle istruzioni
Il flusso logico
Le condizioni
I cicli o loop
Uscire anticipatamente da Function, Sub o cicli
Capitolo 9 - Insiemi di oggetti
Proprietà, metodi, eventi ed ereditarietà: concetti
Gli oggetti di Excel
Font
Un esempio di iterazione con l’oggetto Selection
Capitolo 10 - Creare le finestre
Terminologia
I preliminari
L’aggiunta dei componenti
Navigare tra i componenti
Associare le routine ai componenti
Capitolo 11 - Gestione degli errori
Terminologia
Errori di compilazione e di esecuzione
Il debugging
Capitolo 12 - Come interagire con celle, fogli e cartelle
Terminologia
L’istruzione With
La cella
La colonna e la riga
Il foglio di lavoro e la cartella
La selezione di celle