Benvenuto Ospite Cerca | Topic Attivi | Utenti | | Log In | Registra

[Excel 2007]- Copiare e trasporre dati tabella ordinandoli AZ Opzioni
aetio
Inviato: Monday, October 25, 2010 10:02:59 AM

Rank: AiutAmico

Iscritto dal : 5/10/2010
Posts: 723
Ciao,
sto cercando di scrivere una macro che, partendo dalla selezione di una cella in Foglio 1, selezioni un range definito e lo copi in F.2 partendo dalla cella in col.K e trasponendone tutti i valori nella sola riga 46, ordinandoli nel contempo in senso crescente da sinistra a destra.
Alcune "frasi" della macro penso ormai di conoscerle, ma mi manca la sintassi pulita ed essenziale tipica delle macro di a10n11 :)))) (col registratore di macro di excel ne esce un poema omerico....)
ecco il testo da cui parto...

ActiveCell.Offset(-10, 1).Range("A1:E11").Select
ActiveCell.Activate
Selection.Copy
Sheets("F.2").Select
Range("K46").Select
ActiveSheet.Paste

...

Range("K46:BM46").Select
Selection.Sort Key1:=ActiveCell, Order1:=xlAscending, Header:=xlGuess, _
OrderCustom:=1, MatchCase:=False, Orientation:=xlLeftToRight

ove nella prima parte: da Foglio 1 e in cella attiva, la macro seleziona un'area adiacente alla colonna della cella attiva, ne copia il contenuto del Range in F.2 e nella seconda parte c'è l'istruzione per ordinare i valori.
Ho trovato una macro che fa una cosa simile, ma bisogna scrivere nella macro l'area da processare, e contiene un'istruzione che non conosco ecco il testo:

r = 46 'riga di destinazione
c = 11 'colonna di destinazione
For Each cella In Sheets("Foglio 1").Range("B207:FZ259")
Sheets("F.2").Cells(r, c).Formula = cella.Formula

r = 46 'ricomincia, sul foglio di destinazione
c = c + 1 'passando alla fascia successiva

Next


Ora agisco col registratore e tramite taglio metto tutto in colonna unica, faccio ordinare in senso crescente i dati e poi traspongo il tutto... Procedimento lontano anni luce dall'essenza pulita ed elegante delle 2 righe di istruzioni delle quali ormai sono innamorato... :))))
"A naso" penso che dovrei costruire una serie di brevi istruzioni che prendono i dati di ciascuna riga del range copiato e partendo dalla 1^ riga del Range li accodano via via fino all'ultima riga nell'unica riga di destinazione, la 46, per poi usare l'istruzione di ordinamento in senso crescente da sinistra a destra.....

Grazie infinite e buona giornata,
eZio

p.s. in questi 2 giorni di trasferta forzata, durante gli spostamenti in treno (altrimenti lunghi e noiosi) come da preziosissimo consiglio del mio caro Mentore ho letto con calma e concentrazione un po' del libro del Prof. Giaccaglini: è veramente molto interessante!! Come dicono gl'inglesi: step by step......... :)))
Sponsor
Inviato: Monday, October 25, 2010 10:02:59 AM

 
a10n11
Inviato: Monday, October 25, 2010 12:25:32 PM

Rank: AiutAmico

Iscritto dal : 5/29/2003
Posts: 1,694
salve
la mia soluzione al tuo quesito è quanto segue:

Utilizzo una parte remota del foglio da riga 60000 in giù colonna da 200 a 256 del foglio attivo

definisco il range da esportare : Set rng = ActiveCell.Offset(-10, 1).Resize(11, 5)
11 righe sopra la selezione e 5 colonne dopo la selezione.

Ricopio tutto nella matrice "mycol"
X = 1
For Each cl In rng
mycol(X) = cl.Value
X = X + 1
Next cl

La riverso a partire da cella (60000,200) (GR60000) applico un ordinamento crescente
Copio il range da GR60000 in giù e lo traspongo a partire a cella GS60000
Copio la riga nel foglio 2 a partire da cella K46

questo è il codice:

Option Base 1
Sub copia()
Dim mycol(55)
riga = 60000
A = ActiveCell.Address
Set rng = ActiveCell.Offset(-10, 1).Resize(11, 5)
X = 1
For Each cl In rng
mycol(X) = cl.Value
X = X + 1
Next cl
For n = LBound(mycol) To UBound(mycol)
Cells(riga, 200).Value = mycol(n)
riga = riga + 1
Next n
Set rng = Nothing
Set area = Range(Cells(60000, 200), Cells(60000, 200).End(xlDown))
area.Sort Key1:=Cells(60000, 200), Order1:=xlAscending
area.Copy
Cells(60000, 201).PasteSpecial Paste:=xlAll, Transpose:=True
Selection.Copy Destination:=Sheets("foglio2").Range("k46")
Application.CutCopyMode = False
area.ClearContents
Cells(60000, 201).Resize(, 55).ClearContents
Set area = Nothing
Range(A).Select
End Sub
saluti
Giap


aetio
Inviato: Monday, October 25, 2010 1:56:24 PM

Rank: AiutAmico

Iscritto dal : 5/10/2010
Posts: 723
Ciao,
la macro selezionando ad esempio la cella attiva B34:
- in Foglio 1, col.GR da riga 60002 inolonna i codici e non cancella poi l'area di lavoro
- in foglio2 scrive solo, in cellaK46, il valore che in origine è in cella C24.
Ho provato a disattivare le istruzioni dalla riga seguente alla
Area.Sort Key1:=Cells(60000, 200), Order1:=xlAscending
Il risultato è una colonna (col.GR, la 200) da riga 60000 a 60055 con la riga 60001 saltata... i codici sono 55, ma c'è il sato di una riga...
:::::::::::::::

Una domanda da profano terra-terra: la macro che ho segnalato, a patto di scrivere il Range di lavoro, fa tutto il lavoro senza intoppi in 4 righe di istruzione...
Sto cercando di adattarla alle mie esigenze, cioè:
-Al posto di For Each cella In Sheets("Foglio 1").Range("B207:FZ259") inserire l'istruzione dell'area generata dalla cella attiva
Sheets("F.2").Cells(r, c).Formula = cella.Formula, di cui non conosco minimamente il significato, di fatto senza specificare null'altro di quanto in essa scritto prende l'area selezionata, la copia in F.2, la traspone partendo da cella K46...
Poi applicando a parte l'istruzione
Range("K46:BM46").Select
Selection.Sort Key1:=ActiveCell, Order1:=xlAscending, Header:=xlGuess, _
OrderCustom:=1, MatchCase:=False, Orientation:=xlLeftToRight

ordino i dati in senso crescente.
Misteri della Fede..... :))))

Grazie infinite e buona giornata, (qui piove a catinelle....)
eZio.


