Sei sulla pagina 1di 6

Cicli in Visual Basic for Application

Le strutture del programma che ripetono l'esecuzione di una o pi istruzioni sono chiamateCicli.Alcune
strutture per i cicli sono costruite in modo da venire eseguite un numero impostato di volte, e vengono
chiamatecicliadinterazionefissaaltritipi di strutture per i ciclivengono impostate un numerovariabile di
voltesullabasedialcunecondizioniimpostateproprioperchilnumerodiripetizionidiquestestrutturenon
definitoquesticiclivengonochiamaticicliadinterazioneindefinita.Sianellestruttureadinterazionefissa
chenellestruttureadinterazioneindefinita,cisonoalcuneespressionichedeterminanoquantevolteilciclo
vieneripetuto.Questaespressionevienechiamatadeterminantedelciclo.Inuncicloadinterazionefissa
quasisempreunaespressionenumerica,mentrepericicliainterazioneindefinitaladeterminantedelciclo
solitamente un'espressione logica che descrive la condizione sotto la quale il ciclo pu continuare o
interromperelasuaesecuzione.Praticamentevengonousatedelleespressionilogicheperladeterminante
deicicliallostessomodoincuisonostateusateperprenderedelledecisioniinVBAcheabbiamovistonella
lezioneprecedente.Cisarebberoaltriaspettidaspiegaresuquantoesposto,maliritengopuramenteteorici,
pertanto possiamo andare avanti con l'esposizione delle parole chiave usate e con qualche esempio, nel
prosieguodellalezioneritorneremosuquestoargomentodicostruzionedeiciclierisulterpifacilecapirne
lalogicadioperaredopoavernevistoqualcheesempio.
LapisemplicestrutturapericicliquellaadinterazionefissaVBAnefornisceduediversetipologiechevengono espresse
cosFor ...NexteFor ...Each ... Next entrambi i cicli vengono chiamati cicliForperch vengono eseguiti per uno specifico
numerodivolte.IlcicloFor...Nexthalaseguentesintassi:

For contatore = inizio To fine


istruzioni
Next contatore

contatorevienerappresentatodaunaqualsiasivariabilenumerica
inizioanch'essorappresentatodaunavariabilenumericaespecificailvaloreinizialeperla
variabilecontatore
fineunaespressionenumericacherappresentailvalorefinaleperlavariabilecontatoreper
defaultVBAincrementalavariabilecontatoredi1ognivoltacheesegueleistruzionidiunciclo
NextindicaaVBAchestataraggiuntalafinedelciclo,inoltrelavariabilecontatoredeveesserela
stessacheabbiamomessoappenadopol'enunciatoFor.

Possiamo per anche specificare un valore diverso per l'incremento del contatore includendo la parola
chiaveStep[opzionale], in questo caso dobbiamo specificare l'incremento della variabilecontatore, e la
sintassidiventacos:

For contatore = inizio To fine Step passo


istruzioni
Next contatore
In questo caso l'espressionepassoviene rappresentato da una espressione numerica e indica la quantit
perincrementarelavariabilecontatore.Vediamoqualcheesempio:

Sub for_semplice()
For I = 1 To 10
MsgBox (I)
Next I
End Sub
L'esecuzionediquestocodiceciportaavideolafinestradimessaggio(MsgBox)per10volteconilvalore
dellavariabileI(contatore)eciapparecos :

se invece vogliamo usare la parola chiaveStepe far apparire solo le espressioni dispari possiamo
modificareillistatoinquestomodo:

Sub for_step()
For I = 1 To 10 Step 2
MsgBox (I)
Next I
End Sub
vedremmocomparireilmessaggiodiavvisoconisolivaloridisparidellavariabile

cosaabbiamofattoconStep?Abbiamomodificatol'incrementodellavariabileda1(didefault)a2,inpratica
allaprimaesecuzionedelcicloIvale1, maquandoincontralaparolachiaveStepvieneincrementatadi2.
Se scaricate l'esempio allegato noterete che al primo ciclo viene stampato il valore 1, questo
perchIquandoincontralaparolachiaveStep valeancora1,percambiarevaloredevearrivareallaparola
chiaveNext(che abbiamo detto essere quella che avvisa di essere arrivati alla fine del ciclo e che
incrementalavariabile).Inultimaanalisil'enunciatoForvieneinterpretatocos:ForI[PerI]=1To10[che
v da 1 a 10]Step 2[incrementa di 2],Esegui le istruzioni,Next I[incrementa il valore di I].
IlcicloFor..Nexthalaflessibilitdipoterincrementareedecrementarelavariabile,possiamomodificareil
listato daFor I = 1 To 10 Step 2aFor I = 100 To 1 Step 2pertanto le possibilit di impiego sono
abbastanza vaste: possiamo eseguire somme, incrementare e decrementare il valore delle variabili,
utilizzarelaciclicitperognibisognocherichiedailnostroprogrammafermorestandoiprincipidiimpiego
espostiall'inizio.
Esisteancheun'altraformadicicloedilcicloForEach..Nextadessoprematuroaffrontarel'argomento,
pi avanti quando avremmo visto le matrici ed altri elementi ritorneremo sull'argomento comunque si
esprimeinquestaforma

