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 20

Questa lezione, consultata da 15017 utenti, è stata giudicata di buoni contenuti , con un'esposizione perfettamente comprensibile e con un livello di approfondimento ottimo da 43 votanti.


Lezione 20

Tra le strutture iterative disponibili in Visual Basic, esiste anche il ciclo While…Wend, che è certamente il meno conosciuto e meno utilizzato; in effetti il funzionamento di questo tipo di ciclo è del tutto analogo a quello di un ciclo Do While…Loop: le istruzioni contenute nel ciclo sono eseguite finché la condizione espressa dopo l'istruzione While è vera

While condizione
[istruzioni]
Wend

Oltretutto, il normale ciclo Do While…Loop è più flessibile del ciclo While…Wend, e tanto basta a giustificare lo scarsissimo uso del ciclo While…Wend.

Tornando ai cicli in generale, quando si deve utilizzare una struttura iterativa bisogna fare attenzione in particolare a due cose: la prima, che abbiamo già visto, è fornire una condizione di uscita per evitare cicli infiniti; la seconda riguarda la corretta gestione della prima e dell'ultima iterazione.
La questione non è così banale come sembra, e soprattutto all'inizio può portare a errori grossolani: prendiamo ad esempio il caso di una ricerca ricorsiva di una stringa all'interno di un testo. Spesso capita che sia necessario conoscere, oltre al nome di un file, anche il suo percorso (path in inglese), ovvero la posizione esatta all'interno dell'albero delle directory contenute nell'hard disk; e a volte è utile suddividere il percorso in tanti "pezzi" quante sono le cartelle che bisogna attraversare per giungere fino al file: per fare ciò occorre contare quanti sono i separatori di path presenti nella stringa che identifica il percorso, ovvero quanti backslash ("\") ci sono.
Per trovare una stringa all'interno di un'altra è sufficiente usare la comoda istruzione instr, la cui sintassi è:

instr([start], string1, string2, [compare])

Il primo parametro è un numero che indica la posizione dalla quale cominciare a cercare la stringa da trovare: ad esempio, se stiamo cercando un backslash all'interno di un path completo, è inutile cominciare a cercare dal primo carattere del percorso, perché questo comincia con la lettera di un'unità seguita dai due punti (ad es. "C:"), quindi è possibile iniziare la ricerca direttamente dal terzo carattere.
Il parametro è facoltativo, e se non viene specificato la ricerca partirà dal primo carattere.
I parametri string1 e string2 identificano rispettivamente la stringa in cui bisogna cercare (nel nostro caso il percorso) e la stringa da cercare (nel nostro caso il backslash).
L'ultimo parametro indica come va effettuata la ricerca: nel nostro caso i valori interessanti sono due: 0, espresso anche dalla costante vbBinaryCompare, e 1, espresso dalla costante vbTextCompare; nel primo caso il confronto tra le due stringhe è effettuato in modalità binaria, che tradotto un po' rozzamente significa che il confronto è "case sensitive", ovvero sensibile alla differenza tra maiuscole e minuscole; nel secondo caso invece la differenza tra maiuscole e minuscole è ignorata, perché il confronto è effettuato in semplice modalità testuale.
Per chiarire la differenza, basta scrivere nella finestra immediata:

? instr(1, "Pippo", "p", vbBinaryCompare) 'oppure instr(1, "Pippo", "p", 0), è la stessa cosa

La funzione restituirà il valore 3. Se invece si scrive:

? instr(1, "Pippo", "p", vbTextCompare) 'oppure instr(1, "Pippo", "p", 1)

la funzione restituirà 1.
Come avrete intuito, il valore restituito dalla funzione è la posizione della prima "p" trovata nella stringa "Pippo": ma mentre nel primo caso cerchiamo una p minuscola abilitando la ricerca "case sensitive", nel secondo caso la ricerca è solo in modalità testo, e quindi la funzione restituisce la posizione della prima "p" che trova, maiuscola o minuscola che sia. Se la stringa cercata non si trova in quella in cui è fatta la ricerca (se ad esempio cerchiamo una "z" in "pippo", o anche una "O" in "Pippo" abilitando la ricerca binaria), la funzione instr restituisce zero.
Tornando al nostro esempio, per contare i backslash in un path basta un semplice ciclo do…loop, utilizzando un contatore da incrementare ogni volta che instr trova un "\": dobbiamo però fare attenzione a spostare sempre in avanti il punto di inizio della ricerca (il parametro start), perché se cerchiamo sempre a partire dal primo carattere, il ciclo non si fermerà mai e restituirà sempre la posizione del primo "\".
Una soluzione comoda è quella di utilizzare un'altra variabile che memorizzi la posizione dell'ultimo "\" trovato, ovvero che memorizzi il valore restituito da instr: la ricerca successiva dovrà partire dal carattere successivo:

Dim intPos As Integer
Dim strPath As String
strPath = "C:\documenti\immagini\esempio.jpg"
Do
intPos = Instr(intPos+1, strPath, "\")
Loop

intPos memorizza la posizione dell'ultimo backslash trovato: poiché essa è inizializzata a 0, alla prima iterazione la ricerca partirà dal primo carattere, come avviene nella maggior parte dei casi (se vogliamo farla partire dal terzo carattere, perché i primi due contengono il nome dell'unità, basta inizializzare intPos=2 prima del Do); nelle iterazioni successive, partirà dal carattere successivo all'ultimo backslash trovato nel path.
Il parametro "compare" è stato tralasciato perché non ha alcuna influenza: non esiste un "\" maiuscolo e un "\" minuscolo; comunque l'impostazione predefinita è vbBinaryCompare.
La variabile strPath è inizializzata a un percorso qualunque (compreso il nome di un file) solo per far funzionare il codice: in realtà dovrebbe essere ignoto a priori, ad esempio potrebbe essere inserito dall'utente in fase di esecuzione.
Nel ciclo appena descritto manca una cosa: la condizione di uscita.
Questa dovrebbe verificare se la funzione instr ha restituito un valore positivo oppure no: nel primo caso significa che ha trovato un "\" e quindi possiamo continuare la ricerca; nel secondo caso vuol dire che non ha trovato nulla e quindi la ricerca deve essere fermata perché non ci sono ulteriori "\" nell'ultima parte del percorso. Pertanto la condizione potrebbe essere:

While intPos>0

oppure:

Until intPos=0

Bisogna decidere dove mettere la condizione, se all'inizio o alla fine del ciclo: se intPos è inizializzata a 0, certamente la condizione non dovrà essere posta all'inizio, altrimenti il ciclo non eseguirebbe neppure un'istruzione:

Dim intPos As Integer
Dim strPath As String
strPath = "C:\documenti\immagini\esempio.jpg"
Do While intPos>0 'intPos è =0, quindi il ciclo non è eseguito
intPos = Instr(intPos+1,strPath,"\")
Loop

D'altra parte, mettere la condizione alla fine comporta la perdita di una preziosa informazione: la posizione dell'ultimo backslash esistente nel path, che solitamente indica anche l'inizio del nome vero e proprio del file (oppure il nome della cartella in cui risiede il file, a seconda dei casi):

Dim intPos As Integer
Dim strPath As String
strPath = "C:\documenti\immagini\esempio.jpg"
Do
intPos = Instr(intPos+1,strPath,"\")
Loop While intPos>0

Questo ciclo esegue almeno una volta la ricerca, e prosegue fino a trovare tutti i "\": ma all'uscita dal ciclo intPos vale 0, e noi non sappiamo più qual era la posizione dell'ultimo backslash; magari è un'informazione che non ci interessa, ma in caso contrario dobbiamo trovare una soluzione alternativa.
Ad esempio si potrebbe utilizzare un'altra variabile per memorizzare il valore precedente di intPos:

Dim intPos As Integer
Dim intPosPrec As Integer
Dim strPath As String
strPath = "C:\documenti\immagini\esempio.jpg"
Do
intPosPrec = intPos
intPos = Instr(intPos+1, strPath, "\")
Loop While intPos>0

All'uscita dal ciclo, intPosPrec conterrà la posizione dell'ultimo "\". Oppure si può utilizzare come condizione di uscita non "intPos>0", bensì "Instr(…)>0", ma in questo modo la funzione Instr viene eseguita due volte per ogni ricerca: una volta per controllare se ci sono altri "\", e un'altra volta per sapere dove si trovano:

Dim intPos As Integer
Dim strPath As String
strPath = "C:\documenti\immagini\esempio.jpg"
Do While Instr(intPos+1, strPath, "\")
intPos = Instr(intPos+1, strPath, "\")
Loop

In questo caso la condizione può essere spostata all'inizio del ciclo: se questo non viene eseguito neppure una volta, significa che non ci sono "\" nel percorso; infatti instr() restituisce zero, che viene valutato come valore logico False, e quindi la condizione per eseguire il ciclo non è verificata. Una soluzione analoga può essere adottata inizializzando a un valore positivo la variabile intPos (ad esempio al valore 2, come suggerito prima):

Dim intPos As Integer
Dim strPath As String
strPath = "C:\documenti\immagini\esempio.jpg"
IntPos = 2
Do While intPos
IntPos = Instr(intPos+1, strPath, "\")
Loop

Insomma, quando usate i cicli state attenti non solo a quando interromperli (condizione di uscita), ma anche a quale valore assumono le variabili coinvolte in essi (in particolare prima della prima iterazione e dopo l'ultima iterazione). Se non siete ancora convinti, proviamo ora a memorizzare le varie parti del percorso in un vettore: ogni elemento del vettore deve contenere una delle cartelle appartenenti al path, in ordine gerarchico; poiché non sappiamo a priori quante cartelle sono coinvolte, possiamo usare un vettore dinamico: ogni volta che troviamo un "\", dobbiamo aggiungere un elemento al vettore e assegnargli il nome della cartella che precede questo "\"

Dim strCartelle() As String
Dim intPos As Integer
Dim intPosPrec As Integer
Dim strPath As String
strPath="C:\documenti\immagini\esempio.jpg"
Do
IntPosPrec = intPos
IntPos = instr(intPos+1, strPath, "\")
ReDim Preserve strCartelle(Ubound(strCartelle)+1)
StrCartelle(Ubound(strCartelle)) = Mid$(strPath, intPosPrec+1, intPos - _ intPosPrec)
Loop While intPos

Il vettore strCartelle contiene i nomi delle cartelle presenti nel path: è un vettore dinamico, che viene ridimensionato all'interno del ciclo ogni volta che viene trovato un "\".
Il ridimensionamento, che avevamo brevemente già visto (lez. 14), avviene in base al valore della funzione Ubound, che restituisce il limite superiore attuale del vettore: se il vettore ha tre elementi (da 0 a 2), Ubound restituisce 2; attenzione: se Ubound restituisce zero non significa che il vettore non ha alcun elemento, ma che ne ha uno solo, con indice 0.
Aggiungere un elemento al vettore significa quindi ridimensionarlo assegnandogli un elemento in più di quelli che già possiede (ubound()+1).
La parola chiave Preserve serve invece a mantenere in memoria i valori già assegnati: infatti l'istruzione Redim usata da sola non fa altro che riallocare lo spazio di memoria disponibile per il vettore, reinizializzando tutti i suoi elementi e quindi di fatto cancellando i valori precedentemente assegnati. Il nome di ogni cartella è estratto attraverso la funzione Mid, che prende da una stringa (il primo parametro) un intervallo di caratteri definito da una posizione iniziale (il secondo parametro) e da una lunghezza (il terzo parametro).
Ovviamente il secondo parametro dev'essere positivo, altrimenti si verifica un errore; il terzo invece può anche essere zero (in tal caso è restituita la stringa vuota ""), basta che sia non negativo.
Nel nostro caso la posizione iniziale del nome della cartella è naturalmente il carattere successivo al penultimo backslash trovato, mentre la lunghezza del nome è calcolabile tramite la distanza tra il penultimo e l'ultimo backslash.
Ora, il ciclo appena descritto presenta alcuni inconvenienti; anzi, sono veri e propri errori:

1) prima di tutto, la funzione Ubound deve avere come argomento un vettore (o matrice) con dimensioni definite, altrimenti genera un errore: e siccome alla prima iterazione strCartelle non ha una dimensione definita, indovinate un po' che succede…
2) in secondo luogo, all'ultima iterazione intPos è uguale a 0, come si è visto prima; e in questo caso ad andare in errore è la funzione Mid, perché il terzo parametro risulterebbe negativo.

Nella prossima lezione spiegherò come risolvere gli errori: nel frattempo però sarebbe bene che ci proviate voi da soli (tanto è facile…), eventualmente spedendomi le vostre soluzioni. Per chi non lo sapesse, il mio indirizzo è:
giorgio102@libero.it
Avete tempo fino a quando sarà pubblicata la prossima lezione.