Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Impara Cicli | Fondamenti Di VBA
Excel VBA per l'Automazione Aziendale

Cicli

Scorri per mostrare il menu

Finora, ogni tecnica ha operato su un solo valore alla volta. I cicli (loop) permettono di applicare la stessa logica a molti valori in sequenza — cinque prodotti, cinquecento ordini, o quante righe contiene una tabella — senza dover copiare e incollare lo stesso blocco di codice ripetutamente.

For...Next

Ripete un blocco di codice un numero fisso e noto di volte:

Dim i As Long
For i = 1 To 5
    Debug.Print "Row " & i
Next i
 
' Step lets you skip or count backward
For i = 10 To 1 Step -1
    Debug.Print i
Next i

Nel primo ciclo, i parte da 1, il codice all'interno viene eseguito una volta con quel valore, poi i aumenta automaticamente di 1 e l'intero blocco viene eseguito di nuovo — ripetendo fino a quando i supera 5, momento in cui il ciclo si interrompe e l'esecuzione prosegue dopo Next. Step modifica l'incremento: Step -1 conta all'indietro invece che in avanti di uno, mentre Step 2 conterebbe a due a due. La variabile del ciclo i non è una sintassi speciale — è semplicemente una variabile Long che VBA aggiorna automaticamente ad ogni iterazione.

For Each

Cicla direttamente su ogni elemento di una collezione, senza dover sapere quanti elementi ci sono o gestire un contatore manualmente:

Dim cell As Range
For Each cell In ThisWorkbook.Worksheets("Products").Range("B2:B6")
    Debug.Print cell.Value
Next cell

Qui cell assume a turno ogni singola cella nell'intervallo B2:B6, e si può leggere il contenuto con .Value. Confronta questo con For...Next: con For...Next si conta attraverso i numeri e si usa quel numero per cercare qualcosa; con For Each si attraversano direttamente gli elementi stessi, il che risulta più naturale quando si lavora con intervalli di fogli di lavoro.

Do While

Ripete finché una condizione rimane True — il ciclo non sa in anticipo quante volte verrà eseguito, a differenza di For...Next:

Dim stock As Integer
stock = 134
Do While stock > 0
    stock = stock - 30    ' simulate selling in batches of 30
Loop
Debug.Print stock   ' whatever's left after the loop stops

VBA controlla stock > 0 prima di ogni passaggio nel ciclo, incluso il primo. Segui il ragionamento passo passo: 134 → 104 → 74 → 44 → 14, poi la condizione viene controllata di nuovo — 14 è ancora maggiore di 0, quindi il ciclo si esegue ancora una volta, arrivando a -16. Solo allora stock > 0 restituisce finalmente False, e il ciclo si interrompe con stock a -16, non esattamente a 0 o 14. Questo è importante da seguire attentamente la prima volta, perché è una fonte comune di errori di uno: un ciclo Do While continua a girare finché la condizione è vera al momento del controllo, anche se l'azione all'interno supera il limite previsto.

Do Until

Esiste anche Do Until, che è l'immagine speculare di Do While — ripete finché una condizione è False e si interrompe nel momento in cui quella condizione diventa True, invece che il contrario. Quale delle due risulti più naturale dipende da come si formulerebbe la regola aziendale a voce: "continua finché c'è stock" suggerisce Do While; "continua finché lo stock si esaurisce" suggerisce Do Until — possono produrre lo stesso comportamento, solo espressi da direzioni opposte.

Istruzioni Exit

Permettono di uscire anticipatamente da un ciclo, prima che venga raggiunta la condizione naturale di fine:

For i = 1 To 100
    If i = 10 Then Exit For   ' stop the loop immediately
    Debug.Print i
Next i

Questo ciclo è impostato per contare fino a 100, ma nel momento in cui i raggiunge 10, Exit For lo interrompe subito — nulla dopo Exit For viene eseguito, e l'esecuzione passa direttamente alla riga dopo Next i. Questo è il modello da usare per cercare in un elenco e fermarsi appena si trova ciò che si cerca, invece di continuare inutilmente a controllare ogni elemento rimanente.

Mettere tutto insieme

Ogni tecnica di questo capitolo — variabili, operatori, funzioni, logica condizionale e ora i cicli — si combina nella procedura verso cui il capitolo ha lavorato:

Option Explicit
 
Sub CheckStockLevels()
 
    ' Sample data standing in for the Products table
    Dim products(1 To 5) As String
    Dim stockLevels(1 To 5) As Integer
    Dim reorderLevels(1 To 5) As Integer
    Dim i As Long
    Dim alertMessage As String
 
    products(1) = "Laptop Stand": stockLevels(1) = 58: reorderLevels(1) = 20
    products(2) = "Wireless Mouse": stockLevels(2) = 134: reorderLevels(2) = 30
    products(3) = "USB-C Hub": stockLevels(3) = 44: reorderLevels(3) = 15
    products(4) = "Monitor Arm": stockLevels(4) = 18: reorderLevels(4) = 10
    products(5) = "Keyboard": stockLevels(5) = 61: reorderLevels(5) = 20
 
    alertMessage = ""
 
    For i = 1 To 5
        Select Case stockLevels(i)
            Case Is <= reorderLevels(i)
                alertMessage = alertMessage & products(i) & _
                    " — REORDER NOW" & vbNewLine
            Case Is <= reorderLevels(i) + 10
                alertMessage = alertMessage & products(i) & _
                    " — watch closely" & vbNewLine
        End Select
    Next i
 
    If alertMessage = "" Then
        MsgBox "All products are adequately stocked."
    Else
        MsgBox "Stock Alerts:" & vbNewLine & alertMessage
    End If
