Unificazione delle duplicazioni



  • Unificazione delle duplicazioni
    di far2012 (utente non iscritto) data: 10/11/2012 11:52:57


    Unificazione delle duplicazioni

    Messaggioda far2012 » 08/11/2012, 13:33
    Ciao tutti,

    io avrei bisogno di una formula o un Macro per unificare in un modo particolare delle celle che contengono le ripetizioni. Per spiegarmi meglio, questo funzionamento mi servirebbe per unificare una lista delle parole di un dizionario bilingue.

    La funzione che mi servirebbe è:
    ci sono due colonne. Nella colonna sinistra ci sono la lista delle parole che vengono ripetute nella divrse righe. Nella colonna a destra davanti alle parole della colonna sinistra ci sono le traduzioni che sono diverse una riga dell'altra o sono uguali.
    Vorrei che tramite la formula o la macro le parole ripetute alla colonna sinistra diventassero uniche e le parole che stanno sulle diverse rige davanti alle parole ripetute si unificassero davanti a unica voce, separati con la "puntovirgola".

    avevo un file di esempio in formato Excel ma visto che qua non c'è possibilita di allegare un file, invio come esempio qua sotto:

    Grazie millie
    far
     
    prima:
    aaa	abc, cou, zdf, suh
    aaa	cdu, icf, oid, ncu
    aaa	abc, cou, zdf, suh
    aaa	hbc, oid, zdf, iom, ngo, kodl
    bbb	xcf, iopm, poia, iund, zd
    bbb	hft, kjp, lop, mas, òdl
    bbb	poim, lop, mas, ild, zop
    bbb	ghdf, lop, poin, lku
    bbb	xcf, iopm, poia, iund, zd
    ccc	ocf, ccf, zcf
    ccc	ocf, ccf, zcf
    ccc	dcf, zcf, ncf
    
    e vorrei che diventasse dopo così:
    aaa	abc, cou, zdf, suh; cdu, icf, oid, ncu; hbc, oid, zdf, iom, ngo, kodl
    bbb	xcf, iopm, poia, iund, zd; hft, kjp, lop, mas, òdl; poim, lop, mas, ild, zop; ghdf, lop, poin, lku
    ccc	ocf, ccf, zcf; dcf, zcf, ncf
    



  • di Vecchio Frac data: 10/11/2012 12:14:48

    cit. " qua non c'è possibilita di allegare un file "
    ---> Certo che c'è questa possibilità. Clicca su "nuova risposta" e troverai un pulsante, "Allega un file". Si accettano preferibilmente file in formato compresso zip o rar.

    Nel merito, hai qualche infarinatura di VBA?
    Con formule la vedo ardua.
    In pratica devi scorrere il range che contiene i dati, esaminare la prima colonna e di esso la prima cella, memorizzarne i valori concatenandoli col separatore preferito, aggiungere il risultato a una Collection (oppure a scelta riportando i valori unificati in altra zona).
    In alternativa puoi considerare l'uso di un filtro automatico sulla prima colonna scorrendo poi il range visibile e concatenando i valori per ogni riga estratta.
    Potresti per esercizio implementare entrambe le soluzioni e poi scegliere quella che ti piace di più o che funziona meglio ^_^
    Tradotto in altre parole: ti ho fornito l'algoritmo. Adesso prova a buttare giù un pezzo di codice e poi lo sistemiamo insieme. Sempre che in altri forum tu non abbia già ricevuto il codice pronto, nel qual caso (e solo in questo caso) ti invito a chiudere marcandola "risolta" questa discussione, postando la soluzione a beneficio di altri.




  • Unificazione delle duplicazioni
    di far2012 (utente non iscritto) data: 10/11/2012 13:16:21

    Ciao,
    Intanto molte grazie della risposta.
    Infatti mi sorgeva dubbio che un forum così ricco e attivao non abbia la possibilità di allegare un file. Comunque, ho allegato il file che avevo preparato.

    Ho provato diversi programmi/Macro che facevano "Merge" di diversi tipi ma purtroppo ognuno faceva in un modo diverso e non potevano rispondere alla mia esigenza. Ho diversi file grandi che vorrei unificare in questo modo.

    Per quanto riguarda di prepare dei codici, purtroppo non essendo uno esperto in materia di Excel non so come procedere.

    Ti ringrazio in anticipo del tuo aiuto



  • di Vecchio Frac data: 10/11/2012 14:46:18

    Una cosa che ho capito solo dopo aver riletto bene il tuo esempio è che non solo vuoi raggruppare i risultati ma vuoi anche evitare i duplicati (e lo hai anche scritto nel titolo LOL). Avevo già abbozzato un codicino ma lo voglio rivedere... e siccome adesso sto per uscire, devo rinviare :)
    Comunque il problema non è banale e lo trovo anzi di un certo interesse (anche se io avrei impostato un header nella tabella... questo semplificherà l'utilizzo del filtro automatico).





  • di Far2012 (utente non iscritto) data: 10/11/2012 15:45:36

    Ciao Frac,
    grazie, rimango in attesa delle tue notizie. Comunque per me va benissimo impostare dei header, sono due colonne spesso e si potrebbe impostare per esempio per la prima colonna "lingua1" e per la seconda colonna "lingua2".

    Grazie ancora e a dopo
    Far



  • di Vecchio Frac data: 10/11/2012 19:20:18

    Il codice che segue fa quello che chiedi.
    Sarebbe da rivedere e ottimizzare :)
    Per chiarezza allego il file; ho inserito un'intestazione alla tabella per via del filtro avanzato.
    Sto già vedendo come aggiustare meglio il codice, così com'è non è per niente efficiente, anche se funziona.
     
    Option Explicit
    
    Sub estrapola()
    Dim table As Range, ac As Range, ac2 As Range, coll As Collection, s As String, v As Variant, i As Integer
       
        [A1].CurrentRegion.Resize([A1].CurrentRegion.Rows.Count - 1, 1).AdvancedFilter Action:=xlFilterCopy, CopyToRange:=[D1], Unique:=True
        
        On Error Resume Next
        
        Set table = [D1].CurrentRegion.Resize([D1].CurrentRegion.Rows.Count - 1, 1).Offset(1)
        For Each ac In table
            Set coll = New Collection
            s = ""
            For Each ac2 In [A1].CurrentRegion.Rows
                If ac = ac2.Cells(1) Then coll.Add ac2.Cells(2), ac2.Cells(2)
            Next
            For Each v In coll
                s = s & v & ";"
            Next
            i = i + 1
            [A23].Offset(i) = ac
            [B23].Offset(i) = Replace(s & "@", ";@", "")
        Next
        
        On Error GoTo 0
        
        [D1].CurrentRegion.Delete
        
    End Sub






  • di Vecchio Frac data: 10/11/2012 19:47:33

    Ecco qui un codice concettualmente migliore.
    Posto il codice e allego anche il solito file di esempio.
    Notare che in questa seconda versione non ci sono le intestazioni di tabella, come anche previsto dal file originale.
     
    Option Explicit
    
    Sub estrapola()
    Dim ac As Range, coll As Collection, s As String, v As Variant, i As Integer
    Dim unique_values As Collection, vv As Variant
       
        On Error Resume Next
        
        Set unique_values = New Collection
        Set unique_values = collection_of_duplicates([A1].CurrentRegion.Resize([A1].CurrentRegion.Rows.Count - 1, 1))
        
        For Each v In unique_values
            Set coll = New Collection
            s = ""
            [A1].AutoFilter field:=1, Criteria1:=v
     
            For Each ac In [A1].CurrentRegion.SpecialCells(xlCellTypeVisible).Rows
                coll.Add ac.Cells(2), ac.Cells(2)
            Next
            For Each vv In coll
                s = s & vv & ";"
            Next
            i = i + 1
            [A23].Offset(i) = v
            [B23].Offset(i) = Replace(s & "@", ";@", "")
        Next
        
        [A1].AutoFilter
        On Error GoTo 0
    
    End Sub
    
    
    Function collection_of_duplicates(vettore As Variant) As Collection
    Dim v As Variant, dups As Collection
        
        Set dups = New Collection
        On Error Resume Next
        For Each v In vettore
            dups.Add CStr(v), v
        Next
        On Error GoTo 0
        Set collection_of_duplicates = dups
    End Function






  • di Far2012 (utente non iscritto) data: 10/11/2012 20:17:33

    Grazie mille Farc. Sei stato molto preciso ed efficiente. Funziona bene e comunque rimango in attesa di eventuali miglioramenti.
    Sarebbe anche possibile che nella colonna a destra il font delle scritte delle voci delle diverse celle che vengono unificati, prendessero un colore diverso uno dell'altro?
    Saluti
    Far



  • di Far2012 (utente non iscritto) data: 10/11/2012 20:27:26

    Vedo che sei stato molto più veloce di me a rispondere.
    Grazie ancora. Come posso fare che i dati vengono copiati nelle colonne D ed E invece che sotto?

    Saltui



  • di Vecchio Frac data: 10/11/2012 20:37:48

    La ricopiatura dei dati filtrati e unificati avviene in questo punto:
    [A23].Offset(i) = v
    [B23].Offset(i) = Replace(s & "@", ";@", "")

    Da A23 in giù la prima cella filtrata ("Lingua1"), da B23 in giù il valore della cella a fianco senza duplicati ("Lingua2").
    Quindi invece che A23 e B23 basta che metti D1 e E1 e sei a posto.
    Sul colore del font puoi agire nello stesso modo:
    [D1].Offset(i).Font.Color = vbRed imposta il colore di font della prima cella ("Lingua1") sul rosso.





  • di Far2012 (utente non iscritto) data: 10/11/2012 21:01:01

    Perfetto, ho modificato il codice e adesso i dati vengono copiati nelle colonne a destra.
    Per quanto riguarda il colore, il colore delle colonna a sinistra ovvero lingua1 non è importante. quello che è importante è la colonna di destra ovvero lingua2 che vorrei vedere per esempio, i dati della prima riga rimane nero invece i dati che vengono copiate da altre righe prendono un altro colore, in questo modo posso sapere che cosa è stata copiata e distinguere i dati.
    Grazie ancora
    Far



  • di Vecchio Frac data: 10/11/2012 21:23:10

    Attualmente succede questo:
    aaa - abc, def, ghi
    aaa - jkl, mno, pqr
    aaa - abc, def, ghi

    risultato:
    aaa - abc, def, ghi;jkl, mno, pqr

    Tu vorresti separare con colori diversi della stringa in "risultato" la parte tra un punto e virgola e l'altro.
    Devi allora definire una tavola dei colori abbastanza ampia, splittare la stringa in corrispondenza del punto e virgola, e ricomporla nella cella badando a variare colore ad ogni pezzo di stringa nuova. Non è proprio una cosa semplicissima. Mi sai dire quanti spezzoni separati da punto e virgola potrebbero esserci? Il numero di colori disponibili non è infinito e i colori di base sono poco meno di una quindicina, che poi a volerli usare tutti, alcuni sono anche illeggibili in una cella.
    Ti chiedo perciò se è necessaria questa distinzione visiva prima di cominciare a pensare ad una soluzione che già vedo piuttosto complicata.





  • di Far2012 (utente non iscritto) data: 10/11/2012 21:37:16

    Grazie ancora della risposta molto esauriente.
    Mi hai convinto che la mia idea non era del tutto funzionante. Allora ho pensato se al posto dei colori, si potrebbe fare in modo che i dati della colonna lingua2 vengono copiati in celle diverse sulla stessa riga invece di separargli con punto e virgola? Allo stesso momento io metto colore di sfondo per ogni lista e nel momento che vengono copiati in diverse celle possano avere la possibilità di mantenere il colore di sfondo della cella.
    per esempio se ho tre liste che devo unificare, a uno do colore di sfondo giallo, all'altro verde e al terzo rosso poi li metto insieme e faccio partire il codice...
    Questo sarebbe possibile?

    saluti
    Far



  • di Vecchio Frac data: 10/11/2012 22:52:12

    Concettualmente il problema non cambia. Solo si sposta :)
    Ripeto, non è impossibile nemmeno separare cromaticamente i valori in una stessa cella.
    Quindi (forse con meno codice e quindi più rapidamente implementabile) l'idea di scrivere i diversi valori in celle contigue, ognuna col suo bel colore di sfondo, è fattibile nello stesso modo.
    Per ora chiudo, ma domani riprendo in mano il file :)





  • di Far2012 (utente non iscritto) data: 11/11/2012 11:18:46

    Sì, hai ragione. Solo che in questo modo si può sapere l'origine di una parola. Per esempio una parola può avere diversi significati in diverse materie e quindi avendo le parole in colori diversi si può sapere ogni colore a quale materia appartiene.
    Grazie ancora della tua gentilezza e disponibilità.
    Far



  • di Vecchio Frac data: 11/11/2012 13:15:19

    Alla fine sono riuscito a rispettare le tue condizioni :)
    Adesso in colonna D hai le parole di "Lingua1" e in colonna E, separate da punto e virgola e con un colore diverso le diverse voci senza duplicati di cui alla colonna "Lingua2" (sono supportati 21 colori diversi, escluso il bianco e certi gialli illeggibili).
    Ho preferito fare così piuttosto che colorare le celle, perchè più aderente alla richiesta originale.
    Alla fine il codice risulta perfino abbastanza semplice, anche se complesso.
    Posto il codice, e anche il file di esempio (per far - 3.zip).

     
    Option Explicit
    
    Sub estrapola()
    Dim table As Range, ac As Range, coll As Collection, v As Variant, i As Integer
    Dim unique_values As Collection, vv As Variant, destination As Range, z As Range
    Dim iCharFrom As Integer, iCharLength As Integer, j As Integer, s As String
       
    Dim color_table() As Variant
        
        color_table = Array(3, 4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 21, 22, 23, 24, 25)   '21 colori diversi
        
        Set table = [A1].CurrentRegion.Resize([A1].CurrentRegion.Rows.Count - 1, 1).Offset(1)
        Set unique_values = New Collection
        Set unique_values = collection_of_duplicates(table)
        
        [D:E].Font.ColorIndex = xlAutomatic
        [D:E].ClearContents
        
        On Error Resume Next
        i = 0
        
        For Each v In unique_values
            Set coll = New Collection
            For Each z In table.Resize(, 1)
                If v = z Then coll.Add z.Offset(, 1), z.Offset(, 1)
            Next
            
            [D1].Offset(i) = v
            Set destination = [e1].Offset(i)
            
            For Each vv In coll
                destination = destination & vv & ";"
            Next
            destination = Left(destination, Len(destination) - 1)
            
            j = 0
            For Each vv In coll
                iCharFrom = InStr(destination, vv)
                iCharLength = iCharFrom + Len(vv)
                [e1].Offset(i).Characters(Start:=iCharFrom, Length:=iCharLength).Font.ColorIndex = color_table(j)
                j = j + 1
            Next
            
            i = i + 1
        Next
        
        On Error GoTo 0
    
    End Sub
    
    
    Function collection_of_duplicates(vettore As Variant) As Collection
    Dim v As Variant, dups As Collection
        
        Set dups = New Collection
        On Error Resume Next
        For Each v In vettore
            dups.Add CStr(v), v
        Next
        On Error GoTo 0
        Set collection_of_duplicates = dups
    End Function
    
    
    






  • di Far2012 (utente non iscritto) data: 11/11/2012 13:43:40

    Grazie mille. Funziona molto bene. Adesso ho un altro problema. Il file .xls contiene meno righe (circa 65mila) rispetto a .xlxs allora sto cercando di creare il codice che hai scritto dentro un file .xlsm che abilita anche macro ma non riesco a salvarlo. Ricevo errore che mi dice "Privasy warning: This document contains macros, ActiveX control, XML ..." e quindi non riesco a salvarlo in formato Excel 2010 versione inglese (ho cambiato Foglio1 a Sheet1 ma non ha funzionato).
    Grazie ancora in anticipo di una tua risposta.
    Far



  • di Vecchio Frac data: 11/11/2012 15:00:34

    Io uso abitualmente Excel 2003 in italiano, ma il codice prodotto è indipendente dalla versione e dal linguaggio.
    Devono esserci impostazioni particolari sull'abilitazione delle macro e nel salvataggio dei file con macro, ma io non posso aiutarti su questo punto.
    Non è che devi fargli considerare "attendibili" le macro prima di salvare?





  • di Far2012 (utente non iscritto) data: 11/11/2012 15:07:49

    come posso fargli considerare "attendibili"?
    In ogni modo, sono riuscito a salvare il file ma ogni volta che voglio salvare mi fa vedere questo messaggio di avvertenza. Ho abilitato anche la macro ma non è cambiato niente.

    Grazie ancora
    Far



  • di Vecchio Frac data: 11/11/2012 15:27:03

    Ho trovato questa soluzione, dimmi se può essere applicata.

    Fare clic sul pulsante di Office Excel
    Fare clic sul pulsante Opzioni di Excel
    Selezionare la scheda Centro protezione
    Clicca sul pulsante "Impostazioni Centro protezione ..."
    Selezionare la scheda "Opzioni Privacy"
    Deselezionare la checkbox "Rimuovi le informazioni personali dalle proprietà del file al momento del salvataggio"
    Confermare





  • di Far2012 (utente non iscritto) data: 11/11/2012 16:23:27

    Grazie ancora. Ho provato e ha funzionato. Sono molto soddisfatto di questo forum e sicuramento presto ritornerò a trovarvi con un altro quesito.
    Un ringraziamento speciale a Frac e a presto.

    complimenti anche per il sito perché l'apertura delle pagine è superveloce.
    Far



  • di Vecchio Frac data: 11/11/2012 19:33:08

    Grazie a te per il feedback.
    Se la discussione è conclusa, ti chiedo di spuntare la casella "Spunta se risolta" in una nuova risposta a questo thread.





  • di Far2012 (utente non iscritto) data: 18/11/2012 14:43:55

    grazie a te ancora.
    Far