Le Matrici (by ennius) - Atto unico. - dal 04/09/04 pagina vista: volte Parlare di matrici per me rappresenta un grosso exploit, vista la mia dichiarata (più volte sui siti) mancanza di comprendere le matrici. A differenza di Mike, che sguazza tranquillamente e piacevolmente nel mare Matrix, ho sempre avuto grosse difficoltà nel comprendere le matrici, e quindi utilizzarle. Vediamo intanto come la guida in linea definisce una matrice: "Gruppo di elementi indicizzati in sequenza che possiedono lo stesso tipo di dati intrinseco. A ciascun elemento di una matrice viene assegnato un numero di indice univoco che lo identifica. Le modifiche apportate a un elemento di una matrice non influenzano gli altri elementi." Francamente io non avrei comunque capito granchè da questa spiegazione, se non che una matrice è un insieme di dati (elementi) che vengono identificati attraverso un numero indice assegnato ad ogni elemento. Ma fino a qui non ci sono grossi problemi, solo non so come devo fare per impostare dei dati in matrice, e come posso utilizzarli, insomma mi sento molto "gnocco". Debbo comunque subito precisare che per lavorare con le matrici è necessario conoscere come funzionano i cicli For..Next, cicli necessari a scorrere un insieme di dati, (anche di una matrice, appunto), sia per memorizzarli per poterli poi utilizzare, sia per poterli eventualmente modificare prima di utilizzarli. Abituato a ragionare coi cicli For Next per leggere, modificare, cancellare, copiare, o comunque intervenire sui dati contenuti in una tabella (o database, è la stessa cosa, in Excel), distribuita su celle , dove ogni dato letto dal ciclo, sostituisce il dato precedentemente letto (una volta usato, scritto in una cella), non immaginavo, non sapevo, non intuivo, e non ho mai capito le spiegazioni (forse date per scontate dagli autori dei molti libri che ho letto sull'argomento "matrici") che ora invece mi accingo a descrivere. Devo sicuramente ringraziare Mike, che in un altro disperato quanto arduo tentativo di spiegarmi le matrici, ha finalmente acceso una lampadina che stava da qualche parte del mio modesto (e limitato) cervello. Non voglio parlare
quindi di matrici in forma tecnica (esistono articoli specifici di Mike che
spiegano a sufficienza l'argomento matrici, (vedi i suoi articoli Vediamo quindi la procedura che mi ha inviato Mike come alternativa al problema citato nell'articolo "Copia per lunghezza testo", in questa sezione), e che serve ad ordinare dei fogli di una cartella, usando appunto una Matrice:
Sono stati i primi due commenti in verde che mi hanno "svegliato" :
infatti queste semplici frasi mi hanno fatto capire che i nomi dei fogli vengono letti e MANTENUTI TUTTI IN MEMORIA, (raccolgo i nomi) e non, come ho sempre pensato, che ogni nome letto dal ciclo For sostituisse in memoria quello letto precedente, quindi una MATRICE ora me la posso figurare come una tabella di Dati, CHE ANZICHE' ESSERE SCRITTI su un foglio, sono TUTTI SCRITTI nella MEMORIA (RAM). Una volta accesa la mia "lampadina" personale, non è stato difficile capire, attraverso la frase (metto in ordine..) che i dati tenuti in memoria, si possono modificare (ordinarli alfabeticamente, copiarli in un'altra posizione, filtrarli, ecc.) come siamo (e sono) abituato a fare con i dati scritti sui fogli di lavoro. Chi legge potrà stupirsi di questo articolo, ma io e le matrici fino ad ora non ci eravamo mai capiti, fino a che Mike, con due piccole frasi, mi ha fatto capire ciò che libri e tanti articoli letti non erano riusciti nell'intento. Vorrei aggiungere che spesso due semplici parole riescono dove corposi e ponderosi capitoli falliscono. Le strade che il nostro cervello usa per apprendere sono decisamente strane e incomprensibili, e non sempre sono visibili. Parlare di matrici dovrebbe necessariamente obbligarmi a parlare del loro dimensionamento, di matrici a una dimensione, bidimensionali, multidimensionali, ecc. ma questi argomenti li trovate tutti, e spiegati bene, nei due articoli di Mike citati ad inizio pagina. Unica cosa che è necessario qui ricordare, è che gli elementi che compongono una matrice vengono identificati da un numero indice che iniziando da zero ( 0 ) si incrementerà di tanti valori quanto saranno gli elementi che compongono la matrice. Cioè se una matrice è a 10 elementi i numeri indice partono da 0 e terminano a 9. Proseguo invece tentando di spiegare come sono riuscito a mettere in pratica quanto ho appreso. Seguendo l'esempio che Mike mi ha inviato, provando e riprovando, non a mettere in ordine i fogli, ma a memorizzare, mettere in ordine, estrarre dati contenuti in una colonna di un foglio di lavoro: mi sono quindi preparato una tabellina con un pò di nominativi, occupando le celle della colonna A, simulando quindi un database ad una sola colonna (avremo quindi una matrice monodimensionale = una sola colonna). Vediamo quindi la procedura, spiegando passo passo cosa avviene: Matrice ad una dimensione.
bene, dopo aver lanciato queste istruzioni, noi avremo caricato la nostra matrice con in nomi che sono sul foglio; possiamo immaginare il contenuto di una matrice come un'elenco di dati in una casella di riepilogo, ma senza la casella, tanto per intenderci, una cosa del genere:
dopo questo passaggio, la nostra matrice sarà ordinata (sempre in memoria) alfabeticamente, così: Ora possiamo decidere cosa fare con questi dati; ho preparato tre varianti, ognuna delle quali rappresenta l'ultimo gruppo di istruzioni che chiuderanno la Sub MiaMatrice(); vogliono essere solo degli esempi delle tante soluzioni che potremmo scegliere avendo a disposizione quei dati:
1^ soluzione:
2^ soluzione:
3^ soluzione:
se invece che scriverli nelle celle, questi nomi filtrati, li vogliamo inserire in una ListBox, il procedimento è lo stesso visto più sopra, ma con l'aggiunta delle due inputbox:
Come avete visto, le procedure per la gestione dei dati sono simili a tante altre viste in procedure senza matrici, presenti su questi siti. Lo scoglio (per me) delle "Matrici" ora sembra raggiunto e quasi superato, ma non è così, c'è ancora molta strada da fare, anche se proviamo ora a percorrerla un'altro pò, insieme (per fortuna c'è Mike!). Matrice multidimensionale. Una ciliegia tira l'altra, e il passo successivo risponde alla domanda "Ma se invece che una sola colonna di dati (i cognomi) voglio gestire anche una seconda colonna (i nomi), cosa caspita devo fare?" Il bravo Mike anche stavolta mi aiuta: semplice, si usa una matrice "bidimensionale". Confesso che anche in questo caso il mio cervello ha sputacchiato un pò, prima di mettersi in moto, infatti Mike per spiegarmi come si usano matrici multidimensionali, mi scrive:
dove si desume che per indicare cosa vogliamo da una matrice multidimensionale si indica accanto al nome della matrice (A in questo caso), due numeri separati da una virgola: il primo numero si riferisce al numero indice (di riga, per meglio capire), il secondo numero si riferisce, come se fosse una tabella, alla posizione relativa alla colonna (virtuale) . Se quindi, con l'esempio sopra, si chiedesse il risultato di A(2, 3) vorremmo il dato che si trova sulla riga 2, terza colonna, ed otterremo "Torino". Già, ma come la imposto una matrice a 3 colonne? Cosa devo scrivere come dichiarazione nella variabile per indicare che voglio una matrice a tre colonne? Devo scrivere 3 numeri? O cos'altro? Poi finalmente si è accesa un'altra lampadina: come faccio su un foglio di lavoro a indicare che voglio scorrere tre colonne? Uso un ciclo For Next che parte da 1 ed arriva a 3, una cosa così: For pippo = 1 To 3, cioè uso solo due numeri: 1 (il limite inferiore del ciclo) e 3 (il limite superiore del ciclo), e se poi voglio scorrere anche le righe uso un'altro ciclo che mi consentirà di scorrere tutta una tabella. In una matrice multidimensionale avviene lo stesso e quindi la dichiarazione dei numeri può avvenire indicando solo due valori, il primo indicherà il numero di righe massimo, il secondo il numero di colonne massimo che dovrà contenere la matrice, infatti, ove omesso, il numero iniziale sarà sempre zero, sia per le righe sia per le colonne; si useranno poi due cicli For Next che scorreranno i dati da prelevare e mettere in matrice. Se io dichiaro una matrice: Dim RIS(10, 3) imposto una matrice che conterrà 10*3 = 30 valori; sono i cicli For Next che leggendo le 10 righe di una tabella e le 3 colonne, assegneranno i dati alla matrice. A questo punto si capiscono meglio le istruzioni date da Mike. Supponiamo quindi di avere una tabella del genere: Abbiamo "Cognomi" in A, "nomi" in B, "città" in C. Vorremo prendere tutti questi dati ed ordinarli alfabeticamente, copiandoli in altra destinazione (ma potremo filtrarli, o farci altre cose..). Appare evidente che dovremo "spostare" nell'ordinamento, il nome e la città insieme al Cognome. Faremo quindi come ci ha insegnato Mike, prima comporremo la matrice in memoria, poi la ordineremo, quindi la copieremo a destinazione. Questa volta uso la variabile RIS (come "risultanza") per indicare il nome della matrice; poi, siccome userò la variabile "X" come contatore sia nel ciclo che assegnerà alla matrice i valori contenuti nelle celle, sia perchè userò la stessa "X" nella definizione di quale riga scorrere nella sintassi Cells(X, Y), avrò bisogno che l'indice nella matrice non inizi da zero (non esiste infatti una Cells(0, 0)) ma inizi da 1; per questo uso l'istruzione Option Base 1 posta nella sezione Generale-dichiarazioni del modulo che contiene la macro. E questo il primo gruppo di istruzioni:
a questo punto della macro, avremo in memoria tutta la nostra tabella, e starà lì, pronta ad essere usata. Ora vediamo di sfruttare l'idea che mi ha insegnato Mike per mettere in ordine la matrice; l'idea va necessariamente adattata, ma direi a questo punto che non ci sono grossi problemi: dovremo comparare solo i "cognomi" e nel caso di uno spostamento, spostiamo il cognome e insieme il nome e la città usando due variabili in più, così:
Mike sarà sicuramente soddisfatto (io pure) nel vedere che le sue spiegazioni sono state finalmente assimilate. Ora basterà decidere cosa fare della matrice ordinata, per ora imposto le istruzioni che copieranno i valori in matrice in una'altra parte del foglio; vediamo un pò come avviene:
L'istruzione Erase, che non conoscevo, (Mike mi ha suggerito), serve a svuotare una matrice dinamica. Questa è una nota tratta dalla guida in linea: "L'istruzione Erase consente di liberare la memoria utilizzata dalle matrici dinamiche. Prima che il programma possa di nuovo fare riferimento alla matrice dinamica, è necessario dichiarare nuovamente le dimensioni delle variabili matrice tramite l'istruzione ReDim". Vi conviene, se interessati, leggervi le spiegazioni nei due articoli di Mike riportati in testa per capire la differenza tra matrici statiche e dinamiche. Io avrei finito; chiedo scusa a chi le matrici le conosce bene, per imprecisioni che avrò commesso in questo articolo, ma mi sembrava un buon aiuto fare partecipi altri "del come" sono arrivato a "cominciare" a capire le matrici. In attesa che le due lampadine diventino una luminara, auguro a tutti buon lavoro. prelevato sul sito www.ennius.altervista.org |