Righe: tagliare righe e (incollarle) inserirle in un altro foglio. - dal 04/09/04 pagina vista: volte

Modifica: copiare righe ed incollare a distanza su altro foglio ed eliminare riga di origine rimasta vuota    17/12/2010

Nel presentare queste note, mi sono venuti in mente i corsi di "Taglio & Cucito" che seguono i sarti o le sartine: non avevo mai considerato che potremmo considerarci degli "stilisti", visto che anche noi compiamo operazioni di "Cut & Paste" sui fogli di Excel. Amenità a parte, ci occuperemo di una semplice operazione:

  • Tagliare righe di un foglio di lavoro (che corrisponderanno a certi criteri).

  • Inserire (incollare) queste righe in un altro foglio.

Esitono molti modi diversi nel presentare questo esercizio, per ciò che riguarda il criterio di selezione delle righe che vogliamo tagliare, dipende dalle necessità di ognuno, e sono veramente tante, quindi esaminiamone alcune tanto per capire i concetti :

  • celle di una determinata colonna, che contengono un determinato valore, per esempio tutte le celle dove compare la parola "pippo", oppure dove compare una data, o ancora dove una parola inizia per una determinata lettera, oppure dove è presente un determinato numero, ecc. ecc.

  • righe dove due o più celle corrispondano a più criteri. Useremo l'operatore di unione ( And ) per comporre la condizione che formerà il criterio di ricerca.

  • tutte le righe dove una certa cella è vuota.

  • tutte le righe pari, o le dispari

  • ecc. ecc.

E' evidente che muteranno le condizioni di identificazione delle righe, ma la procedura di "Taglio & Cucito" resterà sempre la solita. Vediamo un paio di esempi: il primo cercherà tutte le righe in un determinato range, dove le celle della colonna A (la colonna n. 1) contengono un valore.

Precisiamo inoltre che NON useremo il Paste (incolla) in questi due esempi, ma Insert (inserisci) : infatti una riga si può incollare o inserire, e l'inserimento avviene sempre nella riga superiore alla riga che verrà selezionata come destinazione. Giova ripetere che Excel provvederà in automatico a rinumerare progressivamente le righe sul foglio destinazione. Non scordiamoci inoltre che un foglio può contenere al massimo 65536 righe, e se fossero già tutte occupate e si volesse inserirne un'altra, cosa pensate che succederà? Provate e lo vedrete.

Ultima cosa: nel foglio di origine, con Cut vengono tagliate le righe e quelle tagliate resteranno vuote, excel non effettua il riordino delle righe tagliate. Questo provocherà dei vuoti che limiteranno l'azione dell'uso di End inserito nel secondo esempio sotto. Scegliere quindi il metodo Cut senza il Paste quando si voglia intenzionalmente lasciare righe vuote, altrimenti converrà usare il terzo esempio che trovate alla fine di questa pagina, in cui si usa i metodi Cut + Paste + Delete, che elimineranno fisicamente la riga copiata permettendo il riordino righe da parte di excel.

Sub TagliaeCuci1()
Set zona = ActiveSheet.Range("A1:A100")
'si imposta con "zona" il Range di celle su cui eseguire 'il controllo e la ricerca del criterio (cerchiamo celle occupate)
contarighe = zona.Rows.Count
'ne contiamo le righe (anche se lo sappiamo già quante sono, ma 'serve per far capire che avremo bisogno di un valore che rappresenterà il limite superiore del 'ciclo For Next che andremo ad impostare)
For N = 1 To contarighe Step 1
'iniziamo il ciclo assegnando N come contatore, con "passo" 1
If Cells(N, 1).Value <> "" Then
'controlliamo se la cella letta è diversa da vuoto, se positivo
Cells(N, 1).EntireRow.Cut
 'tagliamo la riga intera
Sheets(2).Select 
'selezioniamo il foglio in cui vorremo incollare la riga tagliata
Dim iRow As Integer 
'cerchiamo la prima cella vuota nella colonna A
iRow = 1 
 'partendo dalla riga numero 1
