Connessione al database con Visual Basic NET? Lo trovi su Opentraining.it Visual Basic Italia
PRINCIPALE > CORSO DI VISUAL BASIC

Eseguire una ricerca veloce nell' archivio delle risorse di Visual Basic Italia®: 

Preso dall'archivio...

Premere il pulsante sotto per accedere direttamente ad un articolo o ad un esempio preso in modo casuale dall'archivio.



Ultimo e-book pubblicato:

"INTRODUZIONE AI CSS"

Lo scopo del CSS language è quello di controllare lo stile dei vari elementi che concorrono a formare un
documento HTML.
Si può operare in tre modi collegamento ad un foglio di stile esterno;definizione degli stili all'inizio
del documento utilizzo della proprietà style all'interno di un Tag HTML (embedded style). Questo e-book introduttivo
servirà per apprendere tali nozioni fondametali dei fogli di stile.

Prezzo: € 0.0.
Presentazione:
REAL SOFTWARE RILASCIA LA VERSIONE 5.0 di REALbasic per Windows






Gorizia, 5 maggio 2003 - Active, distributore in esclusiva di REALSoftware, Austin, Tx, annuncia la disponibilità di REALbasic 5.0 per Windows, uno strumento per lo sviluppo semplice da usare che permette agli utenti Windows di tutti i livelli di creare applicazioni personalizzate e di compilarle sia per la piattaforma Windows che per quella Macintosh.
[>>]

http://www.active-software.com

 

Contatti. Utilizzare l'email generica per domande relative al sito:
Porre domande relative al sito
oppure scrivere ad un responsabile di area.
Responsabile del sito: >Andrea Martelli
Responsabile area "Corso di VB":
> Giorgio Abraini

Corso di Visual Basic: lezione 19

Questa lezione, consultata da 15713 utenti, è stata giudicata di ottimi contenuti , con un'esposizione perfettamente comprensibile e con un livello di approfondimento ottimo da 35 votanti.


Lezione 19

Come accennato in altre lezioni, Visual Basic mette a disposizione del programmatore vari tipi di cicli iterativi; nell'ultima lezione abbiamo visto il ciclo principale (For… Next), ora vedremo un altro ciclo molto importante: il Do…Loop.
Come il ciclo For…Next, anche il ciclo Do…Loop esegue un gruppo di istruzioni finché risulta verificata (o falsificata, a seconda del punto di vista) una determinata condizione: questa condizione deve essere preceduta da una parola chiave che indica se il proseguimento del ciclo è subordinato alla verità o falsità della condizione. Le due parole chiave che possono essere utilizzate sono While e Until: la prima indica che la condizione specificata deve risultare vera affinché il ciclo prosegua, la seconda indica che la condizione deve risultare falsa affinché il ciclo prosegua.
Ecco un esempio di ciclo Do…Loop:

Dim i As Integer

i = 1
Do While i<10
i = i + 1
Debug.Print i
Loop
Debug.Print "i vale "+cstr(i)+": il ciclo è terminato"

Questo ciclo incrementa e stampa il valore della variabile i fintantoché essa resta minore di 10: quando i assume il valore 10 la condizione i<10 risulterà falsa, e poiché nel ciclo è specificata la parola chiave While, il ciclo si interromperà e il controllo passerà all'istruzione successiva all'istruzione Loop.
Lo stesso identico ciclo può essere espresso anche utilizzando la parola chiave Until:

Dim i As Integer

i = 1
Do Until i>=10
i = i+1
Debug.Print i
Loop
Debug.Print "i vale "+cstr(i)+": il ciclo è terminato"

Avendo utilizzato Until, è necessario invertire la condizione di controllo affinché i due cicli siano equivalenti: nel primo esempio il ciclo era eseguito finché i<10 è vera, nel secondo esempio il ciclo è eseguito finché i>=10 è falsa, poiché il valore iniziale di i è sempre 1. In termini più generali, dato un ciclo Do While:

Do While condizione
[istruzioni]
Loop


il ciclo Do Until equivalente sarà:

Do Until Not condizione
[istruzioni]
Loop

Da questi esempi appare con evidenza una forte analogia con il ciclo For visto sopra: in effetti le differenze sono ben poche, tant'è vero che qualunque ciclo For può essere espresso come un ciclo Do e viceversa.
L'uso di un ciclo al posto di un altro va deciso in base a questioni di convenienza: si sceglie l'istruzione più semplice, più immediata, più facilmente comprensibile: negli esempi appena considerati il ciclo For è leggermente preferibile al ciclo Do, perché è più intuitivo e consente di evitare l'istruzione di incremento della variabile i, che in questi casi funge da "contatore": è proprio l'istruzione For…Next che si occupa di inizializzare e incrementare la variabile, e così il programmatore deve solo preoccuparsi di stamparne il valore.
In generale, il ciclo For è preferibile quando si conosce con esattezza il numero di iterazioni, ossia quando si sa per quante volte il ciclo deve essere eseguito; il ciclo Do è preferibile invece quando è necessaria più flessibilità, quando il numero di iterazioni non può essere conosciuto a priori.
Ad esempio, si supponga di dover eseguire ciclicamente un gruppo di istruzioni finché l'utente non dice "basta!": non è possibile sapere in anticipo di quanta pazienza disponga l'utente, perciò è opportuno ricorrere a un ciclo Do che controlli il verificarsi di una condizione. In casi come questi, solitamente si fa ricorso all'utilizzo di una variabile flag di tipo booleano, che assuma il valore vero (o falso, a seconda della convenienza) quando l'utente decide di interrompere il ciclo:

