trovare doppione



  • trovare doppione
    di rocco (utente non iscritto) data: 27/12/2015 21:56:02

    salve a tutti, Signore e Signori
    e felice Natale
    ho un aiuto da chiedervi e Vi vado subito all'esempio:
    le prime 13 righe della colonna 3 hanno dei valori
    esempio 2
    12
    23
    16
    39
    44
    2
    20
    5
    99
    76
    83
    11
    io vorrei con una ricerda evvidenziare di rosso la cella se questa ha lo stesso valore anche su un altra
    nell'esempio dovrebbe evvidenziare la cella con il valore 2 perchè è l'unica che si ripete
    comunque a me interesserebbe che ne evvidenziasse solo una se si può fare

    ringrazio fin d'ora chi mi potrà aiutare



  • di Cucù data: 27/12/2015 22:29:06

    Ipotizzando la serie di numeri nella colonna A a partire da A1 in poi...
    Una prima ipotesi di lavoro se ho capito bene il tuo problema.
    Cucù
     
    Option Explicit
    Sub Trova_Doppione()
    Dim Ur As Long, doppione As Long, ir As Long, tot As Long
    Dim Rng As Range, cella As Range
    On Error Resume Next
    
    Ur = Range("A65000").End(xlUp).Row
    Range("A:A").Interior.ColorIndex = xlNone
    tot = 0
    For ir = 1 To Ur
        
        doppione = Cells(ir, 1).Value
        Set Rng = Range(Cells(ir + 1, 1), Cells(Ur, 1))
            Set cella = Rng.Find(doppione, LookIn:=xlValues, lookat:=xlWhole)
                If Not cella Is Nothing Then
                    cella.Interior.ColorIndex = 3
                    tot = tot + 1
                End If
    Next ir
    
    If tot = 0 Then
    MsgBox "Nessun doppione trovato!"
    Else
    MsgBox "Trovati " & tot & " doppioni"
    End If
    
    End Sub
    



  • di Textomb data: 27/12/2015 23:53:15

    ciao.
    Mi pare che quella routine non dia il risultato atteso.



  • di Textomb data: 28/12/2015 00:53:58

    Ho cercato un'alternativa che propongo di seguito. Dovrebbe funzionare.
    Nella routine postata viene evidenziata sempre l'ulitima cella del Range anche se questa non ha doppioni.
    Inoltre viene attivata la gestione degli errori senza motivo: On Error Resume Next.
     
    Option Explicit
    Sub Trova_Doppione()
    Dim Ur As Long
    Dim Cell As Range
    Dim i As Long
    Dim j As Long
    
    Ur = Range("A" & Rows.Count).End(xlUp).Row
    Range("A1:A" & Ur).Interior.ColorIndex = xlNone
    
        For i = 1 To Ur - 1
            Set Cell = Cells(i, 1)
            For j = i + 1 To Ur
                If Cell = Cells(j, 1) Then Cells(j, 1).Interior.ColorIndex = 3
            Next j
        Next i
    
    End Sub



  • di Cucù data: 28/12/2015 08:13:15

    modificato



  • di Cucù data: 28/12/2015 08:16:49

    modificato



  • di Cucù data: 28/12/2015 08:18:24

    Ciao textbomb

    cerco di risponderti...

    1. Nella routine postata viene evidenziata sempre l'ultima cella del Range anche se questa non ha doppioni.
    Risp : vero ho modificato il codice per questa evenienza
    2. Inoltre viene attivata la gestione degli errori senza motivo: On Error Resume Next
    Risp : vero, (serve a evitare errori in caso siano inserite stringhe di testo anzichè numeri nella colonna A) ma anche a questo si può porre facilmente rimedio dimensionando la variabile come variant anzichè long_

    Adesso chiedo a te...
    1. Non ti sembra eccessivo un doppio ciclo for??? Se invece di 13 righe fossero molte, ma molte di più???
    Sulle celle vuote ci avevi pensato?

    Cucù 
     
    Option Explicit
    
    Sub Trova_Doppione()
    Dim Ur As Long, doppione As Variant, ir As Long, tot As Long
    Dim Rng As Range, cella As Range
    
    Ur = Range("A65000").End(xlUp).Row
    Range("A:A").Interior.ColorIndex = xlNone
    tot = 0
    For ir = 1 To Ur
        If ir = Ur Then Exit For
        doppione = Cells(ir, 1).Value
        Set Rng = Range(Cells(ir + 1, 1), Cells(Ur, 1))
            Set cella = Rng.Find(doppione, LookIn:=xlValues, lookat:=xlWhole)
                If Not cella Is Nothing Then
                    cella.Interior.ColorIndex = 3
                    tot = tot + 1
                End If
    Next ir
    
    If tot = 0 Then
    MsgBox "Nessun doppione trovato!"
    Else
    MsgBox "Trovati " & tot & " doppioni"
    End If
    
    End Sub



  • di Textomb data: 28/12/2015 11:51:59

    ciao
    cit. Non ti sembra eccessivo un doppio ciclo for??? Se invece di 13 righe fossero molte, ma molte di più???
    Certo, se fossero migliaia di righe, il doppio ciclo For non sarebbe l'ideale e bisogna cambiare strategia. Ma non è stato detto su quante righe si deve effettuare la ricerca. Come non è stato detto che tipi di dati bisogna cercare. Se sono solo numeri o anche testi o date o altro... Per queste ragioni ho preferito evitare l'utilizzo del metodo Find. Quest'ultimo infatti è molto veloce ma allo stesso tempo molto delicato. Prova infatti su valori di questo tipo
    12
    15
    21
    12
    20/04/2015
    18 maggio 2015
    20/04/15
    37
    41
    20-apr-2015
    41
    78

    La data 20 aprile non la trovebbe come doppione perchè è formattata in modo diverso nelle varie celle...
    Potresti ulteriormente cambiare la sintassi e scrivere Lookin:= xlFormulas invece di xlValues ma non puoi sapere se quei valori sono delle costanti oppure il risultato di una formula. Insomma il metodo Find è molto veloce ma fino a quando si tratta di cercare su poche centinaia di righe con i ciclo For i tempi di attesa sono più o meno accettabili. (il mio codice gira in meno di mezzo secondo fino a 500 righe)

    cit: Sulle celle vuote ci avevi pensato?
    Sinceramente non mi sono posto il problema. Ma neanche tu.
    Cmq, non è un grosso problema. Basta poco per escluderle...



  • di Cucù data: 28/12/2015 12:23:44

    Quest'ultimo infatti è molto veloce ma allo stesso tempo molto delicato
    bhe non mi trovi tanto in accordo sul fatto che sia molto delicato per cui è meglio non usarlo a discapito della velocità di esecuzione...

    La data 20 aprile non la trovebbe come doppione
    bhe ovvio ma neanche il tuo codice tiene conto di tale evenienza, che per altro come dici giustamente tu qualora fosse una realtà potrebbe facilmente essere gestita qualora l'utente avesse fatto riferimento a questa possibilità nella lista dati.
    Cucù



  • di Cucù data: 28/12/2015 13:17:20

    Almeno evitiamo il secondo ciclo qualora non fosse necessario... ^_^
    Cucù
     
    Option Explicit
    Sub Trova_Doppione()
    Dim Ur As Long
    Dim Cell As Range
    Dim i As Long
    Dim j As Long
    Dim x As Integer
    
    Ur = Range("A" & Rows.Count).End(xlUp).Row
    Range("A1:A" & Ur).Interior.ColorIndex = xlNone
    
        For i = 1 To Ur - 1
            Set Cell = Cells(i, 1)
            x = Application.CountIf(Range("A1:A" & Ur), Cell)
            If x > 1 Then
            For j = i + 1 To Ur
                If Cell = Cells(j, 1) Then Cells(j, 1).Interior.ColorIndex = 3
            Next j
            End If
        Next i
    
    End Sub



  • di Textomb data: 28/12/2015 14:40:06

    cit. Almeno evitiamo il secondo ciclo qualora non fosse necessario...
    Mi sembra una buona idea.
    Rilancio proponendo di eliminarlo definitivamente!
     
    Sub Trova_Doppione()
    Dim Ur As Long
    Dim cell As Range
    Dim Rng As Range
    Dim i As Long
    Dim Er As Long
    
    Ur = Range("A" & Rows.Count).End(xlUp).Row
    Range("A1:A" & Ur).Interior.ColorIndex = xlNone
    
        For i = 1 To Ur - 1
            Set Rng = Range(Cells(i + 1, 1), Cells(Ur, 1))
            On Error Resume Next
                WorksheetFunction.Index(Rng, WorksheetFunction.Match(Cells(i, 1), Rng, 0)).Interior.ColorIndex = 3
                If Err.Number = 0 Then Er = Er + 1
            On Error GoTo 0
        Next i
    
    MsgBox "Sono stati trovati N. " & Er & " doppioni"
    End Sub



  • di Cucù data: 28/12/2015 14:56:58

    Apprezzo il tentativo Textomb ma...

     
    WorksheetFunction.Match
    'meglio il metodo find a questo punto...
    On Error Resume Next
    'me lo avevi contestato....
    'Ma soprattutto
     On Error GoTo 0
    'Non se pò vedè.... ^_^


  • un momento...
    di mikipaldj data: 28/12/2015 14:59:57

    Scusate se mi intrometto...
    Ciò che chiedi non si può fare tramite formattazione condizionale?
    Nella formatt. c'è una funzione che evidenzia i doppioni...



  • di Cucù data: 28/12/2015 15:06:59

    @mikipaldj
    provaci....



  • di mikipaldj data: 28/12/2015 15:13:47

    Era una domanda retorica...



  • di Marius44 data: 28/12/2015 19:07:24

    Ciao Miki
    approfitto per darti da provare una macro trovata su internet. E' una scheggia: mi ha controllato circa 15mila righe in poco più di un secondo. Eventualmente ti dà anche un messaggio per sapere quanto ha impiegato. Vedi se ti va bene.

    Un ciao particolare a Cucù e a Textomb

    Ciao,
    Mario 

    PS ovviamente i dati sono nella colonna A
     
    Sub colora_duplicate() 'trovata su internet
        Cells(4, 11) = Now
        Dim t As Single
        t = Timer
        Dim q&, x&, i&, a
        Dim ash As Worksheet
        Set ash = ActiveSheet
        q = Range("A" & Rows.Count).End(3).Row - 3
        a = Range("A2").Resize(q)
        Application.ScreenUpdating = False
        With Sheets.Add
            .Cells(1).Resize(q) = a
            .Cells(2) = 1: .Cells(2).Resize(q).DataSeries
            .Cells(1).Resize(q, 2).Sort .Cells(1), 1, Header:=xlNo
            a = .Cells(1).Resize(q + 1)
            For i = 1 To q
                If a(i, 1) <> a(i + 1, 1) Then
                    If i > x + 1 Then _
                        .Cells(x + 2, 1).Resize(i - x - 1).Font.ColorIndex = 3
                    x = i
                End If
            Next i
            .Cells(1).Resize(q, 2).Sort .Cells(2), 1, Header:=xlNo
            .Cells(1).Resize(q).Copy ash.Range("A2")
            Application.DisplayAlerts = False
            .Delete
            Application.DisplayAlerts = True
        End With
        Application.ScreenUpdating = True
        'MsgBox "controllato in " & Format(Timer - t, "0.00 secs"), 0, "Avviso"
        Cells(4, 12) = Now
    End Sub
    



  • di rocco (utente non iscritto) data: 28/12/2015 21:55:50

    ciao e grazie a tutti per le risposte
    ho visto che la mia richiesta di aiuto è stata accolta con interesse e confronti da vari esperti e mi ha fatto piacere
    ho ancora un problema però:
    io la ricerca la volevo fare sulla colonna B
    ho provato a cambiare il range da A a B ma mi colora sempre i doppioni sulla colonna A
    scusate la mia ignoranza ma non so proprio dove metterci le mani
    abbusando delle vostre conoscenze vorrei pure chiedervi come fare la ricerca standoci dati sia sulla colonna B che C
    e comunque i valori saranno sempre numerici (no date o percentuali o testo)
    e le righe saranno sempre 13

    grazie ancora



  • di rocco (utente non iscritto) data: 29/12/2015 07:27:45

    ok,allora....sono riuscito a capire come utilizzare la colonna B al posto della A proposta negli aiuti
    ora però non so come fare per fare la ricerca su 2 colonne, la B e la C
    entrambe hanno valori che vanno dalla riga 1 alla riga 13
    aspetto vostri consigli
    buona giornata!



  • di Cucù data: 29/12/2015 11:55:42

    @ Mairo
    Idea semplice ma funzionale.
    Cucù



  • di rocco (utente non iscritto) data: 29/12/2015 14:19:08

    scusami Cucù ma non ho capito la tua risposta



  • di Cucù data: 29/12/2015 14:40:13

    @Rocco
    Niente, era un commento a quanto postato da mario.



  • di rocco (utente non iscritto) data: 29/12/2015 21:48:16

    non c'è proprio nessuno che mi può dare una mano?
    io ho provato a variare il range ma non serve e ci capisco ancora poco per fare delle prove che alla fine finiscono sempre con errore della macro



  • di Cucù data: 30/12/2015 10:14:29

    CIT "ora però non so come fare per fare la ricerca su 2 colonne, la B e la C "

    Deve essere valutata colonna per colonna o entrambe???
    Mi spiego se ho il valore 13 nella colonna B e il valore 13 nella colonna C deve evidenziarmelo oppure no, essendo 2 colonne differenti?



  • di rocco (utente non iscritto) data: 30/12/2015 21:54:50

    si, devono essere valutate entrambre
    il 13, come dal tuo esempio, deve essere evidenziato