While Cells(iRow, 1) <> ""
'il ciclo While si ripete fino a che la cella letta è diversa da vuota
iRow = iRow + 1
'si passa alla riga successiva ripetendo la'istruzione While
Wend
' trovata la condizione che la cella è uguale a vuoto, si esce dal ciclo
Rows(iRow).Insert
'e quindi si "inserisce" la riga precedentemente tagliata
Sheets(1).Select
'si ritorna al foglio 1 di provenienza per continuare il ciclo For Next fino alla fine
End If
Next
End Sub

Il nocciolo delle istruzioni responsabili del taglio e dell'inserimento sono due sole righe: (a parte il ciclo While necessario per trovare la prima riga libera dove incerire la riga tagliata)

  • Cells(N, 1).EntireRow.Cut 

  • Rows(iRow).Insert

Vediamo un'altro esempio dove cercheremo tutte le celle in cui il testo inizi per la lettera "c", ed useremo in questo caso la Funzione End per reperire l'ultima cella occupata in una determinata colonna. Ricordo che per usare End dovremo avere tutte le righe dell'area dati, nella colonna su cui eseguiamo la ricerca, occupate da valori: se una cella sarà vuota End si interromperà a questa cella anche se sotto continuano celle con valori. Cercheremo quindi nella colonna B tutti i nomi che comincino con la "c", e trovata la cella, taglieremo l'intera riga inserendola in un altro foglio.

Sub TagliaeCuci2()
Set zona = ActiveSheet.Range([B1], [B1].End(xlDown))
'si imposta con "zona" il Range di celle 'su cui eseguire il controllo e la ricerca del criterio (cerchiamo nomi che inizino per "c")
contarighe = zona.Rows.Count
'ne contiamo le righe (non sappiamo quante sono, l'elenco potrà 'essere variabile, per questo abbiamo usato End)
For N = 1 To contarighe Step 1
'iniziamo il ciclo assegnando N come contatore, con "passo" 1
If Left(Cells(N, 2), 1) = "c" Then
'controlliamo se la prima lettera a sinistra nella cella letta,colonna 2, è uguale alla letera "c", se positivo
Cells(N, 2).EntireRow.Cut
 'tagliamo la riga intera
Sheets(2).Select 
'selezioniamo il foglio in cui vorremo incollare la riga tagliata
Dim iRow As Integer 
'cerchiamo la prima cella vuota nella colonna A
iRow = 1 
 'partendo dalla riga numero 1
While Cells(iRow, 1) <> ""
'il ciclo While si ripete fino a che la cella letta è diversa da vuota
iRow = iRow + 1
'si passa alla riga successiva ripetendo la'istruzione While
Wend
' trovata la condizione che la cella è uguale a vuoto, si esce dal ciclo
Rows(iRow).Insert
'e quindi si "inserisce" la riga precedentemente tagliata
Sheets(1).Select
'si ritorna al foglio 1 di provenienza per continuare il ciclo For Next fino alla fine
End If
Next
End Sub

Come vedete le istruzioni per taglia e inserisci sono le stesse, cambiano solo gli altri parametri. Precisazione: non cadiamo in equivoci : stiamo cercando nella colonna B i nomi che niziano per "c" per identificare una riga e tagliarla, e sappiamo che le celle, visto che abbiamo usato End, portano valori in celle successive; questo non vuol dire nella colonna A, per ogni riga in cui la cella B è occupata, sia occupata anche lei. Si potrebbe verificare una situazione come la seguente:

  A B C
1    cercine  
2    bastiancontrario  
3   limone  cerchio  
4    ciccia  

Solo la riga 3 porta un valore anche nella colonna A, ma tutte e tre le righe della B il cui nome inizia con la "c" verranno tagliate. Nelle istruzioni viste sopra, con il ciclo While, stiamo cercando, sul foglio destinazione, la prima cella vuota nella Colonna A (infatti While Cells(iRow, 1) <> "" dove 1 indica il numero di colonna), ma questo provocherebbe la sovrascrittura delle righe in cui la colonna A è vuota. Dovremo solo modificare l'istruzione in modo che il ciclo While cerchi nella colonna B, dove saremo sicuri che se non ci sarà un valore è perchè siamo alla fine dell'elenco presente. Chiaro ? speriamo. Quindi l'istruzione diventerà : While Cells(iRow, 2) <> "" dove 2 rappresenta la colonna B. L'istruzione Rows(iRow).Insert non va modficata perchè restituisce il numero di riga indipendentemente dalla colonna in cui si cerca la cella libera.

