Discussione: Corso VBA
Visualizza messaggio singolo
Vecchio 15-05-2014, 20.23.44   #22
Alexsandra
Senior Member
WT Expert
 
L'avatar di Alexsandra
 
Registrato: 19-05-2007
Loc.: Verona
Messaggi: 1.208
Alexsandra è un gioiello raroAlexsandra è un gioiello raroAlexsandra è un gioiello raroAlexsandra è un gioiello raro
Azioni ripetitive : Il Ciclo For e il ciclo For Each




Ora che sappiamo come scegliere diverse azioni basandosi su delle condizioni predeterminate, siamo pronti a vedere come ripetere delle azioni un numero predeterminato di volte se si verifica, o non si verifica una particolare condizione nella nostra procedura. Uno degli svantaggi delle macro è la loro incapacità di ripetere le azioni a meno che le azioni desiderate non vengano registrate ripetutamente, VBA fornisce diverse strutture potenti e versatili per permetterci di ripetere facilmente le azioni e per controllare il modo in cui VBA effettua queste ripetizioni.

Le strutture del programma che ripetono l'esecuzione di una o più istruzioni sono chiamate Cicli, alcune strutture per i cicli sono costruite in modo da venire eseguite un numero impostato di volte, e vengono chiamate cicli ad interazione fissa, mentre altri tipi di strutture per i cicli vengono impostate un numero variabile di volte sulla base di alcune condizioni impostate, proprio perchè il numero di ripetizioni di queste strutture non è definito questi cicli vengono chiamati cicli ad interazione indefinita.

Sia nelle strutture ad interazione fissa che nelle strutture ad interazione indefinita, ci sono alcune espressioni che determinano quante volte il ciclo viene ripetuto, questa espressione viene chiamata determinante del ciclo, questa espressione in un ciclo ad interazione fissa è quasi sempre una espressione numerica, mentre per i cicli a interazione indefinita la determinante del ciclo è solitamente un'espressione logica che descrive la condizione sotto la quale il ciclo può continuare o interrompere la sua esecuzione, praticamente vengono usate delle espressioni logiche per la determinante dei cicli allo stesso modo in cui sono state usate per prendere delle decisioni in VBA.


Il ciclo For Next
La più semplice struttura per i cicli è quella ad interazione fissa, VBA ne fornisce due diverse tipologie che vengono espresse così For ...Next e For ...Each ... Next entrambi i cicli vengono chiamati cicli For perchè vengono eseguiti per uno specifico numero di volte. Il ciclo For ... Next ha la seguente sintassi

For contatore = inizio To fine
istruzioni
Next contatore


contatore viene rappresentato da una qualsiasi variabile numerica, di tipo Integer o Long, inizio è anch'esso rappresentato da una variabile numerica e specifica il valore iniziale per la variabile contatore, anche fine è una espressione numerica che rappresenta il valore finale per la variabile contatore. Per default VBA incrementa la variabile [I]contatore di 1 ogni volta che esegue le istruzioni di un ciclo. La parola chiave Next indica a VBA che è stata raggiunta la fine del ciclo, inoltre la variabile contatore, dopo la parola chiave Next, deve essere la stessa variabile contatore che abbiamo messo appena dopo l'enunciato For all’inizio della struttura del ciclo.

Quando VBA esegue un ciclo For, prima assegna il valore rappresentato da inizio alla variabile contatore, quindi esegue tutte le istruzioni rappresentate da istruzioni fino a quando non raggiunge la parola chiave Next che indica che è stata raggiunta la fine del ciclo. VBA poi incrementa la variabile contatore di 1 e ritorna all’inizio del ciclo e confronta il valore corrente della variabile contatore col valore rappresentato da fine. Se contatore è minore o uguale a fine esegue nuovamente il ciclo. Se invece contatore è maggiore di fine VBA esce dal ciclo e continua la sua esecuzione con la prima istruzione dopo la parola chiave Next.

Possiamo però anche specificare un valore diverso per l'incremento della variabile contatore includendo la parola chiave Step [opzionale], in questo caso dobbiamo specificare l'incremento della variabile contatore, e la sintassi diventa così :

For contatore = inizio To fine Step passo
istruzioni
Next contatore


In questo caso l'espressione passo viene rappresentato da una espressione numerica e indica la quantità per incrementare la variabile contatore, vediamo qualche esempio
Codice:
Sub for_semplice()
 For I = 1 To 10
 MsgBox (I)
 Next I
