VBA
Strutture di controllo del flusso
Ricerca…
Seleziona caso
Select Case
può essere utilizzato quando sono possibili molte condizioni diverse. Le condizioni vengono controllate dall'alto verso il basso e verrà eseguito solo il primo caso corrispondente.
Sub TestCase()
Dim MyVar As String
Select Case MyVar 'We Select the Variable MyVar to Work with
Case "Hello" 'Now we simply check the cases we want to check
MsgBox "This Case"
Case "World"
MsgBox "Important"
Case "How"
MsgBox "Stuff"
Case "Are"
MsgBox "I'm running out of ideas"
Case "You?", "Today" 'You can separate several conditions with a comma
MsgBox "Uuuhm..." 'if any is matched it will go into the case
Case Else 'If none of the other cases is hit
MsgBox "All of the other cases failed"
End Select
Dim i As Integer
Select Case i
Case Is > 2 '"Is" can be used instead of the variable in conditions.
MsgBox "i is greater than 2"
'Case 2 < Is '"Is" can only be used at the beginning of the condition.
'Case Else is optional
End Select
End Sub
La logica del blocco Select Case
può essere invertita per supportare anche il test di diverse variabili, in questo tipo di scenario possiamo anche utilizzare operatori logici:
Dim x As Integer
Dim y As Integer
x = 2
y = 5
Select Case True
Case x > 3
MsgBox "x is greater than 3"
Case y < 2
MsgBox "y is less than 2"
Case x = 1
MsgBox "x is equal to 1"
Case x = 2 Xor y = 3
MsgBox "Go read about ""Xor"""
Case Not y = 5
MsgBox "y is not 5"
Case x = 3 Or x = 10
MsgBox "x = 3 or 10"
Case y < 10 And x < 10
MsgBox "x and y are less than 10"
Case Else
MsgBox "No match found"
End Select
Le dichiarazioni di caso possono anche utilizzare operatori aritmetici. Quando viene utilizzato un operatore aritmetico rispetto al valore Select Case
, deve essere preceduto dalla parola chiave Is
:
Dim x As Integer
x = 5
Select Case x
Case 1
MsgBox "x equals 1"
Case 2, 3, 4
MsgBox "x is 2, 3 or 4"
Case 7 To 10
MsgBox "x is between 7 and 10 (inclusive)"
Case Is < 2
MsgBox "x is less than one"
Case Is >= 7
MsgBox "x is greater than or equal to 7"
Case Else
MsgBox "no match found"
End Select
Per ogni ciclo
Il costrutto Ciclo For Each
è ideale per iterare tutti gli elementi di una collezione.
Public Sub IterateCollection(ByVal items As Collection)
'For Each iterator must always be variant
Dim element As Variant
For Each element In items
'assumes element can be converted to a string
Debug.Print element
Next
End Sub
Utilizzare For Each
quando si iterano raccolte di oggetti:
Dim sheet As Worksheet
For Each sheet In ActiveWorkbook.Worksheets
Debug.Print sheet.Name
Next
Evitare For Each
quando si iterano gli array; un ciclo For
offrirà prestazioni significativamente migliori con gli array. Viceversa, un ciclo For Each
offrirà prestazioni migliori durante l'iterazione di una Collection
.
Sintassi
For Each [item] In [collection]
[statements]
Next [item]
La parola chiave Next
può essere facoltativamente seguita dalla variabile iteratore; questo può aiutare a chiarire i cicli annidati, sebbene ci siano modi migliori per chiarire il codice annidato, come l'estrazione del ciclo interno nella propria procedura.
Dim book As Workbook
For Each book In Application.Workbooks
Debug.Print book.FullName
Dim sheet As Worksheet
For Each sheet In ActiveWorkbook.Worksheets
Debug.Print sheet.Name
Next sheet
Next book
Fai il ciclo
Public Sub DoLoop()
Dim entry As String
entry = ""
'Equivalent to a While loop will ask for strings until "Stop" in given
'Prefer using a While loop instead of this form of Do loop
Do While entry <> "Stop"
entry = InputBox("Enter a string, Stop to end")
Debug.Print entry
Loop
'Equivalent to the above loop, but the condition is only checked AFTER the
'first iteration of the loop, so it will execute even at least once even
'if entry is equal to "Stop" before entering the loop (like in this case)
Do
entry = InputBox("Enter a string, Stop to end")
Debug.Print entry
Loop While entry <> "Stop"
'Equivalent to writing Do While Not entry="Stop"
'
'Because the Until is at the top of the loop, it will
'not execute because entry is still equal to "Stop"
'when evaluating the condition
Do Until entry = "Stop"
entry = InputBox("Enter a string, Stop to end")
Debug.Print entry
Loop
'Equivalent to writing Do ... Loop While Not i >= 100
Do
entry = InputBox("Enter a string, Stop to end")
Debug.Print entry
Loop Until entry = "Stop"
End Sub
Mentre loop
'Will return whether an element is present in the array
Public Function IsInArray(values() As String, ByVal whatToFind As String) As Boolean
Dim i As Integer
i = 0
While i < UBound(values) And values(i) <> whatToFind
i = i + 1
Wend
IsInArray = values(i) = whatToFind
End Function
Per ciclo
Il ciclo For
viene utilizzato per ripetere la sezione di codice racchiusa un determinato numero di volte. Il seguente semplice esempio illustra la sintassi di base:
Dim i as Integer 'Declaration of i
For i = 1 to 10 'Declare how many times the loop shall be executed
Debug.Print i 'The piece of code which is repeated
Next i 'The end of the loop
Il codice sopra dichiara un intero i
. Il ciclo For
assegna ogni valore compreso tra 1 e 10 a i
e quindi esegue Debug.Print i
- ovvero il codice stampa i numeri da 1 a 10 nella finestra immediata. Si noti che la variabile di ciclo viene incrementata dall'istruzione Next
, ovvero dopo l'esecuzione del codice allegato anziché prima dell'esecuzione.
Per impostazione predefinita, il contatore verrà incrementato di 1 ogni volta che viene eseguito il ciclo. Tuttavia, è possibile specificare una Step
per modificare la quantità dell'incremento come valore letterale o di ritorno di una funzione. Se il valore iniziale, il valore finale o il valore Step
è un numero in virgola mobile, verrà arrotondato al valore intero più vicino. Step
può essere un valore positivo o negativo.
Dim i As Integer
For i = 1 To 10 Step 2
Debug.Print i 'Prints 1, 3, 5, 7, and 9
Next
In generale un ciclo For
dovrebbe essere utilizzato in situazioni in cui è noto prima che il ciclo inizi quante volte eseguire il codice allegato (altrimenti un ciclo Do
o While
potrebbe essere più appropriato). Questo perché la condizione di uscita è fissa dopo la prima entrata in loop, come dimostra questo codice:
Private Iterations As Long 'Module scope
Public Sub Example()
Dim i As Long
Iterations = 10
For i = 1 To Iterations
Debug.Print Iterations 'Prints 10 through 1, descending.
Iterations = Iterations - 1
Next
End Sub
Un ciclo For
può essere chiuso in anticipo con la dichiarazione Exit For
:
Dim i As Integer
For i = 1 To 10
If i > 5 Then
Exit For
End If
Debug.Print i 'Prints 1, 2, 3, 4, 5 before loop exits early.
Next