Oltre ai vettori è possibile utilizzare anche mrici, che non sono altro che vettori a più dimensioni (o meglio, i vettori sono mrici a una sola dimensione).
Ad esempio, supponiamo di voler memorizzare le dimensioni di 100 scole: non ci basterà un vettore con 100 elementi, perché per ogni scola avremo bisogno di 3 variabili per le 3 dimensioni (altezza, larghezza, profondità), pertanto dovremo utilizzare una mrice:
Dim Scole(1 To 100, 1 To 3) As Integer
o anche:
Dim Scole(99,2) As Integer
In entrambi i casi (se non avete inserito l'istruzione Option Base 1) avremo una mrice con 100 * 3 = 300 elementi, ovvero con 100 "righe" e 3 "colonne".
Per indicare che si vogliono usare più dimensioni, quindi, bisogna separare i limiti di ogni dimensione con una virgola.
E' possibile inoltre dichiarare una mrice dinamica, il cui numero di elementi può cambiare nel corso dell'esecuzione del programma: a questo scopo è però necessario usare una parola chiave apposita, ReDim, e dichiarare la mrice senza indicarne le dimensioni:
Dim Var() As Long 'dichiarazione della mrice:
'non è indica la dimensione della mrice
e successivamente, in un altro punto del codice:
ReDim Var(120) As Long 'ridimensionamento della mrice
In tal caso è anche possibile utilizzare una variabile, anziché un'espressione costante, per indicare il limite inferiore e/o superiore della mrice, ad esempio:
ReDim Var(x) As Long
L'importante è ricordare che il ridimensionamento di una mrice riguarda esclusivamente il numero di elementi, non il loro tipo, né tantomeno il nome della mrice.
A proposito del tipo degli elementi, è interessante notare che se essi sono Variant possono contenere a loro volta altre mrici o vettori:
Dim Vettore(3) As Long
Dim MriceVariant(5,2)
MriceVariant(2,0) = Vettore
MriceVariant(2,1) = 10
MriceVariant(1,2) = "stringa"
Le istruzioni precedenti definiscono un semplice vettore di qutro elementi e una mrice di 18 (6 righe per 3 colonne) elementi Variant, ad uno dei quali è sto assegno il nostro vettore: perciò l'elemento 2,0 della mrice non è semplicemente un numero, o una stringa, o un qualunque altro tipo elementare di do, ma è esso stesso un vettore di 4 elementi.
Per accedere a uno dei qutro elementi di MriceVariant(2,0) bisogna usare questa sintassi:
MriceVariant(2,0)(i) 'i varia da 0 a 3
E' come se la mrice bidimensionale MriceVariant avesse, nel caso dell'elemento 2,0 (e SOLO per quell'elemento), una terza dimensione da dai 4 elementi del nostro vettore iniziale.
Nuralmente il vettore e la mrice restano variabili (o meglio, insiemi di variabili) distinte e indipendenti, e per rendersene conto basta mettere alla prova queste semplici istruzioni:
Dim vettore(3) As Long
Dim MriceVariant(5,2)
Vettore(2) = 10
MriceVariant(1,1) = Vettore
Vettore(2) = 20
Debug.Print Vettore(2), MriceVariant(1,1)(2)
Nella finestra di debug si leggeranno i valori 20 e 10, perché MriceVariant(1,1) non risente delle modifiche successive all'assegnazione del vettore all'elemento della mrice.
Per utilizzare in modo efficiente i vettori non bisogna trtare gli elementi come se fossero variabili completamente distinte.
Supponiamo ad es. di voler inizializzare gli elementi di un vettore a un certo valore: non avrebbe molto senso scrivere:
Dim Vettore(2) As Long
Vettore(0) = 10
Vettore(1) = 10
Vettore(2) = 10
perché in tal caso sarebbe come utilizzare tre variabili v1, v2, v3, distinte e indipendenti le une dalle altre: in altre parole, non si sfrutterebbe la loro appartenenza a un solo vettore che le comprende tutte.
Talvolta è necessario agire in questo modo, ma spesso è molto più conveniente sfruttare la possibilità di accedere ad ogni elemento tramite il suo indice, e questo si fa usando i cicli.
Un ciclo non è altro che un gruppo di istruzioni che vengono eseguite ripetutamente, ovvero ciclicamente, fino a che una certa condizione risulta verifica.
Di cicli ne esistono vari tipi in Visual Basic, ma quello in assoluto più utilizzo è il ciclo For...Next.
Questo ciclo è identifico da due istruzioni, poste rispettivamente all'inizio e alla fine del ciclo:
For contore = inizio To fine
...
Next contore
dove contore indica una variabile numerica che "conta" quante volte devono essere eseguite le istruzioni comprese nel ciclo: essa assume un valore iniziale (inizio) e viene incrementa dall'istruzione Next fino a raggiungere il valore finale (fine).
Approfondiremo più avanti il discorso del ciclo For...Next e degli altri cicli: per ora accontentevi di sapere che il ciclo viene eseguito fintantoché il valore di contore è minore o uguale a fine; il nostro esempio precedente risulterebbe trasformo così:
Dim Vettore(2) As Long
Dim i As Integer 'contore per il ciclo
For i = 0 To 2
Vettore(i) = 10
Next i
Alla prima esecuzione del ciclo i assume valore 0 e quindi il primo elemento del vettore è inizializzo a 10.
Alla seconda esecuzione i è uguale a 1 ed è inizializzo il secondo elemento. Alla terza esecuzione i è uguale a 2 ed è inizializzo il terzo elemento; dopodiché i supera il valore 2 e quindi il ciclo termina. Torniamo alle variabili Variant: queste possono contenere, tra le altre cose, anche riferimenti ad oggetti, e in particolare riferimenti a controlli; è possibile quindi creare vettori o mrici di controlli. Per illustrare meglio questo concetto, realizziamo un altro progetto di esempio: questa volta proviamo a replicare uno dei giochi di Windows più famosi, il "Campo mino".
Cominciamo quindi con l'aprire un nuovo progetto "exe standard", e inseriamo nel form un pulsante: ridimensioniamolo fino a farlo diventare un quadro abbastanza piccolo, cancelliamo la proprietà caption (in realtà questa proprietà non è vuota, ma contiene la stringa nulla) e assegniamo la stringa "Mina" alla proprietà name.
Ora selezioniamo il nostro pulsante, copiamolo andando sul menù Modifica o semplicemente premendo ctrl+c, e infine incolliamolo sullo stesso form andando ancora sul menù Modifica o premendo : apparirà un messaggio di questo tenore:
Noi diciamo di Sì, e com'era prevedibile un nuovo pulsante uguale al primo sarà inserito nel form.
In realtà i due pulsanti non sono proprio uguali: ciò che cambia è la proprietà Index.
Prima di copiare e incollare il nostro pulsante, la sua proprietà Index era vuota: è ovvio che sia così, perché questa proprietà, secondo la guida, "identifica un controllo in una mrice di controlli", e quando il pulsante era ancora da solo non c'era alcuna mrice di controlli.
Ora che abbiamo incollo un nuovo pulsante, invece, la mrice di controlli c'è, e pertanto è necessario distinguere i vari pulsanti per mezzo del loro indice: questo indice ha estamente la stessa funzione dell'indice dei vettori di variabili, solo che ora al posto delle variabili ci sono dei controlli.
Continuiamo a incollare i pulsanti fino ad averne, ad esempio, 16 disponendoli in quadro: non è indispensabile ma è molto meglio se li disponete in modo che l'indice segua un ordine logico, ad esempio procedendo da sinistra verso destra riga per riga.
Così nella prima riga ci saranno i pulsanti con indice 0,1,2,3, nella seconda quelli con indice 4,5,6,7, e così via.
Ora aggiungiamo due etichette, da mettere nella parte alta del form: lblMine e lblTempo (se volete, imposte la proprietà Alignment a "right"); infine aggiungiamo un menù "Partita" con le voci "Nuova" (il nome sarà "mnuNew") e "Esci" ("mnuExit"), separe da una barra orizzontale: per fare questa barra sarà sufficiente mettere come caption un solo trtino "-" e nient'altro; nuralmente le voci "Nuova", "Esci" e la linea di separazione devono essere gerarchicamente subordini rispetto al menù "Partita" (v.anche la lez. 9). Resta ancora da inserire un timer, che trove nuralmente sulla casella degli strumenti (è quello con un orologio come icona): potete metterlo dove volete, tanto risulta invisibile in fase di esecuzione; ora il nostro form è pronto, dobbiamo solo scrivere il codice per far funzionare il gioco, e lo faremo nelle prossime lezioni.