Mescolare casualmente

Nel settore Primi passi di questo sito abbiamo visto alcune procedure per ordinare i dati di una tabella nell'articolo esempio 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 esempio

 

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

  1. nella prima colonna l'elenco originale (era una volta originale!)
  2. nella seconda e terza colonna i nomi divisi
  3. nella quarta colonna gli indirizzi
  4. nella quinta colonna le città
  5. nella sesta colonna i CAP
  6. nella settima colonna i telefoni

Con una tabella cosi realizzata possiamo scatenarci con le nostre manipolazioni.

  1. La colonna A subirà la divisione dei cognomi dai nomi che metteremo rispettivamente nelle colonne B e C
  2. Le colonne che vanno dalla "B" alla "E" (dati anagrafici ed indirizzi) verranno mescolate casualmente
  3. La colonna "F" (CAP) invece la creiamo ex novo agendo sui numeri casuali.
  4. La colonne "G" (numeri telefonici) la creiamo anche ex novo agendo sui numeri casuali.

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 esempio 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