For Each elemento In gruppo


Istruzioni
Next [elemento]
moltobrevementepossiamodescriverecosl'enunciato:

elementounavariabileusataperinterareilciclo(allostessomodocheabbiamovistosopra)
gruppounacollezionedioggettiounvettore(matrice)

QuestotipodiciclohamenoopzionidelcicloForNextl'incrementodelcontatorenonrilevanteinquesto
ciclo, perch viene sempre eseguito tante volte quanti sono gli elementi presenti nel gruppo specificato.
Perilmomentotralasciamoloevediamounaltrometodomoltopiversatile:ilcicloDoLoop.
Abbiamo parlato all'inizio di due tipi di cicli, quelli adinterazione fissae quelli ad interazione indefinita: il
cicloDo..Loopappartieneaicicliadinterazioneindefinita.

VBAciforniscequestaistruzioneestremamentepotentepercostruirestruttureciclicheindefinitenellenostre
funzionioprocedure.Essenzialmentecostituitadaunasingolaistruzione:Do.Questaistruzionehamolte
opzioniedtalmenteflessibilecheciforniscequattrodiversepossibilitpercostruiredeicicliraggruppatiin
due diverse categorie di base, che sono icicli controllati da un contatoree icicli controllati da eventi.
Qualeladifferenza?
In un ciclo controllato da un contatore, le istruzioni del corpo del ciclovengono eseguitefinche ilvalore
inferiore o superiore al limite specificato, in sostanza non varia molto dal ciclo For ..Next, eccetto che
ilprogrammatore direttamente responsabile per l'inizializzazione della variabile contatore e per
l'incremento o il decremento del contatore. Potremmo usare il ciclo Do se il passo del contatore non
regolare o se non c' modo di determinare il limite finale se non dopo che il ciclo ha iniziato la sua
esecuzione.
Peresempiosevogliamospostarciattraverso15righediunfoglio,alcunevolteavanzandodiunasolariga
e altre volte avanzando di due righe, poich il numero di righe da avanzare (cio il passo del contatore)
cambia,nonpossiamousareilcicloFor..NextmadobbiamousareilcicloDo.
Periciclicontrollatidaeventi,leistruzionivengonoeseguitequandoladeterminantedelciclodiventaverao
falsasullabasedialcunieventichesiverificanoall'internodelcorpodelciclo.
Per esempio potremmo scrivere un ciclo che viene eseguito indefinitamente fino a quando l'utente non
inserisceunparticolarevaloreinunafinestradidialogoinput,el'inserimentodiquestoparticolarevalore
l'eventocheterminailciclooppurepossiamoeseguiredelleoperazionisullecellediunfogliofinoaquando
non si raggiunge lacellavuota di una colonna, anche in questo caso il raggiungimento della cellavuota
l'eventocheterminailciclo.Peroraabbiamochiaritoleduecategoriedicicli,abbiamocapitocheesistono
ciclicontrollatidauncontatoreeciclicontrollatidaeventi,vediamooralasintassi:

Do
istruzioni
Loop Until condizione
equalcheesempio:

Sub ciclo1()
Dim a As Integer
Do
a=a+1
MsgBox (a)
Loop Until a = 10
End Sub
Questo un ciclo controllato da un contatore, noterete che c' poca differenza dal cicloFor ..Next,infatti
otteniamolostessoeffetto,cioportiamoavideounmessaggiocolvaloredellavariabilefinchnonarrivaa
10, ma abbiamo visto poco sopra che abbiamo quattro diverse possibilit di costruire cicli divisi in due
categorie.
Oralecategorieleabbiamoviste(ciclicontrollatidauncontatoreeiciclicontrollatidaeventi)vediamoorai
quattro modi di costruire un ciclo, il listato sopra esposto un metodo, vediamo ora gli altri e dopo li
commentiamoassieme:

Sub ciclo2()
Dim a As Integer
Do Until a = 10
a=a+1
MsgBox (a)
Loop
End Sub
Sub ciclo3()
Dim a As Integer
Do
a = a +1

MsgBox (a)
Loop While a <> 10
End Sub
Sub ciclo4()
Dim a As Integer
Do While a <> 10
a=a+1
MsgBox (a)
Loop
End Sub
Comepotetevedereladifferenzastanell'enunciatoinblu,ilrisultatononcambiamaleparolechiaveela
lorocollocazionesi.
Vediamocomevieneinterpretatol'enunciato:DoUntila=10[Ripetifincha=10],oppureDoWhilea<>
10[Ripeti finch a diverso da 10], in questi 2 casi la differenza fondamentale che viene verificata la
condizione determinanteprimache venga eseguito il ciclo, infattise a fosse uguale a 20il ciclo non
verrebbeeseguito.
Gli altri 2 metodiDo ......Loop While a <> 10eDo ......Loop Until a = 10 vengono interpretati come
spiegatosopra,maladeterminatedelciclovieneverificataallafinedelciclo.
InpraticalaformaDo...LoopWhileeDo...LoopUntilprimavengonoeseguiteleistruzionipresentinel
ciclo e poi quando raggiunge la parola chiaveLoop viene verificata la condizione (vedi sintassi) se
condizione Falsenel caso si usiUntilVBA ritorna all'inizio del ciclo ed esegue nuovamente leistruzioni
delciclo,seinveceusiamolaformaWhilelacondizionedaverificaredeveessereTrue, mentrenellealtre2
formeespresseDoUntil...LoopeDoWhile...Looplacondizioneinvecevieneverificatasubito.
Vediamounesempiochesemplificaechiarificaquantoesposto.
SupponiamodifarcomparireavideounInputboxperchiedereinformazioni all'utente,epoiverificaresei
dati immessi siano validi, in questo caso inseriamo nel nostro ciclo le istruzioni per far comparire il
messaggio di Input e all'inserimento dei dati da parte dell'utente verifichiamo la condizione il listato si
presentacos:

Sub esempio1()
Dim pass As String
Do
pass = InputBox(prompt:="Inserisci password: ",Title:="Controllo accessi")
Loop Until pass = "AAA"
MsgBox "Password esatta", vbInformation + vbYes, Verifica Password"
End Sub
Seproviamoquestocodicevedremmocheilciclocontinuaaripetereleistruzionifinchnonvienedigitatala
password esatta ma se vogliamo uscire perch non ricordiamo la password? Anche premendo sul tasto
"Annulla"dell'Inputboxleistruzionicontinuanoadessereripetutelostesso.
Conviene allora porre una condizione per evitare di proseguire, ma al tempo stesso controllare che
l'esecuzione del ciclo avvenga correttamente in pratica mettiamo l'utente in grado di uscire da un ciclo
senzapercheevitidiinserirelapasswordrichiesta.Modifichiamoalloraillistatoinquestomodo:

Sub esempio2()
Dim pass As String
Do
pass = InputBox(prompt:="Inserisci password: ", Title:="Controllo accessi")
If pass <> "AAA" Then Exit Sub
Loop Until pass = "AAA"
MsgBox "Password esatta ", vbInformation + vbYes, "Verifica Password"
End Sub
Inserendolarigadicodiceinbluabbiamopostounacondizione,cio"Sepassdiversoda"AAA"escidalla

sub" attenzione! che esci dalla sub non vuol dire proseguire, ma semplicemente abbandoniamo questa
routine per poter proseguire dobbiamo inserire la password giusta, questa semplice metodica viene
chiamata "Uscita forzata dal ciclo". Anche con l'altro metodo cioDo Until ...LoopeDo While ...Loopil
risultato non cambia, pertanto non c' una regola ben precisa su quale forma sia meglio usare.
PossiamodirecheadisposizioneVBAcimettequesteforme,staanoiusarequellacheciparepilogicao
intuitivapereseguireilnostrocodice.
SeviricordatenellalezioneprecedenteavevamoparlatodellanidificazionedelcicloIF,ancheneicicliFor
...NexteDo...Looppossibileeseguirla,vistochel'argomentoloabbiamogitoccatoinquestocontesto
facciamosubitounesempioedopolocommenteremoassieme:

Sub scrivi_col_for()
For riga = 12 To 35
For colonna = 7 To 18
Cells(riga, colonna).Value = riga
Next colonna
Next riga
End Sub
Cosaabbiamofatto?Seprovateadeseguirelamacrovedretechenell'areadilavoroabbiamoriempitotutte
lecelleconilnumerodellarigacorrispondente.VediamoilcodiceForriga=12To35 ilcontatoredelciclo
rappresentato dalla variabilerigae gli diciamo [Per riga che v da 12 a 35] e subito dopo invece di far
eseguireleistruzioniglimettiamoun'altroenunciatoForcolonna=7To18inquestocasoilcontatoredel
ciclorappresentatodallavariabilecolonnaelointerpretiamocos[Percolonnachevda7a18],aquesto
punto abbiamo posto due condizioni una sotto l'altrae subito dopo abbiamo posto le istruzioniCells(riga,
colonna).Value=rigainquestoenunciatolaparolachiaveCellsstaadindicareunadeterminatacelladel
nostrofogliolocalizzatadaivaloridellevariabilirigaecolonnal'altraparolachiaveValueindicailvaloreda
inserirenellecoordinaterappresentate,talevaloreloabbiamoidentificatoconriga.Seguendol'esecuzione
del ciclo, prima viene eseguito il ciclo interno, e cominciamo dalla cella che si trova all'intersezione tra
lacolonnan7elarigan12chesulnostrofogliorappresentatadaG12,alcuiinternoscriviamoilvalore
diriga(percui12)poiincontriamolaparolachiaveNextcolonna,aquestopuntopernonabbiamoancora
raggiuntoladeterminantedelciclo(rappresentatodalvalore18)eVBAincrementailcontatoredi1eripete
le istruzioni, cos facendo andiamo a scorrere tutte le colonne e scriviamo al loro interno il valore della
variabileriga.
Una volta raggiuntala determinante del ciclo usciamo dal ciclo internoma troviamola parola chiaveNext
riga, per cui il contatore del ciclo esterno viene incrementato, passiamo alla riga successiva (la 13) e
ripetiamo il ciclo interno come abbiamo descritto sopra. Il nostro listato ha fine quando viene raggiunta la
determinatedelcicloesternoeaquestopuntotroveremolanostraareadilavororiempitaconilvaloredella
variabilerigaestesasullecolonnediciascunariga.
Oracheabbiamoriempitol'areaconilvaloredellarigatramiteuncicloForNextnidificatopotremmovedere
unlistatoDoLoopperfareilcontrario,cioriempirel'areacolvaloredellacolonna:

Sub scrivi_col_dolop()
riga = 12: colonna = 7
Do Until riga = 35
Do While colonna <> 19
Cells(riga, colonna).Value = colonna
colonna = colonna + 1
Loop
riga = riga + 1: colonna = 7
Loop
End Sub
Notiamo subito una netta differenza tra i due cicli infatti abbiamo dovuto dichiarare i valori iniziali delle
variabili riga e colonna prima dell'inizio delciclo(riga= 12: colonna = 7)in questa tipologia ciclicail VBA
non riesce a determinare da dove deve iniziare in quanto la sintassi di espressione diversa una volta
indicatiivaloridipartenzatroviamolaprimaparolachiaveDoUntilriga=35[ripetifinchilvalorediriga
non uguale a 35] e subito dopo abbiamo posto l'altra condizione che costituisce il ciclo internoDo While
colonna<>19 facciamoattenzioneaquestoenunciato,abbiamousatolaparolachiaveWhileeilcodice
vieneinterpretatocos[ripetimentrecolonnadiversada19],maperch19datochel'ultimacolonnache

dobbiamo riempire la n 18? Lo comprendiamo subito andando avanti con l'analisi del ciclo possiamo
saltare la spiegazione delle istruzioniCells(riga, colonna).Value = colonnain quanto la loro funzione
ugualeaquantospiegatosopraperilcicloForconlasoladifferenzacheriempiamolecellecolvaloredella
variabilecolonna,mentrelasoluzionealquesitopostostanellarigasottocolonna=colonna+1questo
ilnostrocontatore,ilmetodocheusaDo...Loopperincrementarloecontinuarenellasuaesecuzioneinfatti
alla prima esecuzione colonna vale 7 e viene incrementata sempre di 1, poi quando trova la parola
chiaveLoopritorna all'altra parola chiaveDo(dove ha iniziato il ciclo) ed esegue ancora le istruzioni, ma
nella determinante del ciclo abbiamo messo 19 (un valore in pi di 18) semplicemente perch quando
incrementiamoilvaloredellavariabilecolonnaconladicituracolonna=colonna+1allaparolachiaveLoop
la determinate del ciclo sarebbe soddisfatta se mettessimo 18e di conseguenza la nostra area verrebbe
riempita fino alla colonna 17. Provate a modificare il valore nell'esempio allegato e comprenderete come
agisce il ciclo, inoltre quando si lavora con i cicli e per un motivo qualsiasi ci viene rimandato un errore
oppure non viene eseguito quello che volevamo, possiamo usare un piccolo espediente per vedere come
agisce il ciclo e quale valore attribuisce alle variabili usate, infatti basta usare la parola chiave Msgbox e
possiamovederea videoilvaloredellavariabileecorreggerel'errore.Eccounesempiodiutilizzo:

Sub scrivi_col_dolop()
riga = 12: colonna = 7
MsgBox riga
Do Until riga = 36
Do While colonna <> 19
MsgBox colonna
Cells(riga, colonna).Value = colonna
colonna = colonna + 1
Loop
riga = riga + 1: colonna = 7
Loop
End Sub
Ovviamenteilcodiceinblusolounaiutomoltosemplicepertrovareunerrore,esistonoaltrimetodida
poterutilizzaredirettamentenell'editordiVBA,maquestofacomprenderemegliocome"gira"ilnostro
programma.