Nel settore Primi passi di questo sito abbiamo visto alcune procedure per ordinare i dati di una tabella nell'articolo
Ordinare gli in modo ordinato o casuale. L'ultima di queste procedure riguarda appunto, Ordinare in modo Casuale, esegue l'ordinamento casuale della tabella con la funzione che mette a disposizione Excel.
Questo tipo di ordinamente è possibile eseguirlo anche in ambiente VBA e faremo uso dei numeri casuali che troverete in questa pagina
Ma andiamo in ordine.
Molto spesso notate che presentando alcuni esercizi, li corredo, ove necessario, di elenchi di nomi, città, telefoni, ecc. affermando tuttavia che gli elenchi presentati sono assolutamente fittizi. Infatti anche se per fare questo attingo ad alcuni miei elenchi di contatti personali reali, riesco a renderli fittizi mescolando opportunamente in maniera RANDOM nomi e cognomi e generando addirittura falsi numeri telefonici e falsi CAP. Questa volta vorrei mostrarvi come. Naturalmente il codice si può adattare a molte altre applicazioni ed ognuno può cominciare a pensare di creare qualcosa di nuovo o di utile alle proprie esigenze.
Come esempio prendiamo la seguente tabella che mi sembra abbastanza completa
| A | B | C | D | E | F | G | |
|---|---|---|---|---|---|---|---|
| 1 | Cognome Nome | Cognome | Nome | Indirizzo | Città | CAP | Telefono |
| 2 | Migliavacca Luigi | VIA P. FIMIANI | Demonte | ||||
| 3 | Rizzi Carlo | VIA CAVOUR | Borboruso | ||||
| 4 | Liberali Franca | VIA FORNACE 11 | Malborghetto | ||||
| 5 | Di Maggio Mario | VIA DEL TUSCOLANO | Benedello | ||||
| 6 | Scicchitano Andrea | VIA DEL TUSCOLANO | Montebello Ionico | ||||
| 7 | Maggi Massimo | VIA GRAMSCI 14 A | Ville di Fano |
In questa tabella abbiamo
Con una tabella cosi realizzata possiamo scatenarci con le nostre manipolazioni.
Vediamo come.
La colonna A: suddividere i cognomi dai nomi e trascriverli nelle colonne B e C
per questa useremo la tecnica illustrata nell'articolo Suddividere il testo di una cella
da cui possiamo prendere anche la routine
Sub DividiParole()
Dim PriCella As String, Ucella As String
Dim MiaStringa As String
Dim CL As Range
Dim MiaPos As Integer
Ucella = Range("A2").End(xlDown).Address
For Each CL In Range("A2:" & Ucella)
MiaStringa = CL
MiaPos = InStrRev(MiaStringa, " ", -1)
CL.Offset(0, 1) = Left(MiaStringa, MiaPos - 1)
CL.Offset(0, 2) = Mid(MiaStringa, MiaPos + 1)
'in alternativa possiamo usare le seguenti
'CL.Offset(0, 1) = Mid(MiaStringa, MiaPos + 1, Len(MiaStringa) - MiaPos)
'CL.Offset(0, 2) = Right(MiaStringa, Len(MiaStringa) - MiaPos)
Next
End Sub
Questa la tabella dopo l'esecuzione di questo codice:
| A | B | C | D | E | F | G | |
|---|---|---|---|---|---|---|---|
| 1 | Cognome Nome | Cognome | Nome | Indirizzo | Città | CAP | Telefono |
| 2 | Migliavacca Luigi | Migliavacca | Luigi | VIA P. FIMIANI | Demonte | ||
| 3 | Rizzi Carlo | Rizzi | Carlo | VIA CAVOUR | Borboruso | ||
| 4 | Liberali Franca | Liberali | Franca | VIA FORNACE 11 | Malborghetto | ||
| 5 | Di Maggio Mario | Di Maggio | Mario | VIA DEL TUSCOLANO | Benedello | ||
| 6 | Scicchitano Andrea | Scicchitano | Andrea | VIA DEL TUSCOLANO | Montebello Ionico | ||
| 7 | Maggi Massimo | Maggi | Massimo | VIA GRAMSCI 14 A | Ville di Fano |
Mescolare i dati dalla colonna B alla colonna E
A questo punto possiamo cominciare a divertirci coi mescolamenti:
La routine sarà suddivisa in diversi segmenti:
richiesta della colonna da mescolare (si da la possibilità all'utente di scegliere la colonna da mescolare)
Colonna = Val(InputBox("quale colonna mescolare?", "scelta colonna"))
creazione di una Matrice a due dimensioni:
nella prima dimensione verranno raccolti i dati dalla Colonna indicata
nella seconda colonna verranno memorizzati dei numeri casuali
ReDim Matrice(1 To .Rows.Count, 1 To 2)
riempimento della matrice a due dimensioni coi dati che si trovano nella colonna scelta, nella prima colonna, e con una serie di numeri casuali nella seconda colonna
With Range("A2:" & URiga)
For Riga = 1 To .Rows.Count
Matrice(Riga, 1) = .Item(Riga, Colonna)
Matrice(Riga, 2) = Rnd()
Next
ordinamento della matrice in base alla seconda colonna (i numeri casuali): usiamo il Bubble Short che è una delle tecniche di ordinamento
For Riga = 1 To UBound(Matrice, 1) - 1
For R = Riga + 1 To UBound(Matrice, 1)
If Matrice(Riga, 2) > Matrice(R, 2) Then
Temp1 = Matrice(Riga, 1)
Temp2 = Matrice(Riga, 2)
Matrice(Riga, 1) = Matrice(R, 1)
Matrice(Riga, 2) = Matrice(R, 2)
Matrice(R, 1) = Temp1
Matrice(R, 2) = Temp2
End If
Next
Next
alla fine rimettiamo i dati memorizzati nelle prima colonna della matrice e ordinati (mescolati) in base alla seconda colonna della stessa matrice dove avevamo i numeri casuali.
For Riga = 1 To UBound(Matrice, 1)
.Item(Riga, Colonna) = Matrice(Riga, 1)
Next
Questo il codice completo per questa routine:
Sub Mescola()
Dim URiga As String
Dim Riga, R, Colonna
Dim Matrice()
Dim Temp1, Temp2
URiga = Range("A2").End(xlDown).Address
' richiesta della colonna da mescolare
Colonna = Val(InputBox("quale colonna mescolare?", "scelta colonna"))
If Colonna = "" Then Exit Sub
If IsNumeric(Colonna) Then
If Colonna < 2 Or Colonna > 5 Then Exit Sub
' creazione di una Matrice a due dimensioni
' nella prima dimensione verranno raccolti i dati dalla Colonna indicata
' nella seconda colonna verranno memorizzati dei numeri casuali
With Range("A2:" & URiga)
ReDim Matrice(1 To .Rows.Count, 1 To 2)
Randomize
' riempimento della matrice
For Riga = 1 To .Rows.Count
Matrice(Riga, 1) = .Item(Riga, Colonna)
Matrice(Riga, 2) = Rnd()
Next
' ordinamento della matrice in base alla seconda colonna (i numeri casuali)
For Riga = 1 To UBound(Matrice, 1) - 1
For R = Riga + 1 To UBound(Matrice, 1)
If Matrice(Riga, 2) > Matrice(R, 2) Then
Temp1 = Matrice(Riga, 1)
Temp2 = Matrice(Riga, 2)
Matrice(Riga, 1) = Matrice(R, 1)
Matrice(Riga, 2) = Matrice(R, 2)
Matrice(R, 1) = Temp1
Matrice(R, 2) = Temp2
End If
Next
Next
' trascrizione sul foglio della prima colonna (i dati precedentemente raccolti)
For Riga = 1 To UBound(Matrice, 1)
.Item(Riga, Colonna) = Matrice(Riga, 1)
Next
End With
End If
End Sub
Ora la tabella assume questo nuovo aspetto:
| A | B | C | D | E | F | G | |
|---|---|---|---|---|---|---|---|
| 1 | Cognome Nome | Cognome | Nome | Indirizzo | Città | CAP | Telefono |
| 2 | Migliavacca Luigi | Di Maggio | Andrea | VIA P. FIMIANI | Borboruso | ||
| 3 | Rizzi Carlo | Maggi | Massimo | VIA GRAMSCI 14 A | Montebello Ionico | ||
| 4 | Liberali Franca | Migliavacca | Franca | VIA DEL TUSCOLANO | Malborghetto | ||
| 5 | Di Maggio Mario | Rizzi | Carlo | VIA CAVOUR | Demonte | ||
| 6 | Scicchitano Andrea | Liberali | Luigi | VIA FORNACE 11 | Benedello | ||
| 7 | Maggi Massimo | Scicchitano | Mario | VIA DEL TUSCOLANO | Ville di Fano |
Creazione dei CAP in modo casuale nella colonna F
Fatto questo non ci resta che creare in modo casuale la serie di CAP e di telefoni.
Il CAP è composto da 5 cifre, quindi istruiamo un ciclo esterno che scorra tutte le righe dell'intervallo in oggetto, ed un altro ciclo interno che va fino a 5 (le cifre del CAP) che crea in modo casuale il CAP.
Per ottenere una sequenza di numeri che vanno da 0 a 9 la istruzione Rnd() va impostata in questo modo: Int(Rnd() * 10)
La formattazione preventiva della cella che deve ospitare il CAP in formato stringa serve per far visualizzare gli eventuali 0 (zero) iniziali
Sub creaCAP()
Dim URiga, Riga, C
Dim Codice As String
URiga = Range("A2").End(xlDown).Address
With Range("A2:" & URiga)
Randomize
For Riga = 1 To .Rows.Count
Codice = ""
For C = 1 To 5
Codice = Codice & Int(Rnd() * 10)
Next
.Item(Riga, 6).NumberFormat = "@"
.Item(Riga, 6) = CStr(Codice)
Next
End With
End Sub
La tabella coi CAP casuali
| A | B | C | D | E | F | G | |
|---|---|---|---|---|---|---|---|
| 1 | Cognome Nome | Cognome | Nome | Indirizzo | Città | CAP | Telefono |
| 2 | Migliavacca Luigi | Di Maggio | Andrea | VIA P. FIMIANI | Borboruso | 07497 | |
| 3 | Rizzi Carlo | Maggi | Massimo | VIA GRAMSCI 14 A | Montebello Ionico | 93560 | |
| 4 | Liberali Franca | Migliavacca | Franca | VIA DEL TUSCOLANO | Malborghetto | 71258 | |
| 5 | Di Maggio Mario | Rizzi | Carlo | VIA CAVOUR | Demonte | 05747 | |
| 6 | Scicchitano Andrea | Liberali | Luigi | VIA FORNACE 11 | Benedello | 05336 | |
| 7 | Maggi Massimo | Scicchitano | Mario | VIA DEL TUSCOLANO | Ville di Fano | 93781 |
Creazione dei numeri telefonici comprensivi di prefisso in modo casuale nella colonna G
Leggermente più complessa è la creazione dei numeri telefonici.
Il numero è composto dal prefisso e dal numero vero e proprio.
La difficoltà più importante è data dalla lunghezza delle singole parti.
Il prefisso deve essere composto da 2 a 5 cifre
Il numero lo voglio da 4 a 7 cifre.
La sintassi da usare per ottenere un numero casuale compreso tra un minimo ed un massimo è:
Int((limitesup - limiteinf + 1) * Rnd + limiteinf)
quindi dovremmo impostare la formula in questo modo:
prefisso:
For Lunghezza = 1 To Int((5 - 2 + 1) * Rnd()) + 2
numero:
For Lunghezza = 1 To Int((7 - 4 + 1) * Rnd()) + 4
Normalmente il prefisso inizia con la cifra 0. Allora inizializziamo le due variabili per il prefisso e per il numero in questo modo:
Pref = "0": Numero = ""
Da questo deriva che per il prefisso, la cui variabile inizia già con uno 0 (zero), dobbiamo richiedere una lunghezza inferiore e superiore di una unità:
For Lunghezza = 1 To Int((4 - 1 + 1) * Rnd()) + 1
Questo che segue potrebbe essere un possibile codice:
Sub creaTEL()
Dim URiga, Riga, C
Dim Pref, Numero
Dim Lunghezza
URiga = Range("A2").End(xlDown).Address
With Range("A2:" & URiga)
Randomize
For Riga = 1 To .Rows.Count
Pref = "0": Numero = ""
'creazione del prefisso
For Lunghezza = 1 To Int((4 - 1 + 1) * Rnd()) + 1
Pref = Pref & Int(Rnd() * 9) + 1
Next
'creazione del numero
For Lunghezza = 1 To Int((7 - 4 + 1) * Rnd()) + 4
Numero = Numero & Int(Rnd() * 10)
Next
'scrittura dell'intero numero nella settima colonna
.Item(Riga, 7).NumberFormat = "@"
.Item(Riga, 7) = Pref & " " & Numero
Next
End With
End Sub
La configurazione finale della tabella dovrebbe essere simile alla seguente:
| A | B | C | D | E | F | G | |
|---|---|---|---|---|---|---|---|
| 1 | Cognome Nome | Cognome | Nome | Indirizzo | Città | CAP | Telefono |
| 2 | Migliavacca Luigi | Di Maggio | Andrea | VIA P. FIMIANI | Borboruso | 07497 | 05294 7531260 |
| 3 | Rizzi Carlo | Maggi | Massimo | VIA GRAMSCI 14 A | Montebello Ionico | 93560 | 0427 1049071 |
| 4 | Liberali Franca | Migliavacca | Franca | VIA DEL TUSCOLANO | Malborghetto | 71258 | 06915 248943 |
| 5 | Di Maggio Mario | Rizzi | Carlo | VIA CAVOUR | Demonte | 05747 | 066 48126 |
| 6 | Scicchitano Andrea | Liberali | Luigi | VIA FORNACE 11 | Benedello | 05336 | 0168 444296 |
| 7 | Maggi Massimo | Scicchitano | Mario | VIA DEL TUSCOLANO | Ville di Fano | 93781 | 027 9996 |
Questo è tutto per questa volta. Buon lavoro