Hugo, спасибо большое за code review, внес правки в свой код!
Михаил Л, добавил функцию бинарного поиска и массив для исключений (в коде добавил соответствующие строки и комментарии).
Предполагается, что значения в массиве исключений - exception_arr заносятся в алфавитном порядке, то есть, например:
Код |
---|
exception_arr = Array("абрикос","картошка","огурцы","помидоры")
|
код:
Скрытый текст |
---|
Код |
---|
Sub подсветить_дубликаты()
Dim dict As Object, arr As Variant, exception_arr As Variant
Dim i As Variant, data_range As Range
exception_arr = Array("картошка", "огурцы") ' в этот массив ИСКЛЮЧЕНИЙ заносим значения в алфавитном порядке, так как для поиску по нему используется БИНАРНЫЙ ПОИСК
With ActiveSheet
Set data_range = Application.InputBox("выберите диапазон для выделения дубликатов", , , , , , , 8) ' выбор диапазона (тип 8 == объекту диапазон)
arr = data_range ' загоняем выделенный диапазон в массив
Set dict = CreateObject("Scripting.Dictionary") ' создаем словарь
' ниже цикл для поиска дубликатов в выделенном дипазоне (уже помещенном в массив)
For i = LBound(arr, 1) To UBound(arr, 1)
If binary_search(exception_arr, arr(i, 1)) = -1 Then
If Not dict.exists(arr(i, 1)) Then ' если нет такого в словаре, то
dict.Add (arr(i, 1)), 1 ' ключ словаря == значение, значение словаря == 1 (т.е количество повторов)
Else ' иначе
dict(arr(i, 1)) = dict(arr(i, 1)) + 1 ' прибавляем 1 к значению словаря ( то есть этот участовк кода отрабатывает, когда найден первый и последующий дубликаты)
End If
End If
Next i
For i = LBound(arr, 1) To UBound(arr, 1) ' цикл по массиву
If dict(arr(i, 1)) > 1 Then data_range(i, 1).Interior.Color = RGB(255, 242, 204) ' если есть дубликаты, то красим
Next i
End With
End Sub
Sub очистка_формата()
' очистка форматов для выделенного участка листа
With Selection
.ClearFormats
End With
End Sub
Private Function binary_search(arr, what) As Long
'функция поиска значения what в одномерном массиве arr
Dim p, q, r
p = 0: r = UBound(arr)
While p <= r
q = Int((p + r) / 2)
If LCase(Trim(arr(q))) = LCase(Trim(what)) Then binary_search = q: Exit Function
If LCase(Trim(arr(q))) > LCase(Trim(what)) Then
r = q - 1
Else
p = q + 1
End If
Wend
binary_search = -1
End Function |
|