EDIT
Ho adattato la macro dalle sconosciute istruzioni ed ho inserito le mie coordinate. Chiedo scusa per il pasticcio assai poco corretto ed elegante che ne è uscito... ma all'atto pratico funziona tutto perfettamente! (Ripeto: Misteri della Fede!!)
E' chiaro che non sono per nulla soddifatto, dato che ci sono istruzioni di cui non conosco l'origine (pur restituendo i dati al loro posto...so solo che in quell'ambito ci si riferiva ad una formula i cui dati dovevano esser pur essi trasposti, per cui quell'istruzione includerebbe anche quell'evento) e per giunta non è assolutamente il mio modo di operare solitamente....
ecco le istruzioni che ho dato, premesso che:
-cella attiva in Foglio 1 col.B
- F.2 foglio di lavoro che mantiene riferimenti assoluti, che serve per manipolare e modificare dati a seconda delle esigenze interne

Sub trasposizione()
r = 46 'riga di destinazione
c = 11 'colonna di destinazione
ActiveCell.Offset(-10, 1).Range("A1:E11").Select
ActiveCell.Activate
Selection.Copy
Sheets("F.2").Select
Range("F46").Select
ActiveSheet.Paste
For Each cella In Sheets("F.2").Range("F46:J56")
Sheets("F.2").Cells(r, c).Formula = cella.Formula 'Cinese mandarino!!!!! Cosa significa? (funziona comunque: copia i dati di selezione...ho agito copiando prima i dati dal foglio con riferimenti relativi al foglio con riferimenti assoluti- che per mia fortuna ho già- e lavorando con quelle istruzioni su base fissa... un cavallo di Troia?!? :)) ...)
r = 46
c = c + 1
Next
Range("K46:BM46").Select
Selection.Sort Key1:=ActiveCell, Order1:=xlAscending, Header:=xlGuess, _
OrderCustom:=1, MatchCase:=False, Orientation:=xlLeftToRight
Range("F46:J56").ClearContents
Sheets("Foglio 1").Select
ActiveCell.Offset(9, -1).Range("A1").Select
End Sub
a10n11
Inviato: Monday, October 25, 2010 6:31:37 PM

Rank: AiutAmico

Iscritto dal : 5/29/2003
Posts: 1,694
salve
quella piccola riga in testa alla macro
Option Base 1
dove l'hai scritta??
è in cima al modulo o in mezzo ad altre macro??
di solito passa inosservata ma ha la sua bella funzione.

Il codice che hai postato tu, fondamentalmente fa la stessa cosa in maniera diversa.
La tua copia tutto il range nel foglio2 e da lì lo scomponi la mia esegue tutto sul foglio1 e traspone la tabella esplosa a partire da cella K46

la riga definita cinese mandarino
For Each cella In Sheets("F.2").Range("F46:J56")
Sheets("F.2").Cells(r, c).Formula = cella.Formula,

non fa altro che copiare il contenuto di "Cella" (Valore o formule contenute) nella cella( R,C)
R= 46 C =11 che si incrementa di una unità ad ogni escussione del ciclo.

se ad esempio Cella contenesse la formula =10*10 nella cella K46 sarà copiata la stessa formula =10*10

saluti
Giap



a10n11
Inviato: Monday, October 25, 2010 6:41:26 PM

Rank: AiutAmico

Iscritto dal : 5/29/2003
Posts: 1,694
salve
una semplificazione del tutto in questa:

Sub copia2()
Dim mycol(55)
Colonna = 11
A = ActiveCell.Address
Set rng = ActiveCell.Offset(-10, 1).Resize(11, 5)
X = 1
For Each cl In rng
mycol(X) = cl.Value
X = X + 1
Next cl
For n = LBound(mycol) To UBound(mycol)
Sheets("Foglio2").Cells(46, Colonna).Value = mycol(n)
Colonna = Colonna + 1
Next n
Set rng = Nothing
With Sheets("foglio2")
Set area = Range(.Cells(46, 11), .Cells(46, 11).End(xlToRight))
area.Sort Key1:=.Cells(46, 11), Order1:=xlAscending, Orientation:=xlLeftToRight
End With
Set area = Nothing
End Sub

saluti
Giap

aetio
Inviato: Monday, October 25, 2010 8:21:54 PM

Rank: AiutAmico

Iscritto dal : 5/10/2010
Posts: 723
Ciao,
La macro (bellissima!!) funziona alla grande, è una meraviglia... c'era forse qualche dubbio?!? :))
Option Base 1 l'ho scritta in testa alla macro... Cosa significa e cosa fa quella piccola, ma fondamentate breve istruzione che modifica praticamente tutto l'esito della macro?
E' la prima volta che la vedo...
Grazie per la spiegazione dell'istruzione dagli occhi a mandorla... :)) Non l'avevo mai vista prima, e mi ha molto colpito che in un baleno facesse il lavoro di
ActiveCell.Activate
Selection.Copy
Sheets("F.2").Select
Range("F46").Select
ActiveSheet.Paste

Sospettavo che potesse fare un lavoro del genere (lavorarsi anche la formula interessata dalla sua influenza...), ma era troppo ermetica per un lattante come me...... :))
Grazie infinite e buona serata, corro subito a godermi l'ultima tua creatura...
eZio
a10n11
Inviato: Monday, October 25, 2010 9:30:29 PM

Rank: AiutAmico