End Sub
L'esecuzione di questo codice ci porta a video la finestra di messaggio (MsgBox) per 10 volte con il valore della variabile I (contatore), se invece vogliamo usare la parola chiave Step e far apparire solo le espressioni dispari possiamo modificare il listato in questo modo
Codice:
Sub for_step()
 For I = 1 To 10 Step 2
 MsgBox (I)
 Next I
End Sub
E ci verranno riportati i soli valori dispari della variabile nella finestra di dialogo di MsgBox. Con la parola chiave Step, abbiamo modificato l'incremento della variabile da 1 (di default) a 2, in pratica alla prima esecuzione del ciclo I vale 1 ma quando incontra la parola chiave Step viene incrementata di 2, se fate “girare” la macro for_step noterete che al primo ciclo viene stampato il valore 1, questo perchè I quando incontra la parola chiave Step vale ancora 1, per cambiare valore deve arrivare alla parola chiave Next (che abbiamo detto essere quella che avvisa di essere arrivati alla fine del ciclo e che incrementa la variabile).

In ultima analisi l'enunciato For viene interpretato così : For I [Per I] = 1 To 10 [che và da 1 a 10] Step 2 [incrementa di 2], Esegui le istruzioni , Next I [incrementa il valore di I], Il ciclo For ..Next ha la flessibilità di poter incrementare e decrementare la variabile, possiamo modificare il listato da For I = 1 To 10 Step 2 a For I = 100 To 1 Step -2 pertanto le possibilità di impiego sono abbastanza vaste, possiamo eseguire somme, incrementare e decrementare il valore delle variabili, utilizzare la ciclicità per ogni bisogno che richieda il nostro programma fermo restando i principi di impiego esposti all'inizio. Esiste anche un'altra forma di ciclo ed è il ciclo For Each ..Next


Il ciclo For Each
A differenza del ciclo For … Next il ciclo For Each … Next non usa un contatore, ma viene eseguito tante volte quanti sono gli elementi di un gruppo specifico, come una collezione di oggetti o un vettore. In breve il ciclo For Each … Next viene eseguito una volta per ogni elemento di un gruppo. Questo tipo di ciclo ha la seguente sintassi

For Each elemento In gruppo
Istruzioni
Next [elemento]


Dove, elemento è una variabile usata per interare il ciclo per tutti gli elementi del gruppo, gruppo è una collezione di oggetti o un vettore (matrice), se gruppo è una collezione di oggetti, elemento deve essere una variabile di tipo Variant o Object o uno specifico tipo di oggetto come Range, Worksheet, Cells e così via. Istruzioni rappresenta nessuna, una o più istruzioni VBA che formano il corpo del ciclo. Questo tipo di ciclo ha meno opzioni del ciclo For Next, l'incremento del contatore non è rilevante in questo ciclo, perchè viene sempre eseguito tante volte quanti sono gli elementi presenti nel gruppo specificato. In pratica non dovendo indicare il numero iniziale e finale per impostare quante volte il ciclo deve ripetere le nostre istruzioni, la nostra ricerca sarà rappresentata da quante volte il dato da cercare sarà presente nell’area di ricerca e l’inizio sarà sempre dal primo record contenuto nell’area di ricerca.

Per meglio comprendere vediamo un esempio di questo tipo : Supponiamo di avere un elenco di nomi nell’intervallo di celle (Range) A1:A5 e si deve confrontare il valore della cella B1 e verificare se è presente nel Range, possiamo scrivere questo codice :
Codice:
Sub prova_each()
Dim x As Boolean
y = Range("B1").Value
  For Each cl In Range("A1:A5")
   If cl = y Then
   x = True
  End If
 Next
If x = True Then
  MsgBox ("Valore Presente")
Else
  MsgBox ("Valore Assente")
