range celle variabile e delimitato
Hai un problema con Excel? 
range celle variabile e delimitato
di trasp (utente non iscritto) data: 27/09/2012 19:51:23
salve,
sto cercando una soluzione che mi permetta di trasporre del testo elencato in verticale.
Il range di celle non è costante ed è delimitato all'inizio e alla fine da un carattere (p.e. un punto).
Porto un esempio:
.
a
b
c
d
.
a
b
c
.
ecc.
ho trovato una soluzione parziale in vba che mi estrae i dati dalla colonna A1 ma la logica di estrazione prevede gruppi di tre celle per volta.
Ringrazio sin d'ora se qualcuno riesce a dirmi come modificare il codice, adattando la parte legata al range.
Premetto che smanetto un pò ma non conosco la sintassi vb, inoltre prima di chiedere ho girato molto e provato soluzioni altre senza grosse soddisfazioni.
Posto di seguito il codice.
Grazie ancora per l'eventuale aiuto.
un saluto
Sub Trasponi()
Dim D1, D2 As Date
Dim tempoimpiegato As String
D1 = Time
Application.ScreenUpdating = False
Set zona = Range(Range("A1"), Range("A1").End(xlDown))
cont = zona.Rows.Count
For N = 1 To cont Step 3
If Worksheets("Foglio1").Cells(N, 1) <> "" Then
Range(Cells(N, 1), Cells(N + 2, 1)).Select
Selection.Copy
Worksheets("Foglio2").Select
Dim iRow As Integer
iRow = 1
While Cells(iRow, 1).Value <> ""
iRow = iRow + 1
Wend
Cells(iRow, 1).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=True
End If
Worksheets("Foglio1").Select
Next
Application.CutCopyMode = False
D2 = Time
tempoimpiegato = Format(D2 - D1, "hh:mm:ss")
MsgBox "Tempo impiegato: " & tempoimpiegato
End Sub
|
di Vecchio Frac data: 27/09/2012 20:28:34
Non ho capito la domanda...
hai un range di celle in colonna A (tutto in verticale) e vuoi trasporre i dati in riga (quindi in orizzontale), ma a gruppi di celle delimitate dal punto?
Se sì: un'idea è buttare tutot in una variabile locale, splittarla al punto, e ogni pezzo trasporlo nel range orizzontale che ti interessa.
Se i bambini vanno a leto senza storie e la moglie non mi stressa, dopo provo a tradurre questo pensiero in VBA... altrimenti domattina :)
di trasp (utente non iscritto) data: 27/09/2012 20:54:18
si esatto! in effetti, quel codice sarebbe stato perfetto se non avesse avuto il range a step di tre (modificabile da codice ma sempre costante).
L'output che mi indichi è corretto, come risultato avrei i dati incolonnati parallelamente e trasposti a gruppi delimitati dalla costante "punto":
prima
.
a
b
c
d
.
a
b
c
.
dopo
abcd
abc
grazie per la tua disponibilità.
Mi sono un pò fusa la testa a cercare in questi giorni, alcune cose del codice sono comprensibili, altre un pò meno quando non si conosce la logica di un linguaggio.
ad ogni modo appena puoi
di HarryBosch data: 27/09/2012 20:55:47
Mi intrometto anch'io :)
L'idea di "splittare" la variabile che raccoglie l'intervallo fra i punti è molto bella (è una funzione che uso molto anch'io.. lo split, intendo).
Ma la lascio a Vecchio Frac che ha sicuramente già immaginato il "progetto"
Nel frattempo sono andato "sopra" al codice che hai postato, modificandolo allo scopo che hai chiesto.
Sub Trasponi()
Dim D1 As Date, D2 As Date
Dim tempoimpiegato As String
Dim cella As Range, zona As Range
Dim iRow As Integer, iCol As Integer
D1 = Time
Set zona = Range(Range("A1"), Range("A1").End(xlDown))
iCol = 1
iRow = 1
With Sheets("Foglio2")
For Each cella In zona
If cella <> "." Then
.Cells(iRow, iCol) = cella.Value
iCol = iCol + 1
ElseIf cella = "." Then
While .Cells(iRow, 1).Value <> ""
iRow = iRow + 1
Wend
iCol = 1
End If
Next cella
End With
Sheets("Foglio2").Activate
D2 = Time
tempoimpiegato = Format(D2 - D1, "hh:mm:ss")
MsgBox "Tempo impiegato: " & tempoimpiegato
End Sub
|
di trasp (utente non iscritto) data: 27/09/2012 21:24:48
che posso dire...grazie! è il risultato che mi aspettavo!
Questo sito me lo tengo tra i preferiti e lo consiglierò come punto di riferimento.
Grazie anche per la velocità della soluzione, è magnifico!
ciao e a presto
di Vecchio Frac data: 27/09/2012 21:52:44
Se consideri risolta la discussione bene, merito di Harry :)
Penso comunque che ci proverò lo stesso... ma domani, perchè preso dall'entusiasmo ho dimenticato di dirvi che qui a casa ho sostituito l'hard disk con un più ciccione (2TB) e ne ho approfittato per provare ad installare un Ubuntu nuovo di zecca. Risultato: tutto perfetto, a parte la novità un po' scioccante per un Windowsiano storico come me... il dramma è che non ho a disposizione nè Office nè Excel e quindi devo approntare una macchina virtuale per tornare operativo :)
di trasp (utente non iscritto) data: 27/09/2012 22:09:02
Caro Frac,
sarei curiosa di sperimentare la tua soluzione, qualora la volessi postare, in ogni caso sono davvero grata a te ed Harry per disponibilità e prontezza nell'aiuto.
Grazie e a presto
di HarryBosch data: 27/09/2012 22:28:58
@ trasp
Ma di niente, anzi, vieni a trovarci presto.. vedrai poi che la soluzione con lo split sarà sicuramente più elegante.
E se hai qualche dubbio sui passaggi del codice chiedi pure.
@ Vecchio Frac
wow, Bravo Vecchio Frac! anch'io ogni tanto giro su Ubuntu con la "solita" virtual machine, più che altro per smacchinare con il terminale ma come te, a Windows faccio fatica a rinunciare. Ho provato pure Windows 8 e sarà anche innovativo ma, tutte queste task mi rovinano il classico desktop con le mie "comode" cartelle. Hai provato i "cloni" gratuiti di Office? Ci sono anche portable
di Vecchio Frac data: 28/09/2012 08:36:50
[OT]
Io faccio una fatica doppia perchè in ufficio ho XP e a casa (avevo) Seven, due mondi diversi :)
Win8 volevo provarlo ma non sono riuscito a virtualizzarlo.
LibreOffice attualmente presente su Linux è nel complesso carino e pulito, molto simile a Office, ha un Basic suo abbastanza versatile ma non completamente compatibile. Mi piace molto che ci sia l'interprete Python integrato (sto studiando anche Python adesso ^_^).
Però preferisco Office, lo conosco mille volte meglio.
[/OT]
di Vecchio Frac data: 28/09/2012 09:52:04
Provate questo codice, ditemi cosa ne pensate.
Notate la tecnica molto carina per "appiattire" un range in un array.
Sembra contorto ma non lo è: dopo aver appiattito con Transpose il range (zona) e unificato con Join, l'ho risuddiviso in corrispondenza del carattere punto (con Split).
Quindi ho trasferito ogni elemento del vettore così ottenuto nel foglio2, utilizzando TextToColumns (separando ogni elemento del vettore in corrispondenza del carattere nullo).
Doveroso sottolineare che la routine suppone di trovare i dati in colonna A del foglio1, che non ci siano righe vuote prima dell'inizio del range e che il foglio2 sia liberamente disponibile ad accogliere il risultato dell'operazione.
Sub trasponi2()
Dim zona As Range, t1 As Single, compact_range As Variant, v As Variant, i As Integer
Application.ScreenUpdating = False
Application.DisplayAlerts = False
t1 = Timer
Sheets("Foglio1").Activate
Set zona = Range([A1], [A1].End(xlDown))
compact_range = Split(Join(WorksheetFunction.Transpose(zona)), ".")
For Each v In compact_range
With Sheets("Foglio2").[A1].Offset(i, 0)
.Value = v
.TextToColumns other:=True, otherchar:=vbNullChar
End With
i = i + 1
Next
Application.ScreenUpdating = True
Application.DisplayAlerts = True
MsgBox "Tempo impiegato: " & Format(Timer - t1, "0.00") & " secs."
End Sub |
di trasp (utente non iscritto) data: 30/09/2012 13:48:20
ciao Vecchio Frac,
solo oggi ho potuto fare una prova pratica del codice.
Tutto è disposto secondo quanto hai detto:
foglio1 con dati incolonnati in A,foglio2 pronto ad accogliere i dati estratti.
Quando lancio il codice si ferma ad un errore di debug in corrispondenza dell'istruzione ".TextToColumns other:=True, otherchar:=vbNullChar" e la finestra di dialogo dice che "non è stato selezionato alcun dato da analizzare".
Una precisazione, la colonna A del foglio1 inizia con un punto, se lo tolgo ottengo l'incolonnamento ma incontro un altro problema legato alla formattazione d'origine della data, che a sua volta è frutto di un'estrazione da codice, (es. dom30/09/20120.13.48,66)
Difatti, ho disposti verticalmente anche i numeri della data seguiti dal punto (13 e 48,66).
Un piccolo inciso, anche sulla data ho provato a fare un passaggio successivo per estrarre solo 30/09/2012 con stringa estrai ed è perfetto ma se poi desidero cambiare il formato in 30-set (il formato che mi serve), non lo prende, questa è comunque un'altra faccenda.
Altra cosa, il codice è velocissimo in esecuzione!
Sarei curiosa di capire come mai mi da quell'errore, è per via del punto iniziale immagino, ma non è una cella vuota..
Grazie per il tempo che hai dedicato.
A presto
di Vecchio Frac data: 01/10/2012 11:49:48
Ti chiederei, se possibile, il file con il codice che dà errore e con dati fittizi per fare delle prove sul campo.
di Vecchio Frac data: 01/10/2012 13:54:53
Dunque ho risolto il problema del punto iniziale: la stringa nulla derivante dà split mandava in confusione il successivo TextToColumns.
Allego quindi la versione del codice che tenga conto dell'eventualità e la corregga.
Quindi adesso funziona, punto iniziale o no :)
Sul problema della data, attendo, se ti interessa ancora, un piccolo file con dati di esempio su cui lavorare perchè sicuramente si può risolvere :)
Sub trasponi2()
Dim zona As Range, t1 As Single, compact_range As Variant, v As Variant, i As Integer
Application.ScreenUpdating = False
Application.DisplayAlerts = False
t1 = Timer
Sheets("Foglio1").Activate
Set zona = Range([A1], [A1].End(xlDown))
compact_range = Split(Join(WorksheetFunction.Transpose(zona)), ".")
For Each v In compact_range
If v <> vbNullString Then
With Sheets("Foglio2").[A1].Offset(i, 0)
.Value = v
.TextToColumns other:=True, otherchar:=vbNullChar
End With
i = i + 1
End If
Next
Application.ScreenUpdating = True
Application.DisplayAlerts = True
MsgBox "Tempo impiegato: " & Format(Timer - t1, "0.00") & " secs."
End Sub |
di trasp (utente non iscritto) data: 01/10/2012 16:07:45
ciao Vecchio Frac,
ho fatto le debite prove e stavolta non mi segnala nessun errore di debug ma il risultato dell'incolonnamento è lo stesso, nel senso che incolonna anche i numeri successivi alla data.
Ti allego due file, il primo è il file di testo dal quale pesco i dati (quello che ti allego è un campione rappresentativo), il secondo è un xls dove all'interno troverai tre fogli:
dati
foglio1
foglio2
nel foglio dati, vedrai un elenco con le voci che voglio estrapolare dal txt (anche qui, non ho capito perchè mi tronca le voci in elenco, inoltre ho scoperto che è case sensitive, cmq sempre altro discorso che, per estensione, investe anche la data)
il foglio1 ha successivi passaggi che sono pulisci e trasponi appunto (azioni avviate da pulsanti)
il foglio2 già sai.
ps a sto punto tolgo il flag a risolto vista la continuità della conversazione
ciao
di Vecchio Frac data: 02/10/2012 08:19:26
Scusa la domanda ingenua, ma nel tracciato del file txt allegato le diverse sezioni da importare sono delimitate da numerosi trattini consecutivi (cui segue un punto su riga nuova):
-------------------------
.
start process =
...
END PROCESS =
-------------------------
.
Allora mi (ti) chiedo: perchè non consideriamo come separatore la riga di trattini, evitando così i problemi legati al riconoscimento della data, che altrimenti verrebbe splittata in considerazione del punto? in mattinata posterò il codice modificato in questo senso.
di Vecchio Frac data: 02/10/2012 09:41:48
E il tuo obiettivo finale qual è?
Da quel che ho capito io è:
- nel "foglio2" voglio vedere, incolonnate per categoria, le voci che ho specificato in "dati", estratte dal file di log.
In pratica, un risultato simile a questo, per le prime due sezioni di dati separate dai trattini:
START PROCESS mer 12/09/2012 0.11.48,66 mer 12/09/2012 0.14.08,29 ecc.
LAVORAZIONE MOD6994 MOD6399
VOLUME 97419 (assente)
PAGINE IN DESTINAZIONE 73 (assente)
E' corretta la mia interpretazione?
di Vecchio Frac data: 02/10/2012 11:26:09
cit. " non ho capito perchè mi tronca le voci in elenco "
---> Bè sì, se leggi il codice è facile capirlo. Nella tua Sub originale "ImportaTxt" c'è una semplice istruzione:
Ftesto2 = Replace(Replace(Replace(Ftesto, " ", ""), "E", ""), "]", "")
che in pratica elimina spazi vuoti, lettere "E" e parentesi quadre "]" dove le trova e quindi il risultato che produce è, come dire, un po' monco :)
di trasp (utente non iscritto) data: 02/10/2012 14:57:41
ciao
grazie per le indicazioni.
La tua re-interpretazione è corretta, se esegui gli step come li ho impostati nel foglio di lavoro avrai che. dopo l'importazione, i dati verranno "ripuliti" da pulsante "pulisci" e trasposti dall'omonimo pulsante.
Dopo la pulizia, l'incolonnamento ha la serie di dati che ho filtrato dall'importazione, preceduta e seguita dal punto.
Lanciando il codice originale per trasporre, (quello modificato da Harry), ottengo il risultato nel foglio2 a prescindere dalla presenza dei punti nel formato data..c'è qualcosa in quel codice che considera solo i punti delimitanti il gruppo di dati ed è la giusta chiave di volta.
Che ne pensi?
A presto
di Vecchio Frac data: 02/10/2012 15:19:10
Allego il file da me elaborato.
Non so se presenta il risultato voluto, da quello che ho capito io sì, ma fammi sapere.
di trasp (utente non iscritto) data: 02/10/2012 23:50:11
ciao
complimenti, proprio un buon lavoro, ordinato e preciso! Addirittura la numerazione delle righe! Grazie per il tempo che hai dedicato.
Con il tempo vorrei dedicarmi a capire la struttura e la sintassi di questo linguaggio per ottenere autonomamente certi risultati.
In questo forum ho trovato un buon punto di riferimento.
A presto
di Vecchio Frac data: 03/10/2012 07:24:16
Grazie, presumo che il risultato sia soddisfacente ^_^
Allora se ritieni chiusa la discussione per cortesia spunta la casella "Spunta se risolta".
Ti aspettiamo ancora :)
di trasp (utente non iscritto) data: 04/10/2012 14:31:46
ciao
chiudo la discussione
Vuoi Approfondire?