Ordinamento Multiplo di Dati in un elenco con scelta della chiave di ordinamento. - dal 04/09/04 pagina vista: volte

Questo articolo integra l'altro "Ordinare Elenco Dati" presente sul sito padre. Ci occuperemo di ordinamento basato su più chiavi di ricerca.

Esistono, per quanto riguarda un ordinamento, più di un'esigenza, legata a ciò che vogliamo ordinare e al tipo di impostazione che diamo alle nostre tabelle. In questo articolo ci occuperemo di due modi di ordinamento.

  • Ordinamento di dati correlati ad una chiave di ricerca, resa variabile (quindi multipla) per ogni campo (a scelta) che forma la tabella, con "movimento" dei dati correlati.

  • Ordinamento di una tabella formata da molti campi con ordinamento "indipendente" per ogni singola colonna.

Il primo caso: sappiamo che Excel concede di usare al massimo tre sole chiavi di ricerca, impostando a scalare, tre campi di un elenco o tabella di un foglio di lavoro. Vediamo un esempio di una tabella tipica: un elenco di nomi con dati correlati:

e supponiamo di volere un ordinamento basato sul nome, poi su valori, infine su data. Se noi attiviamo il registratore di macro, ed impostiamo l'ordinamento nell'ordine su esposto, alla fine ci troveremo con questo codice compilato:

Sub Macro1()
Range("A2:D10").Sort Key1:=Range("B2"), Order1:=xlAscending, Key2:=Range( _
"C2"), Order2:=xlAscending, Key3:=Range("D2"), Order3:=xlAscending, _
Header:=xlGuess, OrderCustom:=1, MatchCase:=False, Orientation:= _
xlTopToBottom, DataOption1:=xlSortNormal, DataOption2:=xlSortNormal, _
DataOption3:=xlSortNormal
End Sub

Come si nota, l'ordinamento è impostato su tutta l'area dati (A2:D10), e come SortKey vengono indicati i riferimenti alle celle dei campi prescelti. Se a questo punto lanciamo la macro, ci troveremo con questa situazione:

L'ordinamento è stato eseguito correttamente; vediamo infatti che la tabella si è disposta con i nomi in ordine alfabetico, e i dati correlati sono stati spostati insieme al nome. Condizione questa molto importante da non dimenticare: quando si ordina un elenco, i dati correlati alla chiave di ordinamento DEVONO seguire la chiave prescelta. Il motivo è ovvio. Ma il nostro ordinamento, non doveva eseguire anche l'ordinamento sui valori, e poi sulle date? Non avevamo impostato tre chiavi di ordinamento? E meno male che questo tipo di ordinamento in realtà osserva SOLO la prima chiave di ordinamento, altrimenti ci saremmo trovati che il Signor "ac" otterrebbe il valore "10" (che non è il suo) con la data "25/12/02" (che non è la sua), e se questa fosse stata una tabella di imputazione provvigioni ad Agenti, ne sarebbe nato un bel casotto.

Bisogna precisare che un Ordinamento Multiplo si può verificare solo quando del primo criterio di ricerca esistono più valori uguali: infatti se avessimo più campi dove è uguale il primo criterio "nome", l'istruzione (Macro1) provvederebbe al secondo ordinamento basato sul criterio "valore", e solo se con lo stesso "nome" si trovassero più "valori" uguali, si avrebbe l'ordinamento di questi , sul terzo criterio "data". Avremmo dovuto trovare però una tabella come questa (immagine sotto a sinistra): dove nel campo "nomi" (primo criterio di ordinamento) esistono più valori uguali, e dove esistono anche più "valori" uguali. In questo caso, con la Macro1(), otterremo un'ordinamento che terrà conto anche del terzo criterio (le date), come si può notare nell'immagine a destra:

Ovviamente viene rispettato l'ordinamento nell'ordine scelto: prima i nomi, a nome uguale vengono ordinati i valori, e solo se si trovano valori uguali, si ordinano questi valori uguali per data. (vedi esempio sul nome "az" dove il valore 40 è il primo valore anche se la data è successiva alle date degli agli altri due valori (comunque ordinati per data)).

L'unica maniera che io conosco per rendere un ordinamento veramente multiplo (inteso come ordinamento variabile), è rendere la chiave di ordinamento "variabile". Soltanto così potremo scegliere di vedere ordinati i nostri dati in funzione di una chiave diversa, ma ottenendo che i dati correlati SI MUOVANO insieme alla chiave. Potremo così decidere di ordinare sui "valori", oppure su una "data" oltre al "nome", e di essere sicuri che i dati correlati resteranno allineati sulla stessa riga. Un accorgimento utile sarà quello di inserire un campo "progressivo", dove inseriremo i numeri a partire da 1, e che ci servirà per usare il campo "prog" come chiave di ordinamento per riavere la tabella come era all'origine.

Vediamo ora la routine. Ho scelto di usare una InputBox per richiedere la lettera di Colonna che ospita la chiave di ordinamento, La lettera potrà essere scritta sia in minuscolo che in maiuscolo:

Sub OrdinaAScelta()

