Elenchi zebrati.      (11/05/03)

Ovvero: come differenziare il colore delle righe di un elenco, alternando una riga colorata ed una no oppure una riga di un colore e un'altra di un'altro colore.

Prendendo spunto da una domanda postami sulla Formattazione Condizionale, nasce questo articolo che presento con varie soluzioni, la prima delle quali mi ha sorpreso non poco. Premesso che il buon vecchio Excel ci consente a volte di crearci le nostre istruzioni in molte maniere, per ottenere lo stesso risultato, questa volta, seguendo una procedura che sfruttando il metodo Add, consente di definire una condizione nella creazione di una Formattazione Condizionale tramite vba, è venuto fuori che la sintassi della formula usata per definire la condizione, DEVE ESSERE IMPOSTATA CON FUNZIONI IN ITALIANO. Strano ma vero, e non so il perchè, se uso la normale sintassi in inglese tipica del vba, non si ottiene il risultato voluto. Ma vediamo l'origine del caso :

Si vuole alternare il colore delle righe di un elenco, in modo che i dati siano più facilmente leggibili o stampabili, cioè desideriamo creare un "elenco zebrato". Un ragionamento logico è: identifichiamo le righe che corrispondono al numero pari, per esempio, e coloriamo quelle (quindi la 2,4,6,8,,10, ecc). Allora sfruttiamo la Funzione "RESTO" (in inglese=MOD) la quale fornisce come risultato di una divisione, soltanto il resto. Sapendo questo, è facile impostare l'istruzione : se un numero di riga diviso 2 dà come resto zero, allora......infatti tutti i numeri pari diviso 2 danno sempre come resto un bello zero, cioè non ci sono decimali. (stiamo parlando di Resto, non di Quoziente), e quindi nasce la formula, vediamola prima in italiano:

=SE(RESTO(RIF.RIGA();2)=0;VERO;FALSO)

la stessa in inglese, da usare nel codice:

=IF(MOD(ROW(),2)=0,TRUE,FALSE)

Impostiamo quindi tutta la procedura:

'Reperiamo la zona di cui vogliamo l'elenco zebrato

Range("A1:J20").Select
'cancelliamo nella zona selezionata eventuali formattazioni condizionali presenti, istruzione 'comunque necessaria per poter applicare il metodo Add
Selection.FormatConditions.Delete

'impostiamo la format. condiz. tramite la formula
Selection.FormatConditions.Add Type:=xlExpression, Formula1:= _
"=IF(MOD(Row(),2)=0,true,false)"

'e a seguito del reperimento delle righe, applichiamo il colore alle righe
Selection.FormatConditions(1).Interior.ColorIndex = 35

Orrore, Orrore, il debugger si lamenta immediatamente indicando un errore nella composizione della formula; strano, si controlla, ci sembra scritta correttamente, virgole comprese (in vba i punti e virgola della stessa formula in versione Foglio di lavoro, si devono scrivere come virgole). Vuoi vedere che il debugger protesta proprio per le virgole? Allora le sostituiamo con punti e virgola e proviamo. Questa volta il debugger non dice niente, ma neanche succede niente. Allora tento l'ultima carta, vacca miseria, un controsenso, ma tanto vale...e...così funziona. Giuro che non so perchè. Questa è la macro:

Sub Colora()

Range("A1:J20").Select
Selection.FormatConditions.Delete
Selection.FormatConditions.Add Type:=xlExpression, Formula1:= _
"=SE(RESTO(RIF.RIGA();2)=0;VERO;FALSO)"
Selection.FormatConditions(1).Interior.ColorIndex = 35

End Sub

e questo il risultato:

Esistono comunque altre procedure che si possono attivare per ottenere lo stesso risultato; una procedura che propongo, semplice da capire, e in due versioni: colorare una sola riga, o colorare le righe a colori alterni, inoltre tratteggiando le celle delle righe selezionate per migliorare la vista a video; la prima:

Sub Zebrauno()

Set zona = Range("A1:F15") 'si imposta la zona su cui agire
For Each rw In zona.Rows 
'per ogni riga delle righe presenti in zona
If rw.Row Mod 2 = 0 Then
'se il numero riga diviso 2 come resto da zero, allora
rw.Interior.ColorIndex = 35 
'si colora la riga
rw.Borders.LineStyle = xlDashDotDot
'si contornano le celle delle righe con il tratteggio
End If
Next rw
'si passa alla riga successiva

End If

e questo il risultato:

la procedura a due colori, simile alla precedente:

Sub Zebradue

Set zona = Range("A1:F15")
For Each rw In zona.Rows
If rw.Row Mod 2 = 0 Then
rw.Interior.ColorIndex = 35
rw.Borders.LineStyle = xlDashDotDot 'xlContinuous
Else
'con Else si interviene sulle altre righe (che forniscono un resto diverso da zero)
rw.Interior.ColorIndex = 36
'cambia il colore
rw.Borders.LineStyle = xlDashDotDot 'xlContinuous
End If
Next rw
End Sub

e questo il risultato:


Se poi si volessero togliere le zebrature e ripristinate il foglio all'origine, basterà predisporre queste semplici istruzioni da collegare ad un altro pulsante:

per l'elenco ad una sola riga colorata:

Sub canctut()
Set zona = Range("A1:F15")
For Each rw In zona.Rows
If rw.Row Mod 2 = 0 Then
rw.Interior.ColorIndex = xlNone
rw.Borders.LineStyle = xlNone
End If
Next rw

End Sub

per l'elenco con entrambe le righe colorate:

Sub canctutdue()
Set zona = Range("A1:F15")
For Each rw In zona.Rows
If rw.Row Mod 2 = 0 Then
rw.Interior.ColorIndex = xlNone
rw.Borders.LineStyle = xlNone
Else
rw.Interior.ColorIndex = xlNone
rw.Borders.LineStyle = xlNone
End If
Next rw

End Sub

Se poi preferite lavorare di meno, date in occhiata all'articolo "Elenchi zebrati" presente sul sito, sezione "Primi passi".

Buon Lavoro.


prelevato sul sito http://ennius.interfree.it