Попробовал переиначить найденную в интернете процедуру выделения дублей:
Код
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
Как заставить ее выделять и первое значение из дублирующихся? и ускорить, если возможно
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
Все зависит от задачи и самого диапазона, если это один столбец то указав номер столбца либо заменив в коде ("a") на тот столбец который нужен, если проверяемые данные находятся в нескольких столбцах , то тут другая логика и этот код не подойдет.
"Все гениальное просто, а все простое гениально!!!"
Nordheim написал: Все зависит от задачи и самого диапазона, если это один столбец то указав номер столбца либо заменив в коде ("a") на тот столбец который нужен,
Да, на вход будет подаваться диапазон, представляющий собой столбец с какой-то по какую-то строки подряд. Не могу понять, как переделать ваш пример. Подскажите, пожалуйста
У меня показан цикл Do Until....Loop, попробуйте задать переменную с типом Range и пройдитесь по диапазону записывая номер строки, либо адрес ячейки, это как вам удобней. Либо два цикла по диапазону один с занесением данных о дублях в словарь, что то типа
. Где 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
С разными цветами даже удобнее, имхо. Игорю +1 в карму. Если допилить возможность не фиксированного списка цветов, а автоматического (но не вырвиглазного) будет вообще здорово (в случаях большого количества разных дубликатов). Добавлю к себе в заметку, может добавлю в свою процедуру авто-цветовую градацию.
Добрый вечер! bedvit, скажите, а как можно доработать вашу процедуру, чтобы она пустые ячейки не рассматривала в расчетах? А то у меня почему-то они помечаются как дубли
Если вы говорите про ячейки помеченные апострофом = ' , или со строкой нулевой длинны ="", то в код можно внести минимальные корректировки. Код немного актуализированный, по состоянию на сейчас. Если не выделять диапазон, а выделить одну ячейку - ищет повторы и выделяет данные на всём листе.
Код
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 написал: Если вы говорите про ячейки помеченные апострофом = ' , или со строкой нулевой длинны ="", то в код можно внести минимальные корректировки.