Dim blnFlag As Boolean 'flag di controllo del ciclo
Do While blnFlag
Debug.Print Rnd()
Loop

Questo semplice ciclo continua a visualizzare numeri casuali finché la variabile blnFlag è vera: il ciclo si interromperà quando il flag, a seguito di un'azione dell'utente o al verificarsi di altre condizioni, assumerà il valore False. Per esempio, si inserisca in un Form un pulsante di comando e un'etichetta di testo: si imposti la Caption del CommandButton a "Avvia" e nella routine Click si scriva:

Private Sub Command1_Click()
If blnFlag Then
Command1.Caption = "Avvia"
blnFlag = False
Else
Command1.Caption = "Interrompi"
blnFlag = True
End If
Do While blnFlag
Label1.Caption = CStr(Rnd())
DoEvents
Loop
End Sub

La subroutine controlla innanzitutto il valore del flag (che naturalmente deve essere dichiarato a livello di modulo): se è falso (impostazione predefinita iniziale per tutte le variabili booleane), esso diventa vero e il ciclo Do successivo può essere eseguito dando il via alla visualizzazione dei numeri casuali; altrimenti diventa falso e quindi il ciclo Do si interrompe; inoltre viene modificata la Caption del pulsante per far capire all'utente l'effetto della pressione del pulsante stesso.
Nel ciclo Do compare l'istruzione DoEvents, che restituisce temporaneamente il controllo al sistema operativo per consentirgli di gestire altre operazioni accumulatesi durante l'esecuzione del nostro programma: senza questa istruzione, a causa del modo con cui Windows gestisce il multitasking, il programma si bloccherebbe nell'esecuzione del ciclo, perché la pressione del pulsante non avrebbe alcun effetto.
Detto con parole poco precise, il programma è così impegnato ad eseguire il ciclo Do che non ha il tempo di gestire gli altri input forniti dall'utente (come la pressione del pulsante), né di aggiornare l'aspetto degli altri componenti del Form (l'etichetta non mostra nulla), a meno che non ci sia un'istruzione esplicita che obblighi il nostro programma a cedere momentaneamente il controllo al sistema operativo: questo è appunto il compito dell'istruzione DoEvents.
Senza di essa l'unico modo per interrompere il programma è premere la combinazione di tasti ctrl+alt+canc se il programma è stato compilato; se invece è eseguito all'interno dell'IDE di Visual Basic basta premere ctrl+pausa.
L'eliminazione dell'istruzione DoEvents impedisce di modificare il flag blnFlag una volta che il ciclo Do è cominciato: la variabile booleana pertanto resta sempre True, e di conseguenza il ciclo non si interromperà mai; questo è un semplice esempio di ciclo infinito.
La presenza di cicli infiniti è uno dei classici bug commessi da programmatori alle prime armi, ma anche da programmatori un po' più esperti: quando la condizione di controllo del ciclo dipende da diversi fattori può essere difficile rendersi conto dell'errore commesso, anche perché di norma l'errore sarà tanto più "nascosto" quanto più si presenta raramente nel corso dell'esecuzione. Per questo motivo è necessario stare bene attenti a fornire una condizione di uscita dal ciclo: se c'è il rischio che la condizione di controllo resti sempre vera (se si usa While) o sempre falsa (se si usa Until), può essere opportuno utilizzare ancora l'istruzione Exit; nel caso del ciclo For l'istruzione corretta era Exit For, nel caso del ciclo Do l'istruzione corretta è Exit Do.
L'esempio precedente potrebbe quindi essere riscritto in questo modo:

Private Sub Command1_Click()
If blnFlag Then
Command1.Caption = "Avvia"
blnFlag = False
Else
Command1.Caption = "Interrompi"
blnFlag = True
End If
Do While True 'ciclo virtualmente infinito
Label1.Caption = CStr(Rnd())
DoEvents
If Not blnFlag Then Exit Do 'condizione di uscita dal ciclo
Loop
End Sub

Il ciclo è potenzialmente infinito, perché la condizione di controllo non è una vera e propria condizione, ma è un valore letterale costante (True) che in quanto tale non potrà mai diventare False: la condizione di uscita è quindi ottenuta tramite un controllo interno al ciclo, che esamina il valore del flag: se questo è falso, significa che l'utente vuole interrompere il ciclo, pertanto Not blnFlag sarà True e sarà eseguita l'istruzione Exit Do che passa il controllo all'istruzione successiva al ciclo (in questo caso End Sub).
La clausola While o Until può trovarsi alternativamente dopo l'istruzione D
o o dopo l'istruzione Loop:

Do While|Until condizione
[istruzioni]
Loop


oppure:

Do
[istruzioni]
Loop While|Until condizione

La differenza consiste nel momento in cui è controllato il valore di condizione: nel primo caso il controllo avviene all'inizio di ogni iterazione, nel secondo caso alla fine di ogni iterazione.
Ciò significa che se per ipotesi la condizione risulta subito falsa (o vera, se si usa Until), nel primo caso il ciclo non sarà eseguito mai, mentre nel secondo caso sarà eseguito solo una volta, perché la condizione è controllata dopo l'esecuzione delle istruzioni.
La condizione di controllo del ciclo può naturalmente essere rappresentata da un'espressione booleana anche complessa, come la seguente:

Do While blnFlag And (intUsers > 1 Or intUsers = -1) And ((lngCount Xor _ lngMax) = 20)
'istruzioni
Loop

In questi casi bisogna tenere presente che la condizione è sempre e soltanto una, che viene valutata tenendo conto complessivamente del valore delle singole parti e degli operatori logici utilizzati: quando l'intera espressione è vera, il ciclo prosegue, quando diventa falsa il ciclo si interrompe.
Trasformare un ciclo del genere nel corrispondente Do Until…Loop può diventare molto complicato se si cerca di convertire ogni parte della condizione nel corrispondente opposto: in questo caso, l'equivalente sarebbe:

Do Until Not blnFlag Or (intUsers <= 1 And intUsers <> -1) Or ((lngCount Xor _ lngMax) <> 20)
'istruzioni
Loop

Ma la cosa più semplice è premettere un Not all'intera condizione:

Do Until Not (blnFlag And (intUsers > 1 Or intUsers = -1) And ((lngCount Xor _ lngMax) = 20))
'istruzioni
Loop

Infine, come per i cicli For, anche i cicli Do possono essere nidificati a più livelli: ogni istruzione Loop corrisponderà all'istruzione Do immediatamente precedente, in modo che ogni ciclo sia interamente contenuto nel ciclo più esterno, come nell'esempio seguente:

Do While condizione1
Do
[istruzioni2]
Loop Until condizione2
[istruzioni1]
Loop

Ora che conoscete anche il ciclo Do…Loop, potete riprendere in mano il progetto del Campo minato delle lezioni precedenti: ricordate lo stratagemma utilizzato per assicurarsi che le tre mine fossero disposte sotto tre differenti pulsanti? La soluzione escogitata consisteva nel simulare più estrazioni casuali tramite l'uso di etichette e dell'istruzione GoTo.
In realtà una soluzione molto più efficiente e flessibile (oltre che più "bella" stilisticamente) è data dall'uso di un ciclo Do simile a questo:

Dim t As Integer 'variabile temporanea per eseguire i controlli

Dim i As Integer, k As Integer 'contatori per i cicli
Dim blnUguali As Boolean 'flag
Randomize Timer
For i = 0 To 2
Do
PosMine(i) = Int(Rnd * 16)
blnUguali = False
For k = 0 To i - 1
If (PosMine(i) = PosMine(k)) Or blnUguali Then
blnUguali = True
Else
blnUguali = False
End If
Next
k
Loop While blnUguali
Mina(PosMine(i)).Tag = True
Next i

L'algoritmo è solo apparentemente complicato: il ciclo For esterno conta le mine da piazzare, e contiene un ciclo Do che continua a estrarre valori casuali finché l'ultimo valore estratto risulta uguale a uno di quelli estratti nelle iterazioni precedenti. L'uguaglianza di due valori è segnalato dal flag blnUguali, il cui valore è impostato nel terzo ciclo, quello più interno che ha come contatore k: questo ciclo controlla se la posizione calcolata della mina considerata coincide con la posizione delle mine precedenti; se due mine coincidono, il flag è impostato a True, altrimenti è impostato a False.
Si noti che la condizione controllata non è semplicemente (PosMine(i)=PosMine(k)), ma (PosMine(i)=PosMine(k)) Or blnUguali, per evitare che blnUguali diventi False quando è già True, cioè quando è già stata trovata una coincidenza da eliminare.
Per lo stesso motivo, blnUguali è reinizializzato a False prima di controllare la coincidenza di due mine col ciclo For interno. Una volta che si è calcolata una posizione della mina i-esima che è diversa dalle altre, il ciclo Do si interromperà e si potrà aggiornare la proprietà Tag di quella mina, e così via per tutte le tre mine.
Questo è un algoritmo semplice ma potente, perché consente di estrarre valori casuali certamente diversi l'uno dall'altro qualunque sia il numero di iterazioni da effettuare (ovvero il numero di mine da piazzare): se avessimo dovuto cavarcela con le etichette la situazione sarebbe diventata ingestibile anche solo con 10 mine.