Iscritto dal : 5/29/2003
Posts: 1,694
salve
Option Base può assumere il valore di 0/1 (Il valore predefinito è sempre 0)
identifica il limite inferiore dell'indice di una matrice
La nostra matrice è: Dim mycol(55)
il valore 55 è il totale degli elementi della matrice
se non avessimo utilizzato l'istruzione Option Base 1 , gli elementi totali della matrice sarebbero 56 in quanto
il primo elemento avrebbe come indice 0 e 55 come ultimo.
pertanto le righe del codice che sono condizionate dall'istruzione sarebbero:
Dim mycol(55) che sarebbe dovuto essere Dim mycol(54)
X = 1 che sarebbe dovuto essere X=0

Per quanto riguarda il codice che hai postato "Trasposizione" è utile nel caso tu debba copiare non solo il valore delle celle ma la formula in essa contenuta.
saluti
Giap


aetio
Inviato: Tuesday, October 26, 2010 4:02:39 PM

Rank: AiutAmico

Iscritto dal : 5/10/2010
Posts: 723
Ciao,
ho notato che quando il range che la macro processa è meno di 55 codici la macro "impazzisce" restituendo i dati in celle non adiacenti e non ordina più i dati... da cosa può dipendere?
Grazie assai e buon pomeriggio,
eZio
a10n11
Inviato: Tuesday, October 26, 2010 4:55:54 PM

Rank: AiutAmico

Iscritto dal : 5/29/2003
Posts: 1,694
aetio ha scritto:
Ciao,
ho notato che quando il range che la macro processa è meno di 55 codici la macro "impazzisce" restituendo i dati in celle non adiacenti e non ordina più i dati... da cosa può dipendere?
Grazie assai e buon pomeriggio,
eZio



Salve
la macro impazzirebbe se gli elementi dell'array fossero più di 55 nel caso fossero di meno si avrebbero elementi vuoti e non creerebbero il problema che sottoponi.
esempio: dichiaro un array (5) -Option base 1
le mie celle che riempiono l'array sono solo 3 con i valori 10-20-30
il mio array sarà: 10-20-30-vuoto-vuoto
siccome tale procedura è poco ortodossa, nel caso non si sappia a priori come dimensioare l'array, dovremo ridimensionarlo una volta conosciuta la sua reale dimensione. in questo modo:
Dim mycol() senza specificare il numero di elementi
ipotizzando che il nostro range finale da elaborare sia rappresentato dalla seguente istruzione:

Set rng = ActiveCell.Offset(-10, 1).Resize(6, 5)
che equivale a 30 celle da processare
ora possiamo assegnare la dimensione del nostro array come segue:
ReDim mycol(rng.Cells.Count)


e la macro completa sarà questa:

Sub copia2()
Dim mycol()
Colonna = 11
A = ActiveCell.Address
Set rng = ActiveCell.Offset(-10, 1).Resize(6, 5)
ReDim mycol(rng.Cells.Count)
X = 1
For Each cl In rng
mycol(X) = cl.Value
X = X + 1
Next cl
For n = LBound(mycol) To UBound(mycol)
Sheets("Foglio2").Cells(46, Colonna).Value = mycol(n)
Colonna = Colonna + 1
Next n
Set rng = Nothing
With Sheets("foglio2")
Set area = Range(.Cells(46, 11), .Cells(46, 11).End(xlToRight))
area.Sort Key1:=.Cells(46, 11), Order1:=xlAscending, Orientation:=xlLeftToRight
End With
Set area = Nothing
End Sub

saluti
Giap




aetio
Inviato: Wednesday, October 27, 2010 6:17:43 AM

Rank: AiutAmico

Iscritto dal : 5/10/2010
Posts: 723
Ciao,
Grazie assai ! Le tue spiegazioni sono talmente chiare e bene esposte che la Materia sembra cosa facile...
Buona giornata,
eZio

Utenti presenti in questo topic
Guest


Salta al Forum
Aggiunta nuovi Topic disabilitata in questo forum.
Risposte disabilitate in questo forum.
Eliminazione tuoi Post disabilitata in questo forum.
Modifica dei tuoi post disabilitata in questo forum.
Creazione Sondaggi disabilitata in questo forum.
Voto ai sondaggi disabilitato in questo forum.

Main Forum RSS : RSS

Aiutamici Theme
Powered by Yet Another Forum.net versione 1.9.1.8 (NET v2.0) - 3/29/2008
Copyright © 2003-2008 Yet Another Forum.net. All rights reserved.