Страницы: 1
RSS
Доработка процедуры выделения дублей
 
Здравствуйте!

Попробовал переиначить найденную в интернете процедуру выделения дублей:
Код
Sub SelectDoubles(a As Range)
    Dim q, z As Long
    Dim c, r As Range
        For Each c In a
         If Len(c.Value) > 0 Then
          q = 0
          Set c = a.Find(c.Value, LookIn:=xlValues, LookAt:=xlWhole, MatchCase:=True)
                Do
                    If c.Row > q Then q = c.Row
                    Set c = a.FindNext(c)
                    z = c.Row
                    If z > q Then
                        Cells(c.Row, c.Column).Interior.Color = vbMagenta
                        Cells(z, c.Column).Interior.Color = vbMagenta
                    End If
                Loop While c.Row > q
          End If

        Next c
End Sub

Как заставить ее выделять и первое значение из дублирующихся? и ускорить, если возможно
Изменено: borro - 17.08.2018 11:09:56
желаю всем счастья
 
Можно так
Код
Sub test()
    Dim dic As Object, i&, txt$, ikey, arr, lkey
    
    Set dic = CreateObject("Scripting.Dictionary")
    i = 1
    Do Until Range("a" & i).Value = Empty
        txt = Range("a" & i).Value
        dic.Item(txt) = dic.Item(txt) & i & "|"
        i = i + 1
    Loop
    For Each ikey In dic.keys
        txt = CStr(Left(dic.Item(ikey), Len(dic.Item(ikey)) - 1))
        If InStr(1, txt, "|", vbTextCompare) <> 0 Then
            arr = Split(dic.Item(ikey), "|")
            For Each lkey In arr
                If lkey <> "" Then Range("a" & Val(lkey)).Interior.Color = vbRed
            Next lkey
        End If
    Next ikey
End Sub
Изменено: Nordheim - 17.08.2018 11:40:32
"Все гениальное просто, а все простое гениально!!!"
 
Спасибо. А как нацелить ее на подаваемый на вход диапазон ячеек?
желаю всем счастья
 
Все зависит от задачи и самого диапазона, если это один столбец то указав номер столбца либо заменив в коде ("a") на тот столбец который нужен,
если проверяемые данные находятся в нескольких столбцах , то тут другая логика и этот код не подойдет.
"Все гениальное просто, а все простое гениально!!!"
 
Цитата
Nordheim написал:
Все зависит от задачи и самого диапазона, если это один столбец то указав номер столбца либо заменив в коде ("a") на тот столбец который нужен,
Да, на вход будет подаваться диапазон, представляющий собой столбец с какой-то по какую-то строки подряд. Не могу понять, как переделать ваш пример. Подскажите, пожалуйста
желаю всем счастья
 
У меня показан цикл Do Until....Loop, попробуйте задать переменную с типом Range и пройдитесь по диапазону записывая номер строки, либо адрес ячейки, это как вам удобней. Либо два цикла по диапазону один с занесением данных о дублях в словарь, что то типа
Код
Dic.Item(cstr(cells(i,j))) = Dic.Item(cstr(cells(i,j))) +1
, а потом по тому же диапазону с проверкой
Код
Dic.Item(cstr(cells(i,j))) >1
.
Где i - номер строки, j - номер столбца. Но это зависит от того какой цикл будет применен, если For Each ....Next, то тут немного иная логика, но принцип один.
"Все гениальное просто, а все простое гениально!!!"
 
Опираясь на ваш совет, смог написать такое:
Код
Sub testdoubles(r As Range)
    Dim dic As Object, i&, txt$, ikey, arr, lkey
    Dim cell As Range
     
    Set dic = CreateObject("Scripting.Dictionary")
    i = 0
    For Each cell In r
        If cell.Text <> "" Then
            i = cell.Row
            txt = cell.Text
            dic.Item(txt) = dic.Item(txt) & i & "|"
        End If
        i = i + 1
    Next cell

    For Each ikey In dic.keys
        txt = CStr(Left(dic.Item(ikey), Len(dic.Item(ikey)) - 1))
        If InStr(1, txt, "|", vbTextCompare) <> 0 Then
            arr = Split(dic.Item(ikey), "|")
            For Each lkey In arr
                If lkey <> "" Then Range(r.Row, Val(lkey)).Interior.Color = vbRed
            Next lkey
        End If
    Next ikey
End Sub
При выполнении этой процедуры возникает ошибка с текстом Method 'Range' of object '_Global' failed , указывая на
Код
If lkey <> "" Then Range(r.Row, Val(lkey)).Interior.Color = vbRed
Как надо исправить код?
желаю всем счастья
 