'sotto: usiamo una variabile "Campo" per memorizzare la lettera di colonna
Campo = InputBox("Inserire la lettera di Colonna del campo da ordinare")
If Campo = "" Then Exit Sub
'se non scriviamo niente o si preme Annulla si esce dalla routine
'sotto: indichiamo l'area da ordinare (A2:D10) impostando come SortKey1 la lettera di colonna 'ottenuta con "Campo" per la riga 2
Range("A2:D10").Sort Key1:=Range("" & Campo & "2"), Order1:=xlAscending, _
Header:=xlGuess, OrderCustom:=1, MatchCase:=False, Orientation:= _
xlTopToBottom

End Sub

Questa l'immagine della InputBox, dove scegliamo do ordinare i dati sulla chiave "valori" (colonna C):

e questo il risultato, dove vediamo i dati ordinati sui valori, ma con i dati correlati mossi insieme al valore di pertinenza (vedi stesso colore riga):

Per riavere l'ordinamento iniziale sarà sufficiente rilanciare la macro scegliendo la lettera "a". Ovviamente questo esercizio si presta ad ottenere un numero elevato di ordinamenti, dipenderà da quanto sarà ampia la nostra tabella.

Ordinamento multiplo su un'area dati  ma con ordinamento indipendente per ogni singola colonna dell'area.

Secondo caso: a differenza dell'esempio precedente, che opera solo sulla prima chiave di ricerca (nonostante si siano scelti tre criteri diversi) per effetto della selezione di TUTTA l'area da ordinare ( Range("A2:D10") ) in questo esercizio selezioneremo soltanto un campo (colonna) per volta, e su questo applicheremo l'ordinamento. Per poter effettuare un ordinamento su ogni colonna di tutte le colonne presenti nell'area dati (che corrisponde quindi ad un ordinamento multiplo su più chiavi di ordinamento) useremo un ciclo For...Next, che partendo dalla prima colonna che ci interessa, prosegui fino all'ultima. Per questo esempio useremo una tabella formata da valori numerici, come questa sotto, le righe sono colorate per meglio identificare l'effetto dell'ordinamento che applicheremo:

Lo scopo sarà quello di ottenere, per ognuno dei 7 campi (o colonne ) un ordinamento progressivo dei valori presenti in ogni singola colonna. Come vedete, non ho usato nessuna intestazione di colonna, sono tutti valori che dovranno essere ordinati. A questo proposito è opportuno fare una precisazione: nelle istruzioni per l'ordinamento (Sort), l'argomento Header:=  ha il preciso compito di definire se dovrà essere o meno compresa l'eventuale intestazione di campo (o colonna) nell'ordinamento:

  • xlGuess. Consente di determinare automaticamente la presenza di un'intestazione e la rispettiva posizione, senza comprenderla nell'ordinamento.

  • xlNo predefinito. Deve essere ordinato l'intero intervallo.

  • xlYes. Non deve essere ordinato l'intero intervallo, quindi l'intestazione viene esclusa dall'ordinamento

Passiamo alla routine, commentandola: con "zona" reperiamo tutta l'area dati (UsedRange) di cui contiamo le colonne occupate da dati con la variabile X. Sono possibili altre istruzioni per ottenere il numero di colonne occupate da dati, per esempio partire dalla prima colonna che ci interesserà ordinare e trovarne la fine con End(xlToRight), come ad esempio, partendo dalla colonna B Set zona = ActiveSheet.Range(Cells(2, 2), Cells(2, 2).End(xlToRight)) , e impostando quindi il ciclo For inizializzandolo dal numero 2 (la B e la colonna numero 2)

Sub OrdiMultiplo()
Set zona = ActiveSheet.UsedRange
X = zona.Columns.Count

'sotto: si inizia il ciclo che partendo dalla colonna 1 terminerà alla colonna X
For Colonna = 1 To X

'ora selezioniamo tutta le celle della colonna, partendo dalla riga 2 e fino all'ultima cella occupata, 'stessa colonna,
Range(Cells(2, Colonna), Cells(2, Colonna).End(xlDown)).Select

'sotto: e applichiamo l'ordinamento su questa selezione
Selection.Sort Key1:=Cells(1, Colonna), Order1:=xlAscending, _
Header:=xlNo, OrderCustom:=1, MatchCase:=False, Orientation:= _
xlTopToBottom
Next
'si prosegue alla colonna successiva ripetendo l'ordinamento, fino alla fine delle colonne 'rappresentata dal numero ottenuto con X
End Sub

e questo il risultato; dai colori si osserva meglio lo spostamento indipendente effettuato dall'ordinamento:

Ultima cosa: questo tipo di ordinamento non può prevedere di ritornare alla tabella primitiva, ma soltanto di ottenere a questo punto un ordinamento ascendente o discendente.

Ovviamente è possibile anche un ordinamento a scelta (con ImputBox per la definizione della colonna che sarà la chiave di ordinamento) e che agisca ordinando SOLO la colonna scelta; basta modificare integrando la prima macro con la seconda, ma lascio ai pellegrini volenterosi questo compito.

Buon Lavoro.

p/relevato sul sito www.ennius.altervista.org