End Sub
Analisi riga per riga
expand arrow
  • Dim products(1 To 5) As String e le due righe simili sottostanti dichiarano array — ognuno rappresenta una riga numerata di cinque caselle invece di una sola, quindi products(1) è il nome del primo prodotto, products(2) il secondo, e così via;
  • Le cinque righe che usano i due punti (:) tra le istruzioni raggruppano più assegnazioni sulla stessa riga solo per leggibilità — products(1) = "Laptop Stand": stockLevels(1) = 58: reorderLevels(1) = 20 è esattamente equivalente a scrivere queste istruzioni su tre righe separate;
  • For i = 1 To 5 ... Next i attraversa tutti e cinque i prodotti uno alla volta, usando i sia come contatore del ciclo sia come indice per ogni array;
  • Select Case stockLevels(i) ripete la stessa decisione basata su intervallo della sezione 2.4, ma ora sui dati reali dell'array invece che su un singolo numero fisso;
  • Case Is <= reorderLevels(i) intercetta ogni prodotto il cui stock è sceso al livello di riordino o al di sotto — nota che reorderLevels(i) è una variabile, non un numero fisso, quindi ogni prodotto viene valutato rispetto alla propria soglia invece che una soglia unica per tutti;
  • alertMessage = alertMessage & ... & vbNewLine costruisce una stringa crescente una riga alla volta — vbNewLine è una costante integrata che inserisce un'interruzione di riga, così ogni prodotto segnalato appare su una riga separata nel messaggio finale;
  • Il controllo finale If alertMessage = "" Then decide quale delle due varianti di MsgBox l'utente vedrà effettivamente — una stringa vuota significa che il ciclo non ha trovato nulla da segnalare.

Esegui questo e dovresti vedere il Monitor Arm contrassegnato come "osservare attentamente" (18 unità rispetto a un livello di riordino di 10) — segui manualmente il ciclo per i = 4 se vuoi confermare esattamente perché è l'unico rilevato dal secondo Case e non dal primo. Questa procedura utilizza array, un ciclo, un Select Case e la costruzione di stringhe, tutti che lavorano insieme. Questa logica è già molto vicina a quella di produzione, semplicemente applicata a dati di esempio inseriti direttamente nel codice invece che in un vero foglio di lavoro.

Attività

  1. Copia CheckStockLevels nel tuo workbook ed eseguilo. Conferma che il messaggio corrisponda allo screenshot.
  2. Modifica lo stock del Wireless Mouse a 25 e riesegui — ora dovrebbe essere visualizzato anche come "osservare attentamente".
  3. Aggiungi un ciclo Do While sotto che simuli la vendita di 15 unità di Laptop Stand alla volta finché lo stock scende a 20 o meno, stampando il totale progressivo nella Finestra Immediata dopo ogni vendita.
  4. Sfida: riscrivi il ciclo For i = 1 To 5 utilizzando invece For Each su un array Variant — la logica funziona ancora?
Suggerimento
expand arrow

2. Modifica dello stock del Wireless Mouse

  • Individuare la riga che imposta i dati del Wireless Mouse: products(2) = "Wireless Mouse": stockLevels(2) = 134: reorderLevels(2) = 30.
  • È necessario solo modificare il numero centrale (134) in 25 — lasciare invariati il nome del prodotto e il livello di riordino.
  • Prima di eseguire, calcolare manualmente quale Case dovrebbe intercettarlo: 25 ≤ 30 (il livello di riordino)? Confrontare questo con la riga Case Is <= reorderLevels(i), non con la seconda.

3. Simulazione di vendite a lotti con Do While

  • Serve una variabile per memorizzare lo stock corrente del Laptop Stand — inizializzarla con lo stesso valore già presente in stockLevels(1) (58), così da non digitare un nuovo numero che potrebbe non essere coerente con il resto della macro.
  • La condizione del ciclo deve verificare se lo stock è ancora superiore a 20 — appena lo stock raggiunge 20 o meno, il ciclo deve fermarsi.
  • Sottrarre 15 ad ogni iterazione e stampare il nuovo valore subito dopo la sottrazione — non prima — così ogni numero stampato riflette una vendita completata.
  • Tracciare il processo su carta: 58 → 43 → 28 → 13. Notare che l'ultimo valore scende sotto 20 invece di arrivare esattamente a 20 — questo è lo stesso comportamento di "overshoot" del ciclo Do While illustrato nel diagramma del capitolo, non un errore.
Soluzione
expand arrow

Punto 2 — all'interno di CheckStockLevels, modificare solo un numero:

products(2) = "Wireless Mouse": stockLevels(2) = 25: reorderLevels(2) = 30

Eseguire nuovamente la Sub.

Punto 3 — aggiungere questo codice sotto quello esistente, sempre all'interno di CheckStockLevels (prima di End Sub):

    ' --- Simulate selling Laptop Stand in batches of 15 ---
    Dim laptopStandStock As Integer
    laptopStandStock = stockLevels(1)

    Do While laptopStandStock > 20
        laptopStandStock = laptopStandStock - 15
        Debug.Print laptopStandStock
    Loop
Tutto è chiaro?

Come possiamo migliorarlo?

Grazie per i tuoi commenti!

Sezione 2. Capitolo 5

Chieda ad AI

expand

Chieda ad AI

ChatGPT

Chieda pure quello che desidera o provi una delle domande suggerite per iniziare la nostra conversazione

Sezione 2. Capitolo 5
some-alt