Было на форуме, писал шуструю процедуру. Может пригодится.
«Бритва Оккама» или «Принцип Калашникова»?
 
Привет!
Цитата
borro написал:
на вход будет подаваться диапазон, представляющий собой столбец
Тогда попробуйте
Код
Range(r.Row, Val(lkey))
заменить на
Код
r.Range(r.Row, 1)
Изменено: Inexsu - 18.08.2018 11:29:40
Сравнение прайсов, таблиц - без настроек
 
Цитата
Inexsu написал:
заменить на Код ? 1r.Range(r.Row, 1)
Добрый день! Спасибо.
Так выдает на этой строке "Application defined or object defined error"
желаю всем счастья
 
borro, посмотрите мое решение, отрабатывает без ошибок.
«Бритва Оккама» или «Принцип Калашникова»?
 
УИгорь Вахненко уже с цветами  :D  
Сравнение прайсов, таблиц - без настроек
 
С разными цветами даже удобнее, имхо. Игорю +1 в карму. Если допилить возможность не фиксированного списка цветов, а автоматического (но не вырвиглазного) будет вообще здорово (в случаях большого количества разных дубликатов). Добавлю к себе в заметку, может добавлю в свою процедуру авто-цветовую градацию.
Изменено: bedvit - 18.08.2018 17:11:20
«Бритва Оккама» или «Принцип Калашникова»?
 
Цитата
bedvit написал:
borro , посмотрите мое решение, отрабатывает без ошибок.
спасибо. Вроде сработало!
желаю всем счастья
 
Добрый вечер!
bedvit, скажите, а как можно доработать вашу процедуру, чтобы она пустые ячейки не рассматривала в расчетах? А то у меня почему-то они помечаются как дубли
Изменено: borro - 20.08.2018 17:29:52
желаю всем счастья
 
borro, Сделайте УФ, пусть перекрашивает снова в исходный цвет.
По вопросам из тем форума, личку не читаю.
 
borro, приложите пример, у меня пустые ячейки - не красит.
«Бритва Оккама» или «Принцип Калашникова»?
 
Если вы говорите про ячейки помеченные апострофом = ' , или со строкой нулевой длинны ="", то в код можно внести минимальные корректировки.
Код немного актуализированный, по состоянию на сейчас.
Если не выделять диапазон, а выделить одну ячейку - ищет повторы и выделяет данные на всём листе.
Код
Option Explicit

Sub select_replica() 'рабочий
Dim arr, x, R As Range, A As Long, i As Long, j As Long, iEnd As Long, jEnd As Long, y As Long, ac, t
Dim dict: Set dict = CreateObject("Scripting.Dictionary")
If Selection.CountLarge = 1 Then Set R = ActiveSheet.UsedRange Else Set R = Intersect(ActiveSheet.UsedRange, Selection)
If R Is Nothing Then Exit Sub

With Application: .ScreenUpdating = 0: .DisplayAlerts = 0: .EnableEvents = 0: ac = .Calculation: .Calculation = -4135: .StatusBar = "BVV: обработка данных...": End With
R.Interior.Pattern = Empty
    
ReDim arr(1 To R.Areas.Count)
For A = 1 To R.Areas.Count
    arr(A) = R.Areas(A).Value
Next

For A = 1 To R.Areas.Count
    iEnd = R.Areas(A).Count / R.Areas(A).Columns.Count
    jEnd = R.Areas(A).Count / R.Areas(A).Rows.Count
    y = 0
    For i = 1 To iEnd
        For j = 1 To jEnd
        If iEnd + jEnd = 2 Then x = R.Areas(A).Item(1).Value Else x = arr(A)(i, j)
        y = y + 1
            If Not IsEmpty(x) And x <> "" Then If Not dict.Exists(x) Then dict.Add x, R.Areas(A).Item(y) Else Union(R.Areas(A).Item(y), dict.Item(x)).Interior.Color = 6740479
        Next
    Next
Next
With Application: .ScreenUpdating = 1: .DisplayAlerts = 1: .EnableEvents = 1: .Calculation = ac: .StatusBar = False: End With
End Sub
Изменено: bedvit - 20.08.2018 19:08:04
«Бритва Оккама» или «Принцип Калашникова»?
 
Цитата
bedvit написал:
Если вы говорите про ячейки помеченные апострофом = ' , или со строкой нулевой длинны ="", то в код можно внести минимальные корректировки.
Спасибо! Какие?
желаю всем счастья
 
borro, те, которые я внёс в сообщении 18. :)
«Бритва Оккама» или «Принцип Калашникова»?
Страницы: 1
Наверх