E vediamo infine il terzo esempio, dove useremo il Cut & Paste & Delete. Non verrà usata l'istruzione Insert. Vediamo le istruzioni. Commenterò in verde solo le istruzioni che cambiano rispetto ai due esempi precedenti, evidenziando col grassetto:

Sub CopiaeIncolla()
Application.ScreenUpdating = False
 'impediamo il saltellamento a schermo
Set zona = ActiveSheet.Range([B1], [B1].End(xlDown))
contarighe = zona.Rows.Count
For N = 1 To contarighe Step 1
If Left(Cells(N, 2).Value, 1) = "*" Then
Cells(N, 2).EntireRow.Cut
Sheets(2).Select
 'si seleziona il foglio di destinazione e si cerca la prima cella vuota in A
Dim iRow As Integer
iRow = 1
While Cells(iRow, 1) <> ""
iRow = iRow + 1
Wend
Cells(iRow, 1).Select
'per usare Paste è necessario selezionare la cella in quel momento letta
ActiveSheet.Paste
'indi si incolla tutta la riga precedentemente tagliata
Sheets(1).Select  'si ritorna al foglio origine
Cells(N, 2).EntireRow.Delete 
'e si elimina la riga tagliata, ed excel provvede al riordino righe
Application.CutCopyMode = False
End If
Next
End Sub

 

Copiare righe ed incollare a distanza su altro foglio ed eliminare (Delete) la riga di origine rimasta vuota

A volte non è necessario usare il Taglia (Cut) per copiare i dati di un'intera riga, a distanza, ma si può usare il metodo Copy per la copia di una intera riga , e si può poi cancellare (Delete) la riga di origine che è stata copiata. Come abbiamo detto nelle note sopra, il Cut provoca il taglio dei dati (che finiscono nelle clipboard  (in memoria) in attesa di una destinazione) ma lascia la riga appena tagliata al suo posto, con tutte le celle bianche, vuote.

Se la visione di una riga bianca in una tabella disturba o comunque non la si desidera, possiamo scegliere due strade per non vederla più:

  • creare un ordinamento nella tabella, ordinamento che provoca automaticamente lo spostamento di tutte le righe bianche alla fine della tabella.

  • cancellare, eliminare con Delete la riga pocanzi tagliata.

Vediamo un esempio di quanto consigliato sopra: (la riga 3 e la colonna C della Sub sotto sono solo di esempio, (ognuno userà gli indici di riga e la colonna che vorrà))

Sub CopiaIncollaCancella()
Dim Zona As Range

'si deve selezionare l'intestazione di riga della riga che si vuolecopiare e eliminare dopo, e con la variabile Zona indichiamo e impostiamo (Set)  'tutta la riga selezionata
Set Zona = Selection

'quindi si cerca, a "distanza" cioè senza bisogno di selezionare il foglio di destinazione la prima riga libera, a partire dalla riga 3, nella colonna C la '3, (cercheremo nella colonna che ha tutte le celle sicuramente occupate da dati, tramite il ciclo While; una volta trovata la riga vuota con wend 'termina il ciclo e la 'variabile "riga" corrisponderà al numero di riga dove incollare i dati
riga = 3
While Sheets("NomeTuoFoglioDestinazione").Cells(riga, 3) <> ""
riga = riga + 1
Wend


' ora si usa il metodo Copy che copierà il contenuto di Zona nella destinazione indicata, cioè nella riga trovata libera, a partire dalla cella colonna 1, (colonna A) è necessario fornire l'indirizzo della prima cella della riga voluta, quando si incolla il contenuto di una intera riga.

Zona.Copy Sheets("NomeTuoFoglioDestinazione").Cells(riga, 1)

' ora che la copia è stata fatta, si può eliminare la riga selezionata sul foglio attivo con il comando Delete.
Zona.Delete

ActiveSheet.[A1].Select  'quindi si seleziona una cella per deselezionare la riga
End Sub

 

Nota: il comando Copy copia non solo il contenuto di una cella o di una riga, ma anche la formattazione, quindi bordi cella se ce ne sono, colore cella, ecc. Se non si desiderano questi "accessori" si può usare il metodo Copia/Incolla (Copy/Paste) (vedi 6 articoli sul sito).

 

Buon lavoro.

prelevato sul sito www.ennius.altervista.org