Tabelle dati in Excel: Ascisse e Ordinate: come scorrerle, leggerle, sfruttarle?

GESTIONE ELENCHI DI DATI con CICLI (FOR....NEXT, FOT EACH...NEXT, WHILE....WEND, ecc.ecc)

In Excel un elenco (o Tabella) è rappresentato in un foglio di lavoro contenente un insieme di dati strutturato in righe e colonne nel quale è possibile applicare diverse funzionalità di utilizzo o analisi dei dati ivi contenuti. La struttura e l’organizzazione dell’elenco in Excel ricalcano il concetto di tabella nella impostazione di un database: le colonne della tabella rappresentano i campi  di un database mentre le righe della tabella, i record del database.

Per scorrere, leggere, utilizzare i dati delle tabelle in excel (sono dei database, non scordiamolo, siano esse elenchi di indirizzi, componentistica civile o industriale, magazzini di materiali, rubriche contenenti titoli di film, nomi di destinazioni di villeggiature, elenchi di donne amate, ecc. ecc, elenchi di medicinali, o tabelle di gestione turni di lavoro (come nell'esempio allegato)) utilizzando il VBA, dovremo necessariamente riccorrere ai Cicli (che non sono biciclette, he he), primo fra tutti il ciclo For .... Next.

Senza voler cominciare a parlare di matematica (di cui non sono capace), per comprendere meglio come utilizzare cicli For ..Next forse l'esempio migliore è proprio quello di parlare di ascisse e ordinate: cosa è in effetti un foglio di excel se non un'insieme di ascisse (un piano orizzontale rappresentato da una riga e da tutte le colonne che la riga intersecano) e un insieme di ordinate (un piano verticale rappresentato da tutte le righe, per ogni colonna). Il punto di incontro tra una ascissa e ona ordinata (su un foglio di excel) è sempre una cella; e questa cella può venire identificata dalla Lettera che rappresenta la colonna (ascissa) unita al Numero (ordinata) che identifica la riga: nell'esempio sotto la cella evidenziata è dunque la cella D6; questo sistema di identificazione si chiama "Riferimento in stile A1" oppure Un altro modo di identificazione di una cella è usare la sintassi Cells(numero di riga e dopo una virgola, al numero di colonna) quindi la cella sotto evidenziata sarebbe la Cells(6, 4) . Questa modalità è particolarmente indicata quando si debbano scorrere celle con qualsiasi tipo di Ciclo For Next.

 Se quindi vollessimo scorrere le celle di una tabella bidimensionale (cioè verso il basso e poi verso destra) potremmo iniziare un ciclo che inizi a scorrere le righe, come nell'animazione

e per ogni riga, un altro ciclo che scorra le colonne fino al termine tabella, come nell'animazionr

passando poi alla riga successiva e così via fino al termine della tabella; oppure fare il contrario, cioè iniziare a scorrere le colonne e  per ogni colonna tutte le righe della tabella. Queste opportunità dipenderanno esclusivamente da come saranno impostati i dati nelle righe o nelle colonne.

Questo articolo è nato per una richiesta di un pellegrino che aveva questo problema "...ho il foglio come tabella A così com'è. La mia esigenza è trasformarla (evitando di ricompilarla a mano) nella tabella B. ... nella tabella A è immediatamente evidente la condizione del turnista per ogni giorno del mese (sequenza di turni più o meno pesanti ad esempio od incompatibili tra loro) ....nella tabella B è immediatamente evidente che tutti i turni necessari per ogni giorno di lavoro siano eseguiti da qualcuno..."

vediamo le due tabelle: qui sotto la Tabella A dove nella riga 2 sono inserite le date di un periodo a partire dalla colonna B e fino alla colonna AF, mentre i nomi dei turnisti sono tutti nella colonna A a partire dalla riga 3; nelle celle della tabella sono inseriti gli identificativi dei turni di lavoro, ovviamente i dati sono tutti di fantasia.

 

e questa sotto è la tabella B dove vorremo comporre i nomi provenienti dalla tabella A, ma ordinati si per giorni (colonna B) ma divisi per turni, che qui sono diventati le intestazioni di colonna nella riga 3

 

la procedura per ottenere questo risultato si basa su cicli For...Next annidati, cioè si inizia scorrendo le righe nella tabella A : letta la prima riga, si inizia un secondo ciclo interno che scorre le colonne, cercando se una cella contiene dati, se si verifica la condizione, si memorizza il nome del turnista, la data di origine e il valore del turno e si inizia un terzo ciclo interno che scorre le date della colonna B della Tabella B cercando la corrispondenza alla data origine, trovata la riga con la data valida, inizia un quarto ciclo interno che scorre le colonne cercando nella riga 3 della tabella B la corrispondenza al valore turno memorizzato in precedenza, trovata la corrispondenza del turno, si scarica nella cella, riga e colonna ora letta, il nome del turnista memorizzato in precedenza.

questa la routine:

Option Compare Text

-------------------------------------------------------------------------------------------------------------------------------------------
Sub Scorri()
Dim dataorig
Dim Turno As String
rigainizio = 2
colonna = 2
finecolonne = Sheets("Foglio1a").Cells(rigainizio, colonna).End(xlToRight).Column

'si lavora con cicli annidati
fineriga = Sheets("Foglio1a").Cells(65536, 1).End(xlUp).Row

For R = 3 To fineriga
'iniziamo scorrendo le righe nella colonna A
For N = 2 To finecolonne
'quindi iniziamo a scorre le colonne dalla 2 alla fine colonne
nome = Sheets("Foglio1a").Cells(R, 1)
'leggiamo il nome del turnista che si troverà sempre nella colonna A (n questo esempio)

If Sheets("Foglio1a").Cells(R, N) <> "" Then '
controlliamo se la cella contiene dati (il turno) (se diversa da vuota)
Turno = Sheets("Foglio1a").Cells(R, N).Value
'se contiene dati ne leggiamo il turno
dataorig = CDate(Sheets("Foglio1a").Cells(rigainizio, N).Value)
'e leggiamo la data

For M = 4 To 34 '
inizia il ciclo che leggerà le righe della colonna B sul foglio1b scorrendo le date
If CDate(Sheets("Foglio1b").Cells(M, 2).Value) = dataorig Then
'se la data ora letta corrisponde alla data memorizzata con dataorigine
finecolB = Sheets("Foglio1b").Cells(2, 3).End(xlToRight).Column
'leggiamo quante colonne sono occupate nella riga 2 del foglio1b

For C = 3 To finecolB '
quindi inizia il ciclo che scorre i turni e se trova il turno uguale al valore letto con Turno
If Sheets("Foglio1b").Cells(3, C) = Turno Then
'allora
Sheets("Foglio1b").Cells(M, C) = Sheets("Foglio1b").Cells(M, C) + nome + " - "
'nella cella riga M, colonna C, scriviamo il nome letto sul 'foglioA
End If
Next
End If
Next
End If
Next
Next

End Sub

 

ho provato diverse volte la procedura e mi pare funzioni bene; se qualcuno vorrà verificare il tutto, allego il file di prova; per lanciare la macro si usa il pulsante che è sul foglio 1b.

file da scaricare : TabellaAB.rar   19 kb

 

prelevato sul sito www.ennius.altervista.org

ua