End If
End Sub
In questo listato elemento è rappresentato dalla variabile y, cioè dal valore contenuto nella cella B1 e gruppo è rappresentato dal Range A1:A5, mentre il corpo del ciclo è rappresentato dalle istruzioni MsgBox se il valore è presente oppure no. In questo tipo di ciclo il numero iniziale da cui partire è definito dalla prima cella del Range cioè A1 e il numero finale dall’ultima cella dello stesso Range, cioè A5. Adesso il ciclo sa dove iniziare, dove finire e cosa cercare (cerca il valore della cella B1) e scorrendo tutte le celle del Range esegue le istruzioni MsgBox se il valore di B1 è presente oppure no nel percorso di confronto
Possiamo quindi semplificare affermando che gruppo può essere un insieme di oggetti come le celle, le righe e le colonne di un foglio di calcolo, i fogli di lavoro di un file Excel oppure gli oggetti che possiamo inserire in un foglio come pulsanti, caselle di testo pulsanti di comando Userform etc..

E’ indubbio che un ciclo For Each rappresenta un modo pratico per sfogliare gli insiemi di una collezione, va ricordato che l’istruzione For Each funziona come Set, ovvero assegna un riferimento dell’oggetto a una variabile, ma invece di assegnarne uno solo, sceglie tutti gli elementi di una raccolta. Quindi, per ogni oggetto della raccolta, Visual Basic esegue tutte le istruzioni fino al’istruzione Next, anche se tecnicamente, non è necessario inserire il nome della variabile dopo Next, se lo si utilizza, Visual Basic richiede che corrisponda al nome della variabile dopo For Each. Si consiglia di utilizzare sempre la variabile del ciclo dopo Next in modo che Visual Basic possa contribuire a evitare bug nella macro. Le istruzioni che hanno inizio con For Each e terminano con Next sono definite blocchi For Each o cicli For Each.


Cicli Nidificati
È possibile nidificare cicli mettendo un ciclo all'interno di un altro ciclo, fino a un numero illimitato di volte. La variabile contatore per ogni ciclo deve essere univoca ed è possibile nidificare un tipo di ciclo all'interno di un altro tipo diverso. In un ciclo for, è necessario che il ciclo interno sia completato prima che si esegua l'istruzione successiva del ciclo esterno. È inoltre possibile nidificare un tipo di struttura di controllo all'interno di un altro tipo vale a dire che è possibile nidificare un'istruzione IF all'interno di un blocco With che può a sua volta essere annidato all'interno di un For ... Each. Tuttavia, le strutture di controllo non possono essere sovrapposte, ogni blocco nidificato si deve chiudere e terminare entro il livello nidificato esterno.

Esempio di nidificazione di un ciclo IF all'interno di un blocco With che è annidato all'interno di un For. Il codice del ciclo Loop scorre ogni cella nell'intervallo A1: A10, e se il valore della cella è superiore a 5, il colore di sfondo viene impostato come giallo, mentre per valori inferiori a 5 viene usato il colore rosso
Codice:
Sub ciclo1()
Dim iCell As Range
For Each iCell In ActiveSheet.Range("A1:A10")
With iCell
If iCell > 5 Then
.Interior.Color = RGB(255, 255, 0)
Else
.Interior.Color = RGB(255, 0, 0)
End If
End With
Next iCell
End Sub
Uscita anticipata dal ciclo
È possibile uscire da un ciclo For (For ... Next e For Each ... Next) in anticipo, senza completare il ciclo, utilizzando la dichiarazione Exit For che interromperà immediatamente l'esecuzione del ciclo esistente e passerà ad eseguire la sezione di codice immediatamente successiva all'istruzione Next, e nel caso di livello nidificato interno si ferma ed eseguirà il successivo livello nidificato esterno. Si può avere qualsiasi numero di istruzioni Exit For in un ciclo ed è particolarmente utile nel caso in cui si desidera terminare il ciclo al raggiungimento di un certo valore o di soddisfare una condizione specifica, o nel caso in cui si desidera interrompere un Loop infinito a un certo punto.

Esempio: Se la cella A1 è vuota, la variabile nTotal si somma al valore 25, mentre se la cella A1 contiene il valore 5, il ciclo termina ed esce quando il contatore raggiunge il valore 5
Codice:
Sub ciclo2 ()
Dim n As Integer, nTotal As Integer
nTotal = 0
For n = 1 To 10
nTotal = n + nTotal
If n = ActiveSheet.Range("A1") Then
Exit For
End If
Next n
MsgBox nTotal
End Sub
___________________________________

- Il primo fondamento della sicurezza non e' la tecnologia, ma l'attitudine mentale -

Ultima modifica di VincenzoGTA : 18-05-2014 alle ore 15.23.29
Alexsandra non è collegato