T Tu ut to or ri ia al 1 1: L La t to om mb bo ol la G Ge

Transcript

T Tu ut to or ri ia al 1 1: L La t to om mb bo ol la G Ge
Lezione 17 Excel VBA Tutorial 1: La tombola
Generare numeri
casuali
Generare numeri casuali Nei moduli precedenti del corso ci siamo occupati delle basi di VBA, da questa lezione in avanti vi proponiamo dei mini progetti in cui potrete applicare quanto imparato oltre a scoprire funzioni, oggetti, metodi,… nuovi. Tutto quello che imparerete poterete poi riapplicarlo nei vostri progetti personali. Abbiamo pensato di proporvi tre tutorial in cui realizzeremo tre semplici progetti In modo da affrontare molti dei piccoli problemi che vi si possono presentare lavorando con VBA. Cominceremo realizzando una tombola. Avrete a disposizione una cartella con 15 numeri che vanno da 1 a 90, generati casualmente, con un pulsante potrete estrarre i numeri da un ipotetico sacchetto di 90 numeri. Se sulla vostra cartella c’è il numero estratto, questo sarà evidenziato automaticamente. La prima volta che su un riga della cartella saranno evidenziati due numeri, avrete fatto ambo. Se i numeri sono tre, terno, se cinque, cinquina. Se 15 tombola. Per evitare di complicare troppo le cose, procederemo passo per passo. In questa lezione impareremo a generare numeri casuali, quindi a verificare che non si ripetano. Poi li scriveremo nella colonna A del nostro file, in modo che i numeri estratti siano sempre visibili. Cominciamo subito. Create un file nuovo e aggiungete un pulsante che chiameremo cmdEstrai. Fate doppio clic su di esso e completate la routine sub che gestisce il clic sul pulsante come segue Private Sub cmdEstrai_Click() Randomize intNumEstratto = Round(Rnd() * 89) + 1 ActiveCell = intNumEstratto End Sub
Alessandra Salvaggio ­ Merlin Wizard DMC © 2007 Tutti i diritti riservati 1
Excel VBA Lezione 17 All’inizio del foglio di codice dichiarate la variabile intNumeEstratto con tipo integer (Figura 1). Figura 1 Per ora ci limitiamo a generare un numero casuale compreso fra 1 e 90 e a scriverlo nella cella attiva. Vediamo di capire come abbiamo fatto. La funzione Rnd() restituisce un numero casuale compreso fra 0 e 1. Per ottenere un numero maggiore di 1 e compreso fra altri due numeri occorre utilizzare questa formula Int((limiteSuperiore ­ limiteInferiore + 1) * Rnd + limiteInferiore) Che nel nostro caso diventa Int((90­1+1) * Rnd + 1) Ossia Int(90 * Rnd + 1) Con la funzione I nt prendiamo solo la parte intera del numero. L’istruzione Randomize serve per inizializzare il generatore di numeri casuali. Fin qui tutto bene, ma ora dobbiamo correggere la nostra routine in modo che i numeri estratti siano univoci, cioè che ogni volta che estraiamo un numero sia sicuramente diverso. Occorrerà lavorare un po’. Intanto correggete la routine che gestisce l’evento clic sul pulsante come segue Private Sub cmdEstraiNumero_Click() Dim blnEstratto As Boolean Dim blnTrovato As Boolean Dim y As Integer Randomize If intEstrazioni < 90 Then Do Until blnEstratto = True Or intEstrazioni = 90
Alessandra Salvaggio ­ Merlin Wizard DMC © 2007 Tutti i diritti riservati 2 Excel VBA Lezione 17 blnTrovato = False intNumEstratto = Int((90 ­ 1 + 1) * Rnd + 1) For y = 0 To intEstrazioni If IntNumeriEstratti(y) = intNumEstratto Then blnTrovato = True Exit For End If Next If blnTrovato = False Then intEstrazioni = intEstrazioni + 1 IntNumeriEstratti(intEstrazioni) = intNumEstratto Range("A" & intEstrazioni) = intNumEstratto blnEstratto = True End If Loop Else MsgBox "hai già estratto tutti i numeri" End If End Sub All’inizio del foglio di codice dichiarate anche le variabili Dim IntNumeriEstratti(90) As Integer Dim intNumEstratto As Integer Dim intEstrazioni As Integer Il codice non è eccessivamente lungo, ma presenta diverse novità. Analizziamole una per una. Cominciamo proprio dalla dichiarazione delle variabili. La prima delle variabili che vi ho indicato usa una sintassi che non abbiamo ancora incontrato, infatti, dopo il nome della variabile, fra parentesi abbiamo posto un numero intero. Dim IntNumeriEstratti(90) As Integer Si tratta di un Array, ossia una variabile che può contenere più di un valore. Ogni valore occupa una posizione numerata da 0 in avanti, nel nostro caso ci sono 91 valori possibili da 0 a 90 appunto. In questo array memorizzeremo via via i numeri che andremo a estrarre, così ad ogni nuova estrazione potremo verificare se il numero estratto è già stato
Alessandra Salvaggio ­ Merlin Wizard DMC © 2007 Tutti i diritti riservati 3 Excel VBA Lezione 17 estratto (e quindi occorre scartarlo e ripetere l’estrazione) o è nuovo (e quindi possiamo accettarlo. Vedremo più avanti come fare praticamente. Nella variabile intEstrazioni andremo a memorizzare il numero di estrazioni andate a buon fine, cioè quelle in cui il numero risulta non ripetuto. Il numero massimo di estrazioni deve essere 90. Infatti, una nuova estrazione viene effettuata solo se il numero il numero di estrazioni già effettuate è minore di 90 (If intEstrazioni < 90) in caso contrario viene mostrato un messaggio all’utente che lo informa che le estrazioni possibili sono già state tutte effettuate (Else: MsgBox "hai già estratto tutti i numeri"). Passiamo ora a vedere come viene effettuata l’estrazione. Il tutto avviene in un ciclo Do Until … loop che abbiamo imparato ad usare nella lezione di ieri. Usiamo la variabile blnEstratto per verificare che l’estrazione sia avvenuta. Il ciclo viene ripetuto fino a che questa variabile non assume valore True o fino a quando le estrazioni sono 90. All’interno del ciclo Do Until … loop usaiamo la variabile blnTrovato per verificare se il numero estratto è nuovo o ripetuto. All’inizio del loop cioè a ogni nuovo ciclo assegniamo a questa variabile il valore False. Se alla fine del ciclo (per ora lasciate un attimo da parte il ciclo For .. Next, ne parleremo più sotto), con una istruzione If verifichiamo se questa variabile è ancora falsa If blnTrovato = False Then intEstrazioni = intEstrazioni + 1 IntNumeriEstratti(intEstrazioni) = intNumEstratto Range("A" & intEstrazioni) = intNumEstratto blnEstratto = True End If In caso positivo, cioè se la condizione si verifica, incrementiamo il numero delle estrazioni avvenute con successo (intEstrazioni = intEstrazioni + 1), accettiamo il numero estratto e lo memorizziamo fra quelli estratti (IntNumeriEstratti(intEstrazioni) = intNumEstratto), scriviamo il numero in una nuova riga della colonna A ( Range("A" & intEstrazioni) = intNumEstratto), assegnamo alla variabile blnTrovato il valore true (blnEstratto = True ) in modo da interrompere il loop (non occorre estrarre altri numeri). Queste istruzione vi sono tutte note (quindi non c’è bisogno di rispiegarle), tranne I ntNumeriEstratti(intEstrazioni) = intNumEstratto. Concentriamoci un po’ si di essa. Ricordate che IntNumeriestratti è un array che può contenere diversi valori. Quando abbiamo creato questo array ci siamo limitati a indicare quanti valori poteva memorizzare al suo interno. Ora andiamo a specificare quali sono questi
Alessandra Salvaggio ­ Merlin Wizard DMC © 2007 Tutti i diritti riservati 4 Excel VBA Lezione 17 valori. Li inseriamo uno alla volta, ogni volta che vengono estratti. Per indicare in quale posizione (indice) metterli usiamo il valore assunto da intEstrazioni. Alla prima estrazione il valore sarà memorizzato in posizione 1, poi in posizione 2 e così via. Considerate che sia IntNumeriEstratti che intEstrazioni sono state dichiarate all’inizio del foglio di codice e non all’interno della rountine cmdEstraiNumero. In questo caso conservano il loro valore fin che il file è aperto. Dunque ogni volta che si preme il pulsante cmdEstraiNumero possiamo leggere il loro valore. Facciamo ora un passo indietro e torniamo all’istruzione For … Next. All’interno di questa istruzione andiamo a verificare se il numero è già stato estratto. For y = 0 To intEstrazioni If IntNumeriEstratti(y) = intNumEstratto Then blnTrovato = True Exit For End If Next Vediamo un po’ come si effettua questa verifica. Dobbiamo andare a controllare tutti i numeri memorizzati nell’array IntNumeriEstratti, quindi utilizziamo la variabile y per specificare il suo indice. Quando y vale 1 la verifica sarà fra il numero estratto e il valore che si trova in posizione 1 nell’array e il numero estratto, quando vale 2 la verifica sarà fra il numero estratto e il valore che si trova in posizione 2 nell’array e così via. Se il numero viene trovato blnTrovato assume valore True e si interrompe la ricerca. L’istruzione Exit For termina, infatti l’esecuzione di un ciclo for. Avrete già capito che se blnTrovato ha valore True, non si verifica la condizione dell’istruzione If che abbiamo analizzato prima. Il numero dunque non è accettato, né memorizzato nell’array. Il numero di estrazioni non viene incrementato. Si passa ad estrarre un nuovo numero che poi sarà verificato e così via. Array creati col contenuto Prima di concludere questa lezione, dobbiamo ricordare che è anche possibile specificare fin dall’inizio i valori che deve contenere un array. Basta specificarli in fase di creazione del’array stesso. Questa soluzione è utile quando i valori dell’array non cambiano durante l’esecuzione del codice. Facciamo un esempio semplice (domani torneremo alla nostra tombola) Su un foglio abbiamo inserito un pulsante cmdDataOggi. Premendo questo pulsante vogliamo che Excel ci informi su quale è il giorno della settimana corrente.
Alessandra Salvaggio ­ Merlin Wizard DMC © 2007 Tutti i diritti riservati 5 Excel VBA Lezione 17 Completate come segue la routine che gestisce l’evento clic sul pulsante cmdDataOggi Private Sub cmdDataOggi_Click() Dim Data As Variant Dim giorno As Integer Dim GiornoSettimana As Variant Dim giorni As Variant giorni = Array(" Lunedì" , " M artedì" , " Mercoledì" , _ " Giovedì" , " Venerdì" , " Sabato" , " Domenica" ) Data = Date giorno = Weekday(Data, vbMonday) GiornoSettimana = giorni(giorno ­ 1) MsgBox "oggi è " & GiornoSettimana End Sub L’array viene creato dalle istruzioni in grassetto. Dichiariamo la variabile che lo rappresenta, poi lo riempiamo dei valori che deve contenere. I valori vanno sempre separati da una virgola. Il resto del codice non è difficile. Memorizziamo nella variabile Data la data di sistema. La data di sistema ci viene restituita dalla funzione Date. Date restituisce un valore di tipo Variant, quindi, anche la variabile che la ospita deve essere definita in questo modo. Una volta creata la data, con la funzione W eekday andiamo a leggere il giorno della settimana corrispondente alla data corrente. Nella funzione Weekday abbiamo specificato, con la costante vbMonday che vogliamo che il giorno 1 della settimana sia Lunedì (altrimenti, per impostazione predefinita, il primo giorno della settimana è considerata la domenica). Una volta ricavato il numero del giorno (Lunedì = 1, Martedì = 2,…) Lo usiamo per specificare la posizione dell’Array che volgiamo leggere. Al valore ricavato dobbiamo togliere 1, infatti la prima posizione di un array ha sempre valore 0.
Alessandra Salvaggio ­ Merlin Wizard DMC © 2007 Tutti